oceanbase

Форк
0
/
ob_ddl_operator.cpp 
11627 строк · 531.7 Кб
1
/**
2
 * Copyright (c) 2021 OceanBase
3
 * OceanBase CE is licensed under Mulan PubL v2.
4
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
5
 * You may obtain a copy of Mulan PubL v2 at:
6
 *          http://license.coscl.org.cn/MulanPubL-2.0
7
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
 * See the Mulan PubL v2 for more details.
11
 */
12

13
#define USING_LOG_PREFIX RS
14
#include "rootserver/ob_ddl_operator.h"
15

16
#include "lib/time/ob_time_utility.h"
17
#include "lib/string/ob_sql_string.h"
18
#include "lib/mysqlclient/ob_mysql_transaction.h"
19
#include "lib/encrypt/ob_encrypted_helper.h"
20
#include "common/sql_mode/ob_sql_mode.h"
21
#include "share/ob_version.h"
22
#include "share/ob_autoincrement_service.h"
23
#include "share/ob_cluster_version.h"
24
#include "share/resource_manager/ob_resource_manager_proxy.h"
25
#include "share/schema/ob_schema_service.h"
26
#include "share/schema/ob_schema_getter_guard.h"
27
#include "share/schema/ob_multi_version_schema_service.h"
28
#include "share/schema/ob_tenant_sql_service.h"
29
#include "share/schema/ob_database_sql_service.h"
30
#include "share/schema/ob_table_sql_service.h"
31
#include "share/schema/ob_tablegroup_sql_service.h"
32
#include "share/schema/ob_user_sql_service.h"
33
#include "share/schema/ob_priv_sql_service.h"
34
#include "share/schema/ob_outline_sql_service.h"
35
#include "share/schema/ob_label_se_policy_sql_service.h"
36
#include "share/schema/ob_profile_sql_service.h"
37
#include "share/schema/ob_routine_info.h"
38
#include "share/schema/ob_routine_sql_service.h"
39
#include "share/schema/ob_udt_info.h"
40
#include "share/schema/ob_udt_sql_service.h"
41
#include "share/schema/ob_directory_sql_service.h"
42
#include "share/schema/ob_package_info.h"
43
#include "share/schema/ob_schema_service_sql_impl.h"
44
#include "share/schema/ob_security_audit_sql_service.h"
45
#include "share/sequence/ob_sequence_ddl_proxy.h"
46
#include "share/inner_table/ob_inner_table_schema.h"
47
#include "share/config/ob_server_config.h"
48
#include "share/inner_table/ob_inner_table_schema.h"
49
#include "share/ob_rpc_struct.h"
50
#include "share/ob_label_security.h"
51
#include "sql/resolver/ddl/ob_ddl_resolver.h"
52
#include "sql/resolver/ob_resolver_define.h"
53
#include "sql/resolver/ob_resolver_utils.h"
54
#include "sql/resolver/expr/ob_raw_expr_modify_column_name.h"
55
#include "sql/resolver/expr/ob_raw_expr_util.h"
56
#include "sql/printer/ob_raw_expr_printer.h"
57
#include "share/system_variable/ob_system_variable.h"
58
#include "share/system_variable/ob_system_variable_factory.h"
59
#include "share/resource_manager/ob_resource_plan_info.h"
60
#include "rootserver/ob_ddl_sql_generator.h"
61
#include "rootserver/ob_root_service.h"
62
#include "share/schema/ob_part_mgr_util.h"
63
#include "observer/ob_server_struct.h"
64
#include "observer/ob_sql_client_decorator.h"
65
#include "observer/omt/ob_tenant_config_mgr.h"
66
#include "share/schema/ob_error_info.h"
67
#include "rootserver/ob_root_service.h"
68
#include "share/stat/ob_dbms_stats_preferences.h"
69
#include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo
70
#include "rootserver/ob_tablet_drop.h"
71
#include "share/ob_freeze_info_proxy.h"
72
#include "share/ob_global_merge_table_operator.h"
73
#include "share/ob_zone_merge_table_operator.h"
74
#include "share/ob_zone_merge_info.h"
75
#include "storage/tx/ob_i_ts_source.h"
76
#include "share/stat/ob_dbms_stats_maintenance_window.h"
77
#include "share/scn.h"
78
#include "share/external_table/ob_external_table_file_mgr.h"
79
#include "share/schema/ob_mview_info.h"
80
#include "share/schema/ob_mview_refresh_stats_params.h"
81
#include "storage/mview/ob_mview_sched_job_utils.h"
82

83
namespace oceanbase
84
{
85

86
using namespace common;
87
using namespace share;
88
using namespace share::schema;
89
using namespace obrpc;
90
using namespace sql;
91
using namespace storage;
92

93
namespace rootserver
94
{
95

96
ObSysStat::Item::Item(ObSysStat::ItemList &list, const char *name, const char *info)
97
  : name_(name), info_(info)
98
{
99
  value_.set_int(0);
100
  const bool add_success = list.add_last(this);
101
  if (!add_success) {
102
    LOG_WARN_RET(OB_ERR_UNEXPECTED, "add last failed");
103
  }
104
}
105

106
#define MAX_ID_NAME_INFO(id) ObMaxIdFetcher::get_max_id_name(id), ObMaxIdFetcher::get_max_id_info(id)
107
ObSysStat::ObSysStat()
108
  : ob_max_used_tenant_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_TENANT_ID_TYPE)),
109
    ob_max_used_unit_config_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_UNIT_CONFIG_ID_TYPE)),
110
    ob_max_used_resource_pool_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_RESOURCE_POOL_ID_TYPE)),
111
    ob_max_used_unit_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_UNIT_ID_TYPE)),
112
    ob_max_used_server_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_SERVER_ID_TYPE)),
113
    ob_max_used_ddl_task_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_DDL_TASK_ID_TYPE)),
114
    ob_max_used_unit_group_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_UNIT_GROUP_ID_TYPE)),
115
    ob_max_used_normal_rowid_table_tablet_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_NORMAL_ROWID_TABLE_TABLET_ID_TYPE)),
116
    ob_max_used_extended_rowid_table_tablet_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_EXTENDED_ROWID_TABLE_TABLET_ID_TYPE)),
117
    ob_max_used_ls_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_LS_ID_TYPE)),
118
    ob_max_used_ls_group_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_LS_GROUP_ID_TYPE)),
119
    ob_max_used_sys_pl_object_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_SYS_PL_OBJECT_ID_TYPE)),
120
    ob_max_used_object_id_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_OBJECT_ID_TYPE)),
121
    ob_max_used_rewrite_rule_version_(item_list_, MAX_ID_NAME_INFO(OB_MAX_USED_REWRITE_RULE_VERSION_TYPE))
122
{
123
}
124

125
// set values after bootstrap
126
int ObSysStat::set_initial_values(const uint64_t tenant_id)
127
{
128
  int ret = OB_SUCCESS;
129
  if (is_sys_tenant(tenant_id)) {
130
    ob_max_used_tenant_id_.value_.set_int(OB_USER_TENANT_ID);
131
    ob_max_used_unit_config_id_.value_.set_int(OB_USER_UNIT_CONFIG_ID);
132
    ob_max_used_resource_pool_id_.value_.set_int(OB_USER_RESOURCE_POOL_ID);
133
    ob_max_used_unit_id_.value_.set_int(OB_USER_UNIT_ID);
134
    ob_max_used_server_id_.value_.set_int(OB_INIT_SERVER_ID - 1);
135
    ob_max_used_ddl_task_id_.value_.set_int(OB_INIT_DDL_TASK_ID);
136
    ob_max_used_unit_group_id_.value_.set_int(OB_USER_UNIT_GROUP_ID);
137
  } else {
138
    const int64_t root_own_count = 6;
139
    for (int64_t i = 0; i < root_own_count && OB_SUCC(ret); ++i) {
140
      const bool remove_succeed = item_list_.remove_first();
141
      if (!remove_succeed) {
142
        ret = OB_ERR_UNEXPECTED;
143
        LOG_WARN("remove_succeed should be true", K(ret));
144
      }
145
    }
146
  }
147
  if (OB_SUCC(ret)) {
148
    ob_max_used_normal_rowid_table_tablet_id_.value_.set_int(ObTabletID::MIN_USER_NORMAL_ROWID_TABLE_TABLET_ID);
149
    ob_max_used_extended_rowid_table_tablet_id_.value_.set_int(ObTabletID::MIN_USER_EXTENDED_ROWID_TABLE_TABLET_ID);
150
    ob_max_used_ls_id_.value_.set_int(ObLSID::MIN_USER_LS_ID);
151
    ob_max_used_ls_group_id_.value_.set_int(ObLSID::MIN_USER_LS_GROUP_ID);
152
    ob_max_used_sys_pl_object_id_.value_.set_int(OB_MIN_SYS_PL_OBJECT_ID);
153
    // Use OB_INITIAL_TEST_DATABASE_ID to avoid confict when create tenant with initial user schema objects.
154
    ob_max_used_object_id_.value_.set_int(OB_INITIAL_TEST_DATABASE_ID);
155
    ob_max_used_rewrite_rule_version_.value_.set_int(OB_INIT_REWRITE_RULE_VERSION);
156
  }
157
  return ret;
158
}
159

160
ObDDLOperator::ObDDLOperator(
161
    ObMultiVersionSchemaService &schema_service,
162
    common::ObMySQLProxy &sql_proxy)
163
    : schema_service_(schema_service),
164
      sql_proxy_(sql_proxy)
165
{
166
}
167

168
ObDDLOperator::~ObDDLOperator()
169
{
170
}
171

172
int ObDDLOperator::create_tenant(ObTenantSchema &tenant_schema,
173
                                 const ObSchemaOperationType op,
174
                                 ObMySQLTransaction &trans,
175
                                 const ObString *ddl_stmt_str/*=NULL*/)
176
{
177
  int ret = OB_SUCCESS;
178
  int64_t start = ObTimeUtility::current_time();
179
  int64_t new_schema_version = OB_INVALID_VERSION;
180
  ObSchemaService *schema_service = schema_service_.get_schema_service();
181
  if (OB_DDL_ADD_TENANT != op
182
      && OB_DDL_ADD_TENANT_START != op
183
      && OB_DDL_ADD_TENANT_END != op) {
184
    ret = OB_INVALID_ARGUMENT;
185
    LOG_WARN("invalid operation type", K(ret), K(op));
186
  } else if (OB_ISNULL(schema_service)) {
187
    ret = OB_ERR_SYS;
188
    LOG_ERROR("schema_service must not null");
189
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(OB_SYS_TENANT_ID, new_schema_version))) {
190
    LOG_WARN("fail to gen new schema_version", K(ret));
191
  } else {
192
    ObTenantStatus tenant_status = TENANT_STATUS_NORMAL;
193
    if (0 < tenant_schema.get_drop_tenant_time()) {
194
      // A dropping status tenant is created when standby cluster load snapshot.
195
      tenant_status = TENANT_STATUS_DROPPING;
196
    } else if (OB_DDL_ADD_TENANT_START == op) {
197
      if (tenant_schema.is_restore_tenant_status()) {
198
        tenant_status = TENANT_STATUS_RESTORE;
199
      } else if (tenant_schema.is_creating_standby_tenant_status()) {
200
        tenant_status = TENANT_STATUS_CREATING_STANDBY;
201
      } else {
202
        tenant_status = TENANT_STATUS_CREATING;
203
      }
204
    }
205
    tenant_schema.set_schema_version(new_schema_version);
206
    tenant_schema.set_status(tenant_status);
207
    if (OB_FAIL(schema_service->get_tenant_sql_service().insert_tenant(
208
        tenant_schema, op, trans, ddl_stmt_str))) {
209
      LOG_WARN("insert tenant failed", K(tenant_schema), K(ret));
210
    }
211
  }
212
  LOG_INFO("create tenant", K(ret), "tenant_id", tenant_schema.get_tenant_id(),
213
           "cost", ObTimeUtility::current_time() - start);
214
  return ret;
215
}
216

217
int ObDDLOperator::insert_tenant_merge_info(
218
    const ObSchemaOperationType op,
219
    const ObTenantSchema &tenant_schema,
220
    ObMySQLTransaction &trans)
221
{
222
  int ret = OB_SUCCESS;
223
  const uint64_t tenant_id = tenant_schema.get_tenant_id();
224
  if (is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) {
225
    // add zone merge info
226
    if ((OB_DDL_ADD_TENANT_START == op) || (OB_DDL_ADD_TENANT == op)) {
227
      HEAP_VARS_4((ObGlobalMergeInfo, global_info),
228
                  (ObZoneMergeInfoArray, merge_info_array),
229
                  (ObZoneArray, zone_list),
230
                  (ObZoneMergeInfo, tmp_merge_info)) {
231

232
        global_info.tenant_id_ = tenant_id;
233
        tmp_merge_info.tenant_id_ = tenant_id;
234
        if (OB_FAIL(tenant_schema.get_zone_list(zone_list))) {
235
          LOG_WARN("fail to get zone list", KR(ret));
236
        }
237

238
        for (int64_t i = 0; (i < zone_list.count()) && OB_SUCC(ret); ++i) {
239
          tmp_merge_info.zone_ = zone_list.at(i);
240
          if (OB_FAIL(merge_info_array.push_back(tmp_merge_info))) {
241
            LOG_WARN("fail to push_back", KR(ret));
242
          }
243
        }
244
        // add zone merge info of current tenant(sys tenant or meta tenant)
245
        if (OB_SUCC(ret)) {
246
          if (OB_FAIL(ObGlobalMergeTableOperator::insert_global_merge_info(trans,
247
              tenant_id, global_info))) {
248
            LOG_WARN("fail to insert global merge info of current tenant", KR(ret), K(global_info));
249
          } else if (OB_FAIL(ObZoneMergeTableOperator::insert_zone_merge_infos(
250
                     trans, tenant_id, merge_info_array))) {
251
            LOG_WARN("fail to insert zone merge infos of current tenant", KR(ret), K(tenant_id),
252
              K(merge_info_array));
253
          }
254
        }
255
        // add zone merge info of relative user tenant if current tenant is meta tenant
256
        if (OB_SUCC(ret) && is_meta_tenant(tenant_id)) {
257
          const uint64_t user_tenant_id = gen_user_tenant_id(tenant_id);
258
          global_info.tenant_id_ = user_tenant_id;
259
          for (int64_t i = 0; i < merge_info_array.count(); ++i) {
260
            merge_info_array.at(i).tenant_id_ = user_tenant_id;
261
          }
262
          if (OB_FAIL(ObGlobalMergeTableOperator::insert_global_merge_info(trans,
263
              user_tenant_id, global_info))) {
264
            LOG_WARN("fail to insert global merge info of user tenant", KR(ret), K(global_info));
265
          } else if (OB_FAIL(ObZoneMergeTableOperator::insert_zone_merge_infos(
266
                    trans, user_tenant_id, merge_info_array))) {
267
            LOG_WARN("fail to insert zone merge infos of user tenant", KR(ret), K(user_tenant_id),
268
              K(merge_info_array));
269
          }
270
        }
271
      }
272
    }
273
  }
274

275
  return ret;
276
}
277

278

279
int ObDDLOperator::drop_tenant(const uint64_t tenant_id,
280
                               ObMySQLTransaction &trans,
281
                               const ObString *ddl_stmt_str/*=NULL*/)
282
{
283
  int ret = OB_SUCCESS;
284
  int64_t new_schema_version = OB_INVALID_VERSION;
285
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
286

287
  if (OB_ISNULL(schema_service_impl)) {
288
    ret = OB_ERR_SYS;
289
    LOG_ERROR("schema_service_impl must not null");
290
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(OB_SYS_TENANT_ID, new_schema_version))) {
291
    LOG_WARN("fail to gen new schema_version", K(ret));
292
  } else if (OB_FAIL(schema_service_impl->get_tenant_sql_service().delete_tenant(
293
      tenant_id, new_schema_version, trans, ddl_stmt_str))) {
294
    LOG_WARN("delete tenant failed", K(tenant_id), K(ret));
295
  }
296
  return ret;
297
}
298

299
int ObDDLOperator::delay_to_drop_tenant(
300
    ObTenantSchema &new_tenant_schema,
301
    ObMySQLTransaction &trans,
302
    const ObString *ddl_stmt_str/*=NULL*/)
303
{
304
  int ret = OB_SUCCESS;
305
  int64_t new_schema_version = OB_INVALID_VERSION;
306
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
307
  const uint64_t tenant_id = new_tenant_schema.get_tenant_id();
308
  const int64_t timeout = THIS_WORKER.get_timeout_remain();
309
  if (OB_ISNULL(schema_service_impl)) {
310
    ret = OB_ERR_SYS;
311
    LOG_ERROR("schema_service_impl must not null");
312
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(
313
                     OB_SYS_TENANT_ID, new_schema_version))) {
314
    LOG_WARN("fail to gen new schema_version", K(ret));
315
  } else {
316
    new_tenant_schema.set_schema_version(new_schema_version);
317
    // FIXME: after 4.0, drop_tenant_time is not needed by backup&restore anymore.
318
    // So just record local timestmap for drop tenant.
319
    new_tenant_schema.set_drop_tenant_time(ObTimeUtility::current_time());
320
    new_tenant_schema.set_status(TENANT_STATUS_DROPPING);
321
    new_tenant_schema.set_in_recyclebin(false);
322
    if (OB_FAIL(schema_service_impl->get_tenant_sql_service().delay_to_drop_tenant(
323
                                     new_tenant_schema, trans, ddl_stmt_str))) {
324
      LOG_WARN("schema_service_impl delay to drop tenant failed", K(new_tenant_schema), K(ret));
325
    }
326
  }
327
  return ret;
328
}
329

330
int ObDDLOperator::drop_tenant_to_recyclebin(
331
    ObSqlString &new_tenant_name,
332
    ObTenantSchema &tenant_schema,
333
    ObMySQLTransaction &trans,
334
    const ObString *ddl_stmt_str/*=NULL*/)
335
{
336
  int ret = OB_SUCCESS;
337
  const uint64_t tenant_id = tenant_schema.get_tenant_id();
338
  int64_t new_schema_version = OB_INVALID_VERSION;
339
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
340
  ObTenantSchema new_tenant_schema;
341
  if (OB_FAIL(new_tenant_schema.assign(tenant_schema))) {
342
    LOG_WARN("fail to assign", K(ret));
343
  } else if (OB_ISNULL(schema_service_impl)) {
344
    ret = OB_ERR_UNEXPECTED;
345
    LOG_ERROR("schema_service_impl must not null", K(ret));
346
  } else if (OB_INVALID_ID == tenant_id) {
347
    ret = OB_INVALID_ARGUMENT;
348
    LOG_WARN("tenant_id is invalid", K(ret), K(tenant_id));
349
  } else {
350
    ObRecycleObject recycle_object;
351
    recycle_object.set_original_name(tenant_schema.get_tenant_name_str());
352
    recycle_object.set_type(ObRecycleObject::TENANT);
353
    recycle_object.set_tenant_id(tenant_schema.get_tenant_id());
354
    // table_id is not usefull for recycled tenant, mock table_id as original tenant_id for DBA_RECYCLEBIN
355
    recycle_object.set_table_id(tenant_schema.get_tenant_id());
356
    recycle_object.set_tablegroup_id(OB_INVALID_ID);
357
    new_tenant_schema.set_in_recyclebin(true);
358
    if (OB_FAIL(schema_service_.gen_new_schema_version(OB_SYS_TENANT_ID, new_schema_version))) {
359
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
360
    } else if (FALSE_IT(new_tenant_schema.set_schema_version(new_schema_version))) {
361
    } else if (OB_FAIL(new_tenant_schema.set_tenant_name(new_tenant_name.string()))) {
362
      LOG_WARN("set tenant name failed", K(ret));
363
    } else if (FALSE_IT(recycle_object.set_object_name(new_tenant_name.string()))) {
364
      LOG_WARN("fail to set object name", K(ret));
365
    }
366
    if (OB_SUCC(ret)) {
367
      if (OB_FAIL(schema_service_impl->insert_recyclebin_object(recycle_object,
368
                                                                trans))) {
369
        LOG_WARN("insert recycle object failed", K(ret));
370
      } else if (OB_FAIL(schema_service_impl->get_tenant_sql_service().drop_tenant_to_recyclebin(
371
        new_tenant_schema, trans, OB_DDL_DROP_TENANT_TO_RECYCLEBIN, ddl_stmt_str))) {
372
        LOG_WARN("alter_tenant failed,", K(ret));
373
      }
374
    }
375
  }
376
  return ret;
377
}
378

379
int ObDDLOperator::check_tenant_exist(share::schema::ObSchemaGetterGuard &schema_guard,
380
                                      const ObString &tenant_name,
381
                                      bool &is_exist)
382
{
383
  int ret = OB_SUCCESS;
384
  is_exist = false;
385
  const ObTenantSchema *tenant = NULL;
386
  if (OB_FAIL(schema_guard.get_tenant_info(tenant_name, tenant))) {
387
    LOG_WARN("fail get tenant info", K(ret));
388
  } else if (OB_ISNULL(tenant)) {
389
    is_exist = false;
390
  } else {
391
    is_exist = true;
392
  }
393
  return ret;
394
}
395

396
int ObDDLOperator::flashback_tenant_from_recyclebin(
397
                   const share::schema::ObTenantSchema &tenant_schema,
398
                   ObMySQLTransaction &trans,
399
                   const ObString &new_tenant_name,
400
                   share::schema::ObSchemaGetterGuard &schema_guard,
401
                   const ObString &ddl_stmt_str)
402
{
403
  int ret = OB_SUCCESS;
404
  ObSchemaService *schema_service = schema_service_.get_schema_service();
405
  ObArray<ObRecycleObject> recycle_objs;
406
  ObTenantSchema new_tenant_schema;
407
  ObString final_tenant_name;
408
  if (OB_ISNULL(schema_service)) {
409
    ret = OB_ERR_UNEXPECTED;
410
    LOG_WARN("schema_service should not be null", K(ret));
411
  } else if (OB_INVALID_ID == tenant_schema.get_tenant_id()) {
412
    ret = OB_INVALID_ARGUMENT;
413
    LOG_WARN("tenant_id is invalid", K(ret));
414
  } else if (OB_FAIL(schema_service->fetch_recycle_object(
415
      OB_SYS_TENANT_ID,
416
      tenant_schema.get_tenant_name(),
417
      ObRecycleObject::TENANT,
418
      trans,
419
      recycle_objs))) {
420
    LOG_WARN("get_recycle_object failed", K(ret));
421
  } else if (recycle_objs.size() != 1) {
422
    ret = OB_ERR_UNEXPECTED;
423
    LOG_WARN("unexpected recycle object num", K(ret),
424
             "tenant_name", tenant_schema.get_tenant_name_str(),
425
             "size", recycle_objs.size());
426
  } else if (OB_FAIL(new_tenant_schema.assign(tenant_schema))) {
427
    LOG_WARN("fail to assign", K(ret));
428
  } else {
429
    const ObRecycleObject &recycle_obj = recycle_objs.at(0);
430
    if (new_tenant_name.empty()) {
431
      final_tenant_name = recycle_obj.get_original_name();
432
    } else {
433
      final_tenant_name = new_tenant_name;
434
    }
435
    new_tenant_schema.set_in_recyclebin(false);
436
    if (OB_FAIL(new_tenant_schema.set_tenant_name(final_tenant_name))) {
437
      LOG_WARN("set tenant name failed", K(final_tenant_name));
438
    }
439
    if (OB_SUCC(ret)) {
440
      bool is_tenant_exist = false;
441
      int64_t new_schema_version = OB_INVALID_VERSION;
442
      if (OB_FAIL(check_tenant_exist(schema_guard,
443
                                     new_tenant_schema.get_tenant_name_str(),
444
                                     is_tenant_exist))) {
445
        LOG_WARN("fail to check tenant", K(ret));
446
      } else if (is_tenant_exist) {
447
        ret = OB_TENANT_EXIST;
448
        LOG_USER_ERROR(OB_TENANT_EXIST, new_tenant_schema.get_tenant_name_str().ptr());
449
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(OB_SYS_TENANT_ID,
450
                                                                new_schema_version))) {
451
        LOG_WARN("fail to gen new schema_version", K(ret), K(OB_SYS_TENANT_ID));
452
      } else if (FALSE_IT(new_tenant_schema.set_schema_version(new_schema_version))) {
453
      } else if (OB_FAIL(schema_service->get_tenant_sql_service().alter_tenant(
454
          new_tenant_schema,
455
          trans,
456
          OB_DDL_FLASHBACK_TENANT,
457
          &ddl_stmt_str))) {
458
        LOG_WARN("update_tenant failed", K(ret), K(new_tenant_schema));
459
      } else if (OB_FAIL(schema_service->delete_recycle_object(
460
          OB_SYS_TENANT_ID,
461
          recycle_obj,
462
          trans))) {
463
        LOG_WARN("delete_recycle_object failed", K(ret), K(recycle_obj));
464
      }
465
    }
466
  }
467
  return ret;
468
}
469

470
int ObDDLOperator::purge_tenant_in_recyclebin(const share::schema::ObTenantSchema &tenant_schema,
471
                                              ObMySQLTransaction &trans,
472
                                              const ObString *ddl_stmt_str)
473
{
474
  int ret = OB_SUCCESS;
475
  ObSchemaService *schema_service = schema_service_.get_schema_service();
476
  if (OB_ISNULL(schema_service)) {
477
    ret = OB_ERR_UNEXPECTED;
478
    LOG_WARN("schema_service should not be null", K(ret));
479
  } else if (OB_INVALID_ID == tenant_schema.get_tenant_id()) {
480
    ret = OB_INVALID_ARGUMENT;
481
    LOG_WARN("tenant_id is invalid", K(ret));
482
  } else {
483
    ObArray<ObRecycleObject> recycle_objs;
484
    if (OB_FAIL(schema_service->fetch_recycle_object(
485
      OB_SYS_TENANT_ID,
486
      tenant_schema.get_tenant_name_str(),
487
      ObRecycleObject::TENANT,
488
      trans,
489
      recycle_objs))) {
490
      LOG_WARN("get_recycle_object failed", K(ret));
491
    } else if (recycle_objs.size() != 1) {
492
      ret = OB_ERR_UNEXPECTED;
493
      LOG_WARN("unexpected recycle object num", K(ret),
494
               "tenant_name", tenant_schema.get_tenant_name_str(),
495
               "size", recycle_objs.size());
496
    } else {
497
      const ObRecycleObject &recycle_obj = recycle_objs.at(0);
498
      share::schema::ObTenantSchema new_tenant_schema;
499
      if (OB_FAIL(new_tenant_schema.assign(tenant_schema))) {
500
        LOG_WARN("fail to assign", K(ret));
501
      } else if (OB_FAIL(delay_to_drop_tenant(
502
                         new_tenant_schema,
503
                         trans,
504
                         ddl_stmt_str))) {
505
        LOG_WARN("drop_table failed", K(ret));
506
      } else if (OB_FAIL(schema_service->delete_recycle_object(
507
                         OB_SYS_TENANT_ID,
508
                         recycle_obj,
509
                         trans))) {
510
        LOG_WARN("delete_recycle_object failed", K(ret));
511
      }
512
    }
513
  }
514
  return ret;
515
}
516

517
int ObDDLOperator::rename_tenant(
518
    share::schema::ObTenantSchema &tenant_schema,
519
    common::ObMySQLTransaction &trans,
520
    const common::ObString *ddl_stmt_str /* = NULL */)
521
{
522
  int ret = OB_SUCCESS;
523
  int64_t new_schema_version = OB_INVALID_VERSION;
524
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
525

526
  if (OB_ISNULL(schema_service_impl)) {
527
    ret = OB_ERR_SYS;
528
    LOG_ERROR("schema_service_impl must not null");
529
  } else if (!tenant_schema.is_valid()) {
530
    ret = OB_INVALID_ARGUMENT;
531
    LOG_WARN("invalid tenant schema", K(tenant_schema), K(ret));
532
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(
533
                     OB_SYS_TENANT_ID,
534
                     new_schema_version))) {
535
    LOG_WARN("fail to gen new schema_version", K(ret));
536
  } else {
537
    tenant_schema.set_schema_version(new_schema_version);
538
    if (OB_FAIL(schema_service_impl->get_tenant_sql_service().rename_tenant(
539
        tenant_schema, trans, ddl_stmt_str))) {
540
      LOG_WARN("rename tenant failed", K(ret), K(tenant_schema));
541
    }
542
  }
543
  return ret;
544
}
545

546
int ObDDLOperator::alter_tenant(ObTenantSchema &tenant_schema,
547
                                ObMySQLTransaction &trans,
548
                                const ObString *ddl_stmt_str/*=NULL*/)
549
{
550
  int ret = OB_SUCCESS;
551
  int64_t new_schema_version = OB_INVALID_VERSION;
552
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
553

554
  if (OB_ISNULL(schema_service_impl)) {
555
    ret = OB_ERR_SYS;
556
    LOG_ERROR("schema_service_impl must not null");
557
  } else if (!tenant_schema.is_valid()) {
558
    ret = OB_INVALID_ARGUMENT;
559
    LOG_WARN("invalid tenant schema", K(tenant_schema), K(ret));
560
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(OB_SYS_TENANT_ID, new_schema_version))) {
561
    LOG_WARN("fail to gen new schema_version", K(ret));
562
  } else {
563
    tenant_schema.set_schema_version(new_schema_version);
564
    const ObSchemaOperationType op = OB_DDL_ALTER_TENANT;
565
    if (OB_FAIL(schema_service_impl->get_tenant_sql_service().alter_tenant(
566
        tenant_schema, trans, op, ddl_stmt_str))) {
567
      LOG_WARN("schema_service_impl alter_tenant failed", K(tenant_schema), K(ret));
568
    }
569
  }
570
  return ret;
571
}
572

573
int ObDDLOperator::replace_sys_variable(ObSysVariableSchema &sys_variable_schema,
574
                                        const int64_t schema_version,
575
                                        ObMySQLTransaction &trans,
576
                                        const ObSchemaOperationType &operation_type,
577
                                        const common::ObString *ddl_stmt_str)
578
{
579
  int ret = OB_SUCCESS;
580
  int64_t start = ObTimeUtility::current_time();
581
  sys_variable_schema.set_schema_version(schema_version);
582
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
583

584
  if (schema_version < 0) {
585
    ret = OB_INVALID_ARGUMENT;
586
    LOG_WARN("invalid schema_version", K(ret), K(schema_version));
587
  } else if (OB_ISNULL(schema_service_impl)) {
588
    ret = OB_ERR_SYS;
589
    LOG_ERROR("schema_service_impl must not null");
590
  } else if (OB_FAIL(schema_service_impl->get_sys_variable_sql_service()
591
                     .replace_sys_variable(sys_variable_schema, trans, operation_type, ddl_stmt_str))) {
592
    LOG_WARN("schema_service_impl update sys variable failed", K(sys_variable_schema), K(operation_type), K(ret));
593
  }
594
  LOG_INFO("replace sys variable", K(ret),
595
           "tenant_id", sys_variable_schema.get_tenant_id(),
596
           "cost", ObTimeUtility::current_time() - start);
597
  return ret;
598
}
599

600
int ObDDLOperator::create_database(ObDatabaseSchema &database_schema,
601
                                   ObMySQLTransaction &trans,
602
                                   const ObString *ddl_stmt_str/*=NULL*/)
603
{
604
  int ret = OB_SUCCESS;
605
  //set the old database id
606
  const uint64_t tenant_id = database_schema.get_tenant_id();
607
  int64_t new_schema_version = OB_INVALID_VERSION;
608
  uint64_t new_database_id = database_schema.get_database_id();
609
  ObSchemaService *schema_service = schema_service_.get_schema_service();
610

611
  if (OB_ISNULL(schema_service)) {
612
    ret = OB_ERR_SYS;
613
    LOG_ERROR("schema_service must not null");
614
  } else if (OB_FAIL(schema_service->fetch_new_database_id(
615
      database_schema.get_tenant_id(), new_database_id))) {
616
    LOG_WARN("fetch new database id failed", K(database_schema.get_tenant_id()),
617
             K(ret));
618
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
619
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
620
  } else {
621
    database_schema.set_database_id(new_database_id);
622
    database_schema.set_schema_version(new_schema_version);
623
    if (OB_FAIL(schema_service->get_database_sql_service().insert_database(
624
        database_schema, trans, ddl_stmt_str))) {
625
      LOG_WARN("insert database failed", K(database_schema), K(ret));
626
    }
627
  }
628
  return ret;
629
}
630

631
int ObDDLOperator::alter_database(ObDatabaseSchema &new_database_schema,
632
                                  ObMySQLTransaction &trans,
633
                                  const ObSchemaOperationType op_type,
634
                                  const ObString *ddl_stmt_str/*=NULL*/,
635
                                  const bool need_update_schema_version/*=true*/)
636
{
637
  int ret = OB_SUCCESS;
638
  ObSchemaService *schema_service = schema_service_.get_schema_service();
639
  if (OB_ISNULL(schema_service)) {
640
    ret = OB_ERR_SYS;
641
    RS_LOG(ERROR, "schema_service must not null");
642
  } else {
643
    if (need_update_schema_version) {
644
      const uint64_t tenant_id = new_database_schema.get_tenant_id();
645
      int64_t new_schema_version = OB_INVALID_VERSION;
646
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
647
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
648
      } else {
649
        new_database_schema.set_schema_version(new_schema_version);
650
      }
651
    }
652
    if (OB_FAIL(ret)) {
653
    } else if (OB_FAIL(schema_service->get_database_sql_service()
654
         .update_database(new_database_schema,
655
                          trans,
656
                          op_type,
657
                          ddl_stmt_str))) {
658
      RS_LOG(WARN, "update database failed", K(new_database_schema), K(ret));
659
    }
660
  }
661
  return ret;
662
}
663

664
int ObDDLOperator::drop_database(const ObDatabaseSchema &db_schema,
665
                                 ObMySQLTransaction &trans,
666
                                 const ObString *ddl_stmt_str/*=NULL*/)
667
{
668
  int ret = OB_SUCCESS;
669
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
670
  const uint64_t tenant_id = db_schema.get_tenant_id();
671
  const uint64_t database_id = db_schema.get_database_id();
672
  int64_t new_schema_version = OB_INVALID_VERSION;
673

674
  if (OB_ISNULL(schema_service_impl)) {
675
    ret = OB_ERR_SYS;
676
    LOG_ERROR("schama service_impl and schema manage must not null",
677
        "schema_service_impl", OB_P(schema_service_impl), K(ret));
678
  }
679
  //drop tables in recyclebin
680
  if (OB_SUCC(ret)) {
681
    if (OB_FAIL(purge_table_of_database(db_schema, trans))) {
682
      LOG_WARN("purge_table_in_db failed", K(ret));
683
    }
684
  }
685

686
  //delete triggers in database, 只删除trigger_database != base_table_database 的trigger
687
  // trigger_database == base_table_database 的trigger会在下面删除表的时候删除
688
  if (OB_SUCC(ret)) {
689
    ObArray<uint64_t> trigger_ids;
690
    ObSchemaGetterGuard schema_guard;
691
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
692
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
693
    } else if (OB_FAIL(schema_guard.get_trigger_ids_in_database(tenant_id, database_id, trigger_ids))) {
694
      LOG_WARN("get trigger infos in database failed", KR(ret), K(tenant_id), K(database_id));
695
    } else {
696
      for (int64_t i = 0; OB_SUCC(ret) && i < trigger_ids.count(); i++) {
697
        const ObTriggerInfo *tg_info = NULL;
698
        const uint64_t trigger_id = trigger_ids.at(i);
699
        if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
700
          LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
701
        } else if (OB_FAIL(schema_guard.get_trigger_info(tenant_id, trigger_id, tg_info))) {
702
          LOG_WARN("fail to get trigger info", KR(ret), K(tenant_id), K(trigger_id));
703
        } else if (OB_ISNULL(tg_info)) {
704
          ret = OB_ERR_UNEXPECTED;
705
          LOG_WARN("trigger info is NULL", K(ret));
706
        } else {
707
          const ObSimpleTableSchemaV2 * tbl_schema = NULL;
708
          OZ (schema_guard.get_simple_table_schema(tenant_id, tg_info->get_base_object_id(), tbl_schema));
709
          CK (OB_NOT_NULL(tbl_schema));
710
          if (OB_SUCC(ret) && database_id != tbl_schema->get_database_id()) {
711
            OZ (drop_trigger(*tg_info, trans, NULL));
712
          }
713
        }
714
      }
715
    }
716
  }
717

718
  // delete tables in database
719
  if (OB_SUCC(ret)) {
720
    ObArray<uint64_t> table_ids;
721
    ObSchemaGetterGuard schema_guard;
722
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
723
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
724
    } else if (OB_FAIL(schema_guard.get_table_ids_in_database(tenant_id, database_id, table_ids))) {
725
      LOG_WARN("get tables in database failed", K(tenant_id), KT(database_id), K(ret));
726
    } else {
727
      // drop index tables first
728
      for (int64_t cycle = 0; OB_SUCC(ret) && cycle < 2; ++cycle) {
729
        for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count(); ++i) {
730
          const ObTableSchema *table = NULL;
731
          const uint64_t table_id = table_ids.at(i);
732
          if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
733
            LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
734
          } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, table))) {
735
            LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(table_id));
736
          } else if (OB_ISNULL(table)) {
737
            ret = OB_ERR_UNEXPECTED;
738
            LOG_WARN("table is NULL", K(ret));
739
          } else if (table->is_in_recyclebin()) {
740
            // already been dropped before
741
          } else {
742
            bool is_delete_first = table->is_aux_table() || table->is_mlog_table();
743
            if ((0 == cycle ? is_delete_first : !is_delete_first)) {
744
              // drop triggers before drop table
745
              if (OB_FAIL(drop_trigger_cascade(*table, trans))) {
746
                LOG_WARN("drop trigger failed", K(ret), K(table->get_table_id()));
747
              } else if (OB_FAIL(drop_table(*table, trans, NULL, false, NULL, true))) {
748
                LOG_WARN("drop table failed", K(ret), K(table->get_table_id()));
749
              }
750
            }
751
          }
752
        }
753
      }
754
    }
755
  }
756

757
  // delete outlines in database
758
  if (OB_SUCC(ret)) {
759
    ObArray<const ObSimpleOutlineSchema *> outline_schemas;
760
    ObSchemaGetterGuard schema_guard;
761
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
762
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
763
    } else if (OB_FAIL(schema_guard.get_simple_outline_schemas_in_database(tenant_id, database_id, outline_schemas))) {
764
      LOG_WARN("get outlines in database failed", K(tenant_id), KT(database_id), K(ret));
765
    } else {
766
      for (int64_t i = 0; OB_SUCC(ret) && i < outline_schemas.count(); ++i) {
767
        const ObSimpleOutlineSchema *outline_schema = outline_schemas.at(i);
768
        if (OB_ISNULL(outline_schema)) {
769
          ret = OB_ERR_UNEXPECTED;
770
          LOG_WARN("outline info is NULL", K(ret));
771
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
772
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
773
        } else if (OB_FAIL(schema_service_impl->get_outline_sql_service().delete_outline(tenant_id,
774
                                                                                         database_id,
775
                                                                                         outline_schema->get_outline_id(),
776
                                                                                         new_schema_version, trans))) {
777
          LOG_WARN("drop outline failed", KR(ret), "outline_id", outline_schema->get_outline_id());
778
        }
779
      }
780
    }
781
  }
782
  // delete synonyms in database
783
  if (OB_SUCC(ret)) {
784
    ObSchemaGetterGuard schema_guard;
785
    ObArray<const ObSimpleSynonymSchema *> synonym_schemas;
786
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
787
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
788
    } else if (OB_FAIL(schema_guard.get_simple_synonym_schemas_in_database(tenant_id, database_id, synonym_schemas))) {
789
      LOG_WARN("get synonyms in database failed", K(tenant_id), KT(database_id), K(ret));
790
    } else {
791
      for (int64_t i = 0; OB_SUCC(ret) && i < synonym_schemas.count(); ++i) {
792
        const ObSimpleSynonymSchema *synonym_schema = synonym_schemas.at(i);
793
        if (OB_ISNULL(synonym_schema)) {
794
          ret = OB_ERR_UNEXPECTED;
795
          LOG_WARN("synonym info is NULL", K(ret));
796
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
797
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
798
        } else if (OB_FAIL(schema_service_impl->get_synonym_sql_service().delete_synonym(tenant_id,
799
                                                                                         database_id,
800
                                                                                         synonym_schema->get_synonym_id(),
801
                                                                                         new_schema_version, &trans))) {
802
          LOG_WARN("drop synonym failed", KR(ret), "synonym_id", synonym_schema->get_synonym_id());
803
        }
804
      }
805
    }
806
  }
807

808
  // delete packages in database
809
  if (OB_SUCC(ret)) {
810
    ObSchemaGetterGuard schema_guard;
811
    ObArray<const ObSimplePackageSchema*> package_schemas;
812
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
813
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
814
    } else if (OB_FAIL(schema_guard.get_simple_package_schemas_in_database(tenant_id, database_id, package_schemas))) {
815
       LOG_WARN("get packages in database failed", K(tenant_id), KT(database_id), K(ret));
816
     } else {
817
       ObArray<const ObSAuditSchema *> audits;
818
       common::ObSqlString public_sql_string;
819
       for (int64_t i = 0; OB_SUCC(ret) && i < package_schemas.count(); ++i) {
820
         const ObSimplePackageSchema *package_schema = package_schemas.at(i);
821
         if (OB_ISNULL(package_schema)) {
822
           ret = OB_ERR_UNEXPECTED;
823
           LOG_WARN("package info is NULL", K(ret));
824
         } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
825
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
826
         } else if (OB_FAIL(schema_service_impl->get_routine_sql_service().drop_package(
827
                                                                           package_schema->get_tenant_id(),
828
                                                                           package_schema->get_database_id(),
829
                                                                           package_schema->get_package_id(),
830
                                                                           new_schema_version, trans))) {
831
           LOG_WARN("drop package failed", KR(ret), "package_id", package_schema->get_package_id());
832
         } else {
833
           // delete audit in package
834
           audits.reuse();
835
           public_sql_string.reuse();
836
           if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
837
                                                              AUDIT_PACKAGE,
838
                                                              package_schema->get_package_id(),
839
                                                              audits))) {
840
             LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
841
           } else if (!audits.empty()) {
842
             for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
843
               const ObSAuditSchema *audit_schema = audits.at(i);
844
               if (OB_ISNULL(audit_schema)) {
845
                 ret = OB_ERR_UNEXPECTED;
846
                 LOG_WARN("audit_schema is NULL", K(ret));
847
               } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
848
                 LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
849
               } else if (OB_FAIL(schema_service_impl->get_audit_sql_service().handle_audit_metainfo(
850
                   *audit_schema,
851
                   AUDIT_MT_DEL,
852
                   false,
853
                   new_schema_version,
854
                   NULL,
855
                   trans,
856
                   public_sql_string))) {
857
                 LOG_WARN("drop audit_schema failed",  KPC(audit_schema), K(ret));
858
               } else {
859
                 LOG_INFO("succ to delete audit_schema from drop package", KPC(audit_schema));
860
               }
861
             }
862
           } else {
863
             LOG_DEBUG("no need to delete audit_schema from drop package", K(audits), KPC(package_schema));
864
           }
865
         }
866
       }
867
     }
868
   }
869

870
  // delete routines in database
871
  if (OB_SUCC(ret)) {
872
    ObArray<uint64_t> routine_ids;
873
    ObSchemaGetterGuard schema_guard;
874
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
875
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
876
    } else if (OB_FAIL(schema_guard.get_routine_ids_in_database(tenant_id, database_id, routine_ids))) {
877
      LOG_WARN("get routines in database failed", K(tenant_id), KT(database_id), K(ret));
878
    } else {
879
      ObArray<const ObSAuditSchema *> audits;
880
      common::ObSqlString public_sql_string;
881
      for (int64_t i = 0; OB_SUCC(ret) && i < routine_ids.count(); ++i) {
882
        const ObRoutineInfo *routine_info = NULL;
883
        const uint64_t routine_id = routine_ids.at(i);
884
        int64_t new_schema_version = OB_INVALID_VERSION;
885
        if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
886
           LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
887
        } else if (OB_FAIL(schema_guard.get_routine_info(tenant_id, routine_id, routine_info))) {
888
          LOG_WARN("fail to get routine with id", KR(ret), K(tenant_id), K(routine_id));
889
        } else if (OB_ISNULL(routine_info)) {
890
          ret = OB_ERR_UNEXPECTED;
891
          LOG_WARN("routine info is NULL", K(ret));
892
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
893
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
894
        } else if (OB_FAIL(schema_service_impl->get_routine_sql_service().drop_routine(
895
                           *routine_info, new_schema_version, trans))) {
896
          LOG_WARN("drop routine failed", KR(ret), "routine_id", routine_id);
897
        } else {
898
          // delete audit in routine
899
          audits.reuse();
900
          public_sql_string.reuse();
901
          if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
902
                                                             AUDIT_PROCEDURE,
903
                                                             routine_id,
904
                                                             audits))) {
905
            LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
906
          } else if (!audits.empty()) {
907
            for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
908
              const ObSAuditSchema *audit_schema = audits.at(i);
909
              if (OB_ISNULL(audit_schema)) {
910
                ret = OB_ERR_UNEXPECTED;
911
                LOG_WARN("audit_schema is NULL", K(ret));
912
              } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
913
                LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
914
              } else if (OB_FAIL(schema_service_impl->get_audit_sql_service().handle_audit_metainfo(
915
                  *audit_schema,
916
                  AUDIT_MT_DEL,
917
                  false,
918
                  new_schema_version,
919
                  NULL,
920
                  trans,
921
                  public_sql_string))) {
922
                LOG_WARN("drop audit_schema failed",  KPC(audit_schema), K(ret));
923
              } else {
924
                LOG_INFO("succ to delete audit_schema from drop package", KPC(audit_schema));
925
              }
926
            }
927
          } else {
928
            LOG_DEBUG("no need to delete audit_schema from drop package", K(audits), KPC(routine_info));
929
          }
930
         }
931
      }
932
    }
933
  }
934

935
  // delete udts in database
936
  if (OB_SUCC(ret)) {
937
    ObArray<uint64_t> udt_ids;
938
    ObSchemaGetterGuard schema_guard;
939
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
940
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
941
    } else if (OB_FAIL(schema_guard.get_udt_ids_in_database(tenant_id, database_id, udt_ids))) {
942
      LOG_WARN("get udts in database failed", K(tenant_id), KT(database_id), K(ret));
943
    } else {
944
      for (int64_t i = 0; OB_SUCC(ret) && i < udt_ids.count(); ++i) {
945
        const ObUDTTypeInfo *udt_info = NULL;
946
        const uint64_t udt_id = udt_ids.at(i);
947
        int64_t new_schema_version = OB_INVALID_VERSION;
948
        if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
949
           LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
950
        } else if (OB_FAIL(schema_guard.get_udt_info(tenant_id, udt_id, udt_info))) {
951
          LOG_WARN("fail to get routine with id", KR(ret), K(tenant_id), K(udt_id));
952
        } else if (OB_ISNULL(udt_info)) {
953
          ret = OB_ERR_UNEXPECTED;
954
          LOG_WARN("routine info is NULL", K(ret));
955
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
956
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
957
        } else if (OB_FAIL(schema_service_impl->get_udt_sql_service().drop_udt(
958
                           *udt_info, new_schema_version, trans))) {
959
          LOG_WARN("drop routine failed", "routine_id", udt_info->get_type_id(), K(ret));
960
        }
961
      }
962
    }
963
  }
964

965
  // delete sequences in database
966
  if (OB_SUCC(ret)) {
967
    ObSchemaGetterGuard schema_guard;
968
    ObArray<const ObSequenceSchema*> sequence_schemas;
969
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
970
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
971
    } else if (OB_FAIL(schema_guard.get_sequence_schemas_in_database(tenant_id,
972
                                                                     database_id,
973
                                                                     sequence_schemas))) {
974
      LOG_WARN("get sequences in database failed",
975
               K(tenant_id), KT(database_id), K(ret));
976
    } else {
977
      ObArray<const ObSAuditSchema *> audits;
978
      common::ObSqlString public_sql_string;
979
      for (int64_t i = 0; OB_SUCC(ret) && i < sequence_schemas.count(); ++i) {
980
        const ObSequenceSchema *sequence_schema = sequence_schemas.at(i);
981
        if (OB_ISNULL(sequence_schema)) {
982
          ret = OB_ERR_UNEXPECTED;
983
          LOG_WARN("sequence info is NULL", K(ret));
984
        } else if (sequence_schema->get_is_system_generated()) {
985
          continue;
986
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
987
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
988
        } else if (OB_FAIL(schema_service_impl
989
                           ->get_sequence_sql_service()
990
                           .drop_sequence(*sequence_schema, new_schema_version, &trans))) {
991
          LOG_WARN("drop sequence failed",
992
                   KR(ret), K(*sequence_schema));
993
        } else {
994
          // delete audit in table
995
          audits.reuse();
996
          public_sql_string.reuse();
997
          if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
998
                                                             AUDIT_SEQUENCE,
999
                                                             sequence_schema->get_sequence_id(),
1000
                                                             audits))) {
1001
            LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
1002
          } else if (!audits.empty()) {
1003
            ObSchemaService *schema_service = schema_service_.get_schema_service();
1004
            for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
1005
              const ObSAuditSchema *audit_schema = audits.at(i);
1006
              if (OB_ISNULL(audit_schema)) {
1007
                ret = OB_ERR_UNEXPECTED;
1008
                LOG_WARN("audit_schema is NULL", K(ret));
1009
              } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))){
1010
                LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1011
              } else if (OB_FAIL(schema_service->get_audit_sql_service().handle_audit_metainfo(
1012
                  *audit_schema,
1013
                  AUDIT_MT_DEL,
1014
                  false,
1015
                  new_schema_version,
1016
                  NULL,
1017
                  trans,
1018
                  public_sql_string))) {
1019
                LOG_WARN("drop audit_schema failed",  KPC(audit_schema), K(ret));
1020
              } else {
1021
                LOG_INFO("succ to delete audit_schema from drop sequence", KPC(audit_schema));
1022
              }
1023
            }
1024
          } else {
1025
            LOG_DEBUG("no need to delete audit_schema from drop sequence", K(audits), KPC(sequence_schema));
1026
          }
1027
        }
1028
      }
1029
    }
1030
  }
1031

1032
  // delete mock_fk_parent_tables in database
1033
  if (OB_SUCC(ret)) {
1034
    ObSchemaGetterGuard schema_guard;
1035
    ObArray<uint64_t> mock_fk_parent_table_ids;
1036
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1037
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
1038
    } else if (OB_FAIL(schema_guard.get_mock_fk_parent_table_ids_in_database(tenant_id, database_id, mock_fk_parent_table_ids))) {
1039
      LOG_WARN("fail to get mock_fk_parent_table_schemas in database", K(ret), K(tenant_id), K(database_id));
1040
    } else {
1041
      ObArray<ObMockFKParentTableSchema> mock_fk_parent_table_schema_array;
1042
      int64_t new_schema_version = OB_INVALID_VERSION;
1043
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1044
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1045
      }
1046
      for (int64_t i = 0; OB_SUCC(ret) && i < mock_fk_parent_table_ids.count(); ++i) {
1047
        ObMockFKParentTableSchema tmp_mock_fk_parent_table_schema;
1048
        const uint64_t mock_fk_parent_table_id = mock_fk_parent_table_ids.at(i);
1049
        const ObMockFKParentTableSchema *mock_fk_parent_table_schema = NULL;
1050
        if (OB_FAIL(schema_guard.get_mock_fk_parent_table_schema_with_id(tenant_id,
1051
                                                                         mock_fk_parent_table_id,
1052
                                                                         mock_fk_parent_table_schema))) {
1053
          LOG_WARN("fail to get mock fk parent table schema", KR(ret), K(tenant_id), K(mock_fk_parent_table_id));
1054
        } else if (OB_ISNULL(mock_fk_parent_table_schema)) {
1055
          ret = OB_ERR_UNEXPECTED;
1056
          LOG_WARN("mock fk parent table schema is NULL", KR(ret), K(tenant_id), K(mock_fk_parent_table_id));
1057
        } else if (OB_FAIL(tmp_mock_fk_parent_table_schema.assign(*mock_fk_parent_table_schema))) {
1058
          LOG_WARN("fail to assign mock_fk_parent_table_schema", K(ret), K(tenant_id), K(database_id), KPC(mock_fk_parent_table_schema));
1059
        } else if (FALSE_IT(tmp_mock_fk_parent_table_schema.set_schema_version(new_schema_version))) {
1060
        } else if (FALSE_IT(tmp_mock_fk_parent_table_schema.set_operation_type(ObMockFKParentTableOperationType::MOCK_FK_PARENT_TABLE_OP_DROP_TABLE))) {
1061
        } else if (OB_FAIL(mock_fk_parent_table_schema_array.push_back(tmp_mock_fk_parent_table_schema))) {
1062
          LOG_WARN("push_back mock_fk_parent_table failed", K(ret), K(tmp_mock_fk_parent_table_schema));
1063
        }
1064
      }
1065
      if (FAILEDx(deal_with_mock_fk_parent_tables(trans, schema_guard, mock_fk_parent_table_schema_array))) {
1066
        LOG_WARN("drop mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema_array));
1067
      }
1068
    }
1069
  }
1070

1071
  if (OB_SUCC(ret)) {
1072
    int64_t new_schema_version = OB_INVALID_VERSION;
1073
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1074
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1075
    } else if (OB_FAIL(schema_service_impl->get_database_sql_service().delete_database(
1076
        db_schema,
1077
        new_schema_version,
1078
        trans,
1079
        ddl_stmt_str))) {
1080
      LOG_WARN("delete database failed", KT(database_id), K(ret));
1081
    }
1082
  }
1083
  return ret;
1084
}
1085

1086
// When delete database to recyclebin, it is necessary to update schema version
1087
// of each table, in case of hitting plan cache.
1088
// The key of plan cache is current database name, table_id and schema version.
1089
int ObDDLOperator::update_table_version_of_db(const ObDatabaseSchema &database_schema,
1090
                                              ObMySQLTransaction &trans)
1091
{
1092
  int ret = OB_SUCCESS;
1093
  const uint64_t tenant_id = database_schema.get_tenant_id();
1094
  const uint64_t database_id = database_schema.get_database_id();
1095
  int64_t new_schema_version = OB_INVALID_VERSION;
1096
  ObArray<uint64_t> table_ids;
1097
  ObSchemaGetterGuard schema_guard;
1098
  ObSchemaService *schema_service = schema_service_.get_schema_service();
1099
  if (OB_ISNULL(schema_service)) {
1100
    ret = OB_ERR_UNEXPECTED;
1101
    LOG_WARN("schema service should not be null", K(ret));
1102
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1103
    LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
1104
  } else if (OB_FAIL(schema_guard.get_table_ids_in_database(tenant_id,
1105
                                                            database_id,
1106
                                                            table_ids))) {
1107
    LOG_WARN("get_table_schemas_in_database failed", K(ret), K(tenant_id));
1108
  }
1109
  const int64_t table_count = table_ids.count();
1110
  for (int64_t idx = 0; OB_SUCC(ret) && idx < table_count; ++idx) {
1111
    const ObTableSchema *table = NULL;
1112
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1113
      LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
1114
    } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_ids.at(idx), table))) {
1115
      LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(table_ids.at(idx)));
1116
    } else if (OB_ISNULL(table)) {
1117
      ret = OB_ERR_UNEXPECTED;
1118
      LOG_WARN("table schema should not be null", K(ret));
1119
    } else if (table->is_index_table()) {
1120
      continue;
1121
    } else {
1122
      ObSEArray<ObAuxTableMetaInfo, 16> simple_index_infos;
1123
      if (OB_FAIL(table->get_simple_index_infos(simple_index_infos))) {
1124
        LOG_WARN("get_index_tid_array failed", K(ret));
1125
      }
1126
      ObSchemaGetterGuard tmp_schema_guard;
1127
      for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
1128
        const ObTableSchema *index_table_schema = NULL;
1129
        const uint64_t table_id = simple_index_infos.at(i).table_id_;
1130
        if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, tmp_schema_guard))) {
1131
          LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
1132
        } else if (OB_FAIL(tmp_schema_guard.get_table_schema(tenant_id,
1133
                                                             table_id,
1134
                                                             index_table_schema))) {
1135
          LOG_WARN("get_table_schema failed", KR(ret), "table id", table_id);
1136
        } else if (OB_ISNULL(index_table_schema)) {
1137
          ret = OB_ERR_UNEXPECTED;
1138
          LOG_WARN("table schema should not be null", K(ret));
1139
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1140
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1141
        } else {
1142
          HEAP_VAR(ObTableSchema, new_index_schema) {
1143
            if (OB_FAIL(new_index_schema.assign(*index_table_schema))) {
1144
              LOG_WARN("fail to assign schema", KR(ret), K(tenant_id), K(table_id));
1145
            } else {
1146
              new_index_schema.set_schema_version(new_schema_version);
1147
            }
1148
            if (FAILEDx(schema_service->get_table_sql_service().update_table_options(
1149
                trans,
1150
                *index_table_schema,
1151
                new_index_schema,
1152
                OB_DDL_DROP_TABLE_TO_RECYCLEBIN,
1153
                NULL))) {
1154
              LOG_WARN("update_table_option failed", KR(ret), K(tenant_id), K(table_id));
1155
            }
1156
          }
1157
        }
1158
      }
1159
      if (OB_SUCC(ret)) {
1160
        HEAP_VAR(ObTableSchema, new_ts) {
1161
          ObSchemaOperationType op_type;
1162
          if (OB_FAIL(new_ts.assign(*table))) {
1163
            LOG_WARN("fail to assign schema", K(ret));
1164
          } else {
1165
            op_type = new_ts.is_view_table() ? OB_DDL_DROP_VIEW_TO_RECYCLEBIN : OB_DDL_DROP_TABLE_TO_RECYCLEBIN;
1166
          }
1167
          if (OB_FAIL(ret)) {
1168
          } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1169
            LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1170
          } else {
1171
            new_ts.set_schema_version(new_schema_version);
1172
            if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
1173
                trans, *table, new_ts, op_type, NULL))) {
1174
              LOG_WARN("update_table_option failed", K(ret));
1175
            }
1176
          }
1177
        }
1178
      }
1179
    }
1180
  }
1181
  return ret;
1182
}
1183

1184
int ObDDLOperator::drop_database_to_recyclebin(const ObDatabaseSchema &database_schema,
1185
                                               ObMySQLTransaction &trans,
1186
                                               const ObString *ddl_stmt_str)
1187
{
1188
  int ret = OB_SUCCESS;
1189
  const uint64_t tenant_id = database_schema.get_tenant_id();
1190
  const uint64_t database_id = database_schema.get_database_id();
1191
  int64_t new_schema_version = OB_INVALID_VERSION;
1192
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
1193
  if (OB_ISNULL(schema_service_impl)) {
1194
    ret = OB_ERR_UNEXPECTED;
1195
    LOG_ERROR("schema_service_impl must not null", K(ret));
1196
  } else if (OB_INVALID_ID == tenant_id) {
1197
    ret = OB_INVALID_ARGUMENT;
1198
    LOG_WARN("tenant_id is invalid", K(ret), K(tenant_id));
1199
  } else {
1200
    ObSqlString new_db_name;
1201
    ObRecycleObject recycle_object;
1202
    ObDatabaseSchema new_database_schema;
1203
    ObSchemaService *schema_service = schema_service_.get_schema_service();
1204
    recycle_object.set_type(ObRecycleObject::DATABASE);
1205
    recycle_object.set_database_id(database_schema.get_database_id());
1206
    recycle_object.set_table_id(OB_INVALID_ID);
1207
    recycle_object.set_tablegroup_id(database_schema.get_default_tablegroup_id());
1208
    if (OB_FAIL(recycle_object.set_original_name(database_schema.get_database_name_str()))) {
1209
      LOG_WARN("fail to set original name for recycleb object", KR(ret), K(tenant_id), K(database_id));
1210
    } else if (OB_FAIL(new_database_schema.assign(database_schema))) {
1211
      LOG_WARN("fail to assign new database schema", KR(ret), K(tenant_id), K(database_id));
1212
    } else if (FALSE_IT(new_database_schema.set_in_recyclebin(true))) {
1213
    } else if (FALSE_IT(new_database_schema.set_default_tablegroup_id(OB_INVALID_ID))) {
1214
     // It ensure that db schema version of insert recyclebin and alter database
1215
     // is equal that updating table version and inserting recyclebin.
1216
    } else if (OB_FAIL(update_table_version_of_db(database_schema, trans))) {
1217
      LOG_WARN("update table version of db failed", K(ret), K(database_schema));
1218
    } else if (OB_ISNULL(schema_service)) {
1219
      ret = OB_ERR_SYS;
1220
      LOG_WARN("schema service should not be NULL");
1221
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1222
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1223
    } else if (FALSE_IT(new_database_schema.set_schema_version(new_schema_version))) {
1224
    } else if (OB_FAIL(construct_new_name_for_recyclebin(new_database_schema, new_db_name))) {
1225
      LOG_WARN("construct_new_name_for_recyclebin failed", K(ret));
1226
    } else if (OB_FAIL(new_database_schema.set_database_name(new_db_name.string()))) {
1227
      LOG_WARN("set database name failed", K(ret));
1228
    } else if (FALSE_IT(recycle_object.set_object_name(new_db_name.string()))) {
1229
    } else if (FALSE_IT(recycle_object.set_tenant_id(tenant_id))) {
1230
    } else if (OB_FAIL(schema_service_impl->insert_recyclebin_object(recycle_object,
1231
                                                              trans))) {
1232
      LOG_WARN("insert recycle object failed", K(ret));
1233
    } else if (OB_FAIL(alter_database(new_database_schema, trans,
1234
                                      OB_DDL_DROP_DATABASE_TO_RECYCLEBIN,
1235
                                      ddl_stmt_str,
1236
                                      false /*no need_new_schema_version*/))) {
1237
      LOG_WARN("alter_database failed,", K(ret));
1238
    } else {
1239
      ObSchemaGetterGuard schema_guard;
1240
      ObArray<const ObSimpleTableSchemaV2 *> tables;
1241
      if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1242
        LOG_WARN("fail to get schema guard", KR(ret), K(tenant_id));
1243
      } else if (OB_FAIL(schema_guard.get_table_schemas_in_database(tenant_id,
1244
                                                                    database_id,
1245
                                                                    tables))) {
1246
        LOG_WARN("get tables in database failed", KR(ret), K(tenant_id), K(database_id));
1247
      }
1248
      for (int64_t i = 0; OB_SUCC(ret) && i < tables.count(); ++i) {
1249
        const ObSimpleTableSchemaV2 *table_schema = tables.at(i);
1250
        if (OB_ISNULL(table_schema)) {
1251
          ret = OB_ERR_UNEXPECTED;
1252
          LOG_WARN("table is NULL", K(ret));
1253
        } else if (table_schema->is_view_table()
1254
                  && OB_FAIL(ObDependencyInfo::delete_schema_object_dependency(
1255
                            trans,
1256
                            tenant_id,
1257
                            table_schema->get_table_id(),
1258
                            table_schema->get_schema_version(),
1259
                            ObObjectType::VIEW))) {
1260
          LOG_WARN("failed to delete_schema_object_dependency", K(ret), K(tenant_id),
1261
          K(table_schema->get_table_id()));
1262
        }
1263
      }
1264
    }
1265
  }
1266
  return ret;
1267
}
1268

1269
int ObDDLOperator::create_tablegroup(ObTablegroupSchema &tablegroup_schema,
1270
                                     ObMySQLTransaction &trans,
1271
                                     const ObString *ddl_stmt_str/*=NULL*/)
1272
{
1273
  int ret = OB_SUCCESS;
1274
  uint64_t new_tablegroup_id = OB_INVALID_ID;
1275
  const uint64_t tenant_id = tablegroup_schema.get_tenant_id();
1276
  int64_t new_schema_version = OB_INVALID_VERSION;
1277
  ObSchemaService *schema_service = schema_service_.get_schema_service();
1278

1279
  if (OB_ISNULL(schema_service)) {
1280
    ret = OB_ERR_SYS;
1281
    LOG_ERROR("schema_service must not null");
1282
  } else if (OB_FAIL(schema_service->fetch_new_tablegroup_id(
1283
    tablegroup_schema.get_tenant_id(), new_tablegroup_id))) {
1284
    LOG_WARN("failed to fetch new_tablegroup_id",
1285
        "tenant_id", tablegroup_schema.get_tenant_id(), K(ret));
1286
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1287
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1288
  } else {
1289
    tablegroup_schema.set_tablegroup_id(new_tablegroup_id);
1290
    tablegroup_schema.set_schema_version(new_schema_version);
1291
    if (OB_FAIL(schema_service->get_tablegroup_sql_service().insert_tablegroup(
1292
        tablegroup_schema, trans, ddl_stmt_str))) {
1293
      LOG_WARN("insert tablegroup failed", K(ret));
1294
    }
1295
  }
1296
  return ret;
1297
}
1298

1299
int ObDDLOperator::drop_tablegroup(const ObTablegroupSchema &tablegroup_schema,
1300
                                   ObMySQLTransaction &trans,
1301
                                   const ObString *ddl_stmt_str/*=NULL*/)
1302
{
1303
  int ret = OB_SUCCESS;
1304

1305
  ObSchemaGetterGuard schema_guard;
1306
  ObArenaAllocator allocator(ObModIds::OB_SCHEMA_OB_SCHEMA_ARENA);
1307
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
1308
  const uint64_t tenant_id = tablegroup_schema.get_tenant_id();
1309
  const uint64_t tablegroup_id = tablegroup_schema.get_tablegroup_id();
1310
  if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1311
    LOG_WARN("failed to get schema guard", K(ret));
1312
  } else if (OB_ISNULL(schema_service_impl)) {
1313
    ret = OB_ERR_SYS;
1314
    LOG_ERROR("schama schema_service_impl and schema manage must not null",
1315
              "schema_service_impl", OB_P(schema_service_impl), K(ret));
1316
  } else {
1317
    // check whether tablegroup is empty, if not empty, return OB_TABLEGROUP_NOT_EMPTY
1318
    bool not_empty = false;
1319
    ObArray<const ObSimpleTableSchemaV2 *> tables;
1320
    if (OB_FAIL(schema_guard.get_table_schemas_in_tablegroup(
1321
        tenant_id, tablegroup_id, tables))) {
1322
      LOG_WARN("get table ids in tablegroup failed", K(tenant_id), KT(tablegroup_id), K(ret));
1323
    } else if (tables.count() > 0) {
1324
      // When tablegroup is dropped, there must not be table in tablegroup, otherwise it is failed to get tablegroup
1325
      // schema when getting derived relation property by table. As locality and primary_zone is add in tablegroup
1326
      // after 2.0
1327
      //
1328
      not_empty = true;
1329
    }
1330
    // check databases' default_tablegroup_id
1331
    if (OB_SUCC(ret) && !not_empty) {
1332
      if (OB_FAIL(schema_guard.check_database_exists_in_tablegroup(
1333
          tenant_id, tablegroup_id, not_empty))) {
1334
        LOG_WARN("failed to check whether database exists in table group",
1335
                 K(tenant_id), KT(tablegroup_id), K(ret));
1336
      }
1337
    }
1338
    // check tenants' default_tablegroup_id
1339
    if (OB_SUCC(ret) && !not_empty) {
1340
      const ObTenantSchema *tenant_schema = NULL;
1341
      if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) {
1342
        LOG_WARN("fail to get tenant info", K(ret), KT(tenant_id));
1343
      } else if (OB_ISNULL(tenant_schema)) {
1344
        ret = OB_ERR_UNEXPECTED;
1345
        LOG_WARN("tenant schema is null", K(ret), KT(tenant_id));
1346
      } else if (tablegroup_id == tenant_schema->get_default_tablegroup_id()) {
1347
        not_empty = true;
1348
      }
1349
    }
1350
    if (OB_SUCC(ret) && not_empty) {
1351
      ret = OB_TABLEGROUP_NOT_EMPTY;
1352
      LOG_WARN("tablegroup still has tables or is some databases' default tablegroup or is tenant default tablegroup, can't delete it",
1353
          KT(tablegroup_id), K(ret));
1354
    }
1355
  }
1356

1357
  // delete tablegroup and log ddl operation
1358
  if (OB_SUCC(ret)) {
1359
    int64_t new_schema_version = OB_INVALID_VERSION;
1360
    if (OB_FAIL(ret)) {
1361
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1362
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1363
    } else if (OB_FAIL(schema_service_impl->get_tablegroup_sql_service().
1364
                       delete_tablegroup(tablegroup_schema,
1365
                                         new_schema_version,
1366
                                         trans, ddl_stmt_str))) {
1367
      LOG_WARN("delete tablegroup failed", KT(tablegroup_id), K(ret));
1368
    }
1369
  }
1370
  return ret;
1371
}
1372

1373
int ObDDLOperator::alter_tablegroup(ObTablegroupSchema &new_schema,
1374
                                    common::ObMySQLTransaction &trans,
1375
                                    const ObString *ddl_stmt_str)
1376
{
1377
  int ret = OB_SUCCESS;
1378
  const uint64_t tenant_id = new_schema.get_tenant_id();
1379
  int64_t new_schema_version = OB_INVALID_VERSION;
1380
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
1381
  if (!new_schema.is_valid()) {
1382
    ret = OB_INVALID_ARGUMENT;
1383
    LOG_WARN("invalid argument", K(ret), K(new_schema));
1384
  } else if (OB_ISNULL(schema_service_impl)) {
1385
    ret = OB_ERR_SYS;
1386
    LOG_ERROR("schema schema_service_impl must not null",
1387
           "schema_service_impl", OB_P(schema_service_impl), K(ret));
1388
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1389
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1390
  } else {
1391
    new_schema.set_schema_version(new_schema_version);
1392
    if (OB_FAIL(schema_service_impl->get_tablegroup_sql_service().update_tablegroup(
1393
                new_schema, trans, ddl_stmt_str))) {
1394
      LOG_WARN("fail to get tablegroup sql service", K(ret));
1395
    }
1396
  }
1397
  return ret;
1398
}
1399

1400
int ObDDLOperator::alter_tablegroup(ObSchemaGetterGuard &schema_guard,
1401
                                    ObTableSchema &new_table_schema,
1402
                                    common::ObMySQLTransaction &trans,
1403
                                    const ObString *ddl_stmt_str/*=NULL*/)
1404
{
1405
  int ret = OB_SUCCESS;
1406
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
1407
  int64_t new_schema_version = OB_INVALID_VERSION;
1408
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
1409
  if (OB_ISNULL(schema_service_impl)) {
1410
     ret = OB_ERR_SYS;
1411
     RS_LOG(ERROR, "schema schema_service_impl must not null",
1412
            "schema_service_impl", OB_P(schema_service_impl), K(ret));
1413
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1414
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1415
  } else {
1416
    new_table_schema.set_schema_version(new_schema_version);
1417
    // check whether tablegroup is empty, if not empty, return OB_TABLEGROUP_NOT_EMPTY
1418
    if (OB_FAIL(schema_service_impl->get_table_sql_service().update_tablegroup(
1419
                schema_guard,
1420
                new_table_schema,
1421
                trans,
1422
                ddl_stmt_str))) {
1423
      RS_LOG(WARN, "alter tablegroup failed", K(ret));
1424
    }
1425
  }
1426
  return ret;
1427
}
1428

1429
int ObDDLOperator::handle_audit_metainfo(const share::schema::ObSAuditSchema &audit_schema,
1430
                                         const ObSAuditModifyType modify_type,
1431
                                         const bool need_update,
1432
                                         const ObString *ddl_stmt_str,
1433
                                         common::ObMySQLTransaction &trans,
1434
                                         common::ObSqlString &public_sql_string)
1435
{
1436
  int ret = OB_SUCCESS;
1437
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
1438
  int64_t new_schema_version = OB_INVALID_VERSION;
1439
  if (OB_ISNULL(schema_sql_service)) {
1440
    ret = OB_ERR_SYS;
1441
    LOG_ERROR("schema_sql_service must not be null", K(ret));
1442
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(audit_schema.get_tenant_id(),
1443
                                                            new_schema_version))) {
1444
    LOG_WARN("fail to gen new schema_version", K(ret), K(audit_schema.get_tenant_id()));
1445
  } else {
1446
    ObAuditSqlService &tmp_audit_ss = schema_sql_service->get_audit_sql_service();
1447
    if (OB_FAIL(tmp_audit_ss.handle_audit_metainfo(audit_schema,
1448
                                                   modify_type,
1449
                                                   need_update,
1450
                                                   new_schema_version,
1451
                                                   ddl_stmt_str,
1452
                                                   trans,
1453
                                                   public_sql_string))) {
1454
      LOG_WARN("Failed to handle audit meta info", K(audit_schema), K(modify_type),
1455
                                                   K(new_schema_version), K(ret));
1456
    }
1457
  }
1458
  return ret;
1459
}
1460

1461
int ObDDLOperator::get_user_id_for_inner_ur(ObUserInfo &user,
1462
                                            bool &is_inner_ur,
1463
                                            uint64_t &new_user_id)
1464
{
1465
  int ret = OB_SUCCESS;
1466
  const char* ur_name = user.get_user_name();
1467
  ObSchemaService *schema_service = schema_service_.get_schema_service();
1468
  const ObSysVariableSchema *sys_variable_schema = NULL;
1469
  ObSchemaGetterGuard schema_guard;
1470
  bool is_oracle_mode = false;
1471
  const uint64_t tenant_id = user.get_tenant_id();
1472
  is_inner_ur = false;
1473
  if (OB_ISNULL(schema_service)) {
1474
    ret = OB_ERR_UNEXPECTED;
1475
    LOG_WARN("schema_service is NULL", K(ret));
1476
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1477
    LOG_WARN("failed to get schema guard", K(ret));
1478
  } else if (OB_FAIL(schema_guard.get_sys_variable_schema(tenant_id, sys_variable_schema))) {
1479
    LOG_WARN("get sys variable schema failed", K(ret));
1480
  } else if (OB_ISNULL(sys_variable_schema)) {
1481
    ret = OB_ERR_UNEXPECTED;
1482
    LOG_WARN("sys variable schema is null", K(ret));
1483
  } else if (OB_FAIL(sys_variable_schema->get_oracle_mode(is_oracle_mode))) {
1484
    RS_LOG(WARN, "failed to get oracle mode", K(ret), K(tenant_id));
1485
  } else if (is_oracle_mode) {
1486
    if (STRCMP(ur_name, OB_ORA_LBACSYS_NAME) == 0) {
1487
      new_user_id = OB_ORA_LBACSYS_USER_ID;
1488
      is_inner_ur = true;
1489
    } else if (STRCMP(ur_name, OB_ORA_CONNECT_ROLE_NAME) == 0) {
1490
      new_user_id = OB_ORA_CONNECT_ROLE_ID;
1491
      is_inner_ur = true;
1492
    } else if (STRCMP(ur_name, OB_ORA_RESOURCE_ROLE_NAME) == 0) {
1493
      new_user_id = OB_ORA_RESOURCE_ROLE_ID;
1494
      is_inner_ur = true;
1495
    } else if (STRCMP(ur_name, OB_ORA_DBA_ROLE_NAME) == 0) {
1496
      new_user_id = OB_ORA_DBA_ROLE_ID;
1497
      is_inner_ur = true;
1498
    } else if (STRCMP(ur_name, OB_ORA_PUBLIC_ROLE_NAME) == 0) {
1499
      new_user_id = OB_ORA_PUBLIC_ROLE_ID;
1500
      is_inner_ur = true;
1501
    }
1502
  }
1503
  // both oracle mode and mysql mode
1504
  if (OB_SUCC(ret)) {
1505
    if (STRCMP(ur_name, OB_ORA_AUDITOR_NAME) == 0) {
1506
      new_user_id = OB_ORA_AUDITOR_USER_ID;
1507
      is_inner_ur = true;
1508
    }
1509
  }
1510
  return ret;
1511
}
1512

1513
int ObDDLOperator::create_user(ObUserInfo &user,
1514
                               const ObString *ddl_stmt_str,
1515
                               ObMySQLTransaction &trans)
1516
{
1517
  int ret = OB_SUCCESS;
1518
  uint64_t new_user_id = user.get_user_id();
1519
  ObSchemaService *schema_service = schema_service_.get_schema_service();
1520
  bool is_inner_ur;
1521
  if (OB_ISNULL(schema_service)) {
1522
    ret = OB_ERR_SYS;
1523
    LOG_ERROR("schema_service must not null");
1524
  } else if (OB_FAIL(get_user_id_for_inner_ur(user, is_inner_ur, new_user_id))) {
1525
      LOG_WARN("failed to fetch_new_user_id", "tennat_id", user.get_tenant_id(), K(ret));
1526
  } else if (!is_inner_ur &&
1527
             OB_FAIL(schema_service->fetch_new_user_id(user.get_tenant_id(), new_user_id))) {
1528
    LOG_WARN("failed to fetch_new_user_id", "tennat_id", user.get_tenant_id(), K(ret));
1529
  } else {
1530
    user.set_user_id(new_user_id);
1531
  }
1532
  if (OB_SUCC(ret)) {
1533
    const uint64_t tenant_id = user.get_tenant_id();
1534
    int64_t new_schema_version = OB_INVALID_VERSION;
1535
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1536
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1537
    } else if (OB_FAIL(schema_service->get_user_sql_service().create_user(
1538
               user, new_schema_version, ddl_stmt_str, trans))) {
1539
      LOG_WARN("insert user failed", K(user), K(ret));
1540
    }
1541
  }
1542
  return ret;
1543
}
1544

1545
int ObDDLOperator::create_table(ObTableSchema &table_schema,
1546
                                ObMySQLTransaction &trans,
1547
                                const ObString *ddl_stmt_str/*=NULL*/,
1548
                                const bool need_sync_schema_version,
1549
                                const bool is_truncate_table /*false*/)
1550
{
1551
  int ret = OB_SUCCESS;
1552
  const uint64_t tenant_id = table_schema.get_tenant_id();
1553
  int64_t new_schema_version = OB_INVALID_VERSION;
1554
  ObSchemaService *schema_service = schema_service_.get_schema_service();
1555
  ObSchemaGetterGuard schema_guard;
1556
  if (OB_ISNULL(schema_service)) {
1557
    ret = OB_ERR_SYS;
1558
    RS_LOG(ERROR, "schema_service must not null");
1559
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1560
    LOG_WARN("failed to get schema guard", K(ret));
1561
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1562
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1563
  } else {
1564
    table_schema.set_schema_version(new_schema_version);
1565
    if (OB_FAIL(schema_service->get_table_sql_service().create_table(
1566
        table_schema,
1567
        trans,
1568
        ddl_stmt_str,
1569
        need_sync_schema_version,
1570
        is_truncate_table))) {
1571
      RS_LOG(WARN, "failed to create table", K(ret));
1572
    } else if (OB_FAIL(sync_version_for_cascade_table(tenant_id,
1573
               table_schema.get_depend_table_ids(), trans))) {
1574
      RS_LOG(WARN, "fail to sync cascade depend table", K(ret));
1575
    } else if (OB_FAIL(sync_version_for_cascade_mock_fk_parent_table(table_schema.get_tenant_id(), table_schema.get_depend_mock_fk_parent_table_ids(), trans))) {
1576
      LOG_WARN("fail to sync cascade depend_mock_fk_parent_table_ids table", K(ret));
1577
    }
1578
  }
1579

1580
  // add audit in table if necessary
1581
  if (OB_SUCC(ret) && !is_truncate_table && (table_schema.is_user_table() || table_schema.is_external_table())) {
1582
    const uint64_t tenant_id = table_schema.get_tenant_id();
1583
    ObArray<const ObSAuditSchema *> audits;
1584

1585
    ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
1586
    if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
1587
                                                              AUDIT_OBJ_DEFAULT,
1588
                                                              OB_AUDIT_MOCK_USER_ID,
1589
                                                              audits))) {
1590
      LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(table_schema), K(ret));
1591
    } else if (!audits.empty()) {
1592
      common::ObSqlString public_sql_string;
1593
      ObSAuditSchema new_audit_schema;
1594
      for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
1595
        uint64_t new_audit_id = common::OB_INVALID_ID;
1596
        const ObSAuditSchema *audit_schema = audits.at(i);
1597
        if (OB_ISNULL(audit_schema)) {
1598
          ret = OB_ERR_UNEXPECTED;
1599
          LOG_WARN("audit_schema is NULL", K(ret));
1600
        } else if (!audit_schema->is_access_operation_for_table()) {
1601
          continue;
1602
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1603
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1604
        } else if (OB_FAIL(schema_service_impl->fetch_new_audit_id(tenant_id, new_audit_id))) {
1605
          LOG_WARN("Failed to fetch new_audit_id", K(ret));
1606
        } else if (OB_FAIL(new_audit_schema.assign(*audit_schema))) {
1607
          LOG_WARN("fail to assign audit schema", KR(ret));
1608
        } else {
1609
          new_audit_schema.set_schema_version(new_schema_version);
1610
          new_audit_schema.set_audit_id(new_audit_id);
1611
          new_audit_schema.set_audit_type(AUDIT_TABLE);
1612
          new_audit_schema.set_owner_id(table_schema.get_table_id());
1613
          if (OB_FAIL(schema_service_impl->get_audit_sql_service().handle_audit_metainfo(
1614
              new_audit_schema,
1615
              AUDIT_MT_ADD,
1616
              false,
1617
              new_schema_version,
1618
              NULL,
1619
              trans,
1620
              public_sql_string))) {
1621
            LOG_WARN("drop audit_schema failed",  K(new_audit_schema), K(ret));
1622
          } else {
1623
            LOG_INFO("succ to add audit_schema from default", K(new_audit_schema));
1624
          }
1625
        }
1626
      }
1627
    }
1628
  }
1629
  return ret;
1630
}
1631

1632
int ObDDLOperator::sync_version_for_cascade_table(
1633
    const uint64_t tenant_id,
1634
    const ObIArray<uint64_t> &table_ids,
1635
    ObMySQLTransaction &trans)
1636
{
1637
  int ret = OB_SUCCESS;
1638
  uint64_t id = OB_INVALID_ID;
1639
  const ObTableSchema *schema = NULL;
1640
  ObSchemaService *schema_service = schema_service_.get_schema_service();
1641
  if (OB_ISNULL(schema_service)) {
1642
    ret = OB_ERR_SYS;
1643
    RS_LOG(ERROR, "schema_service must not null");
1644
  } else {
1645
    for (int64_t i = 0; i < table_ids.count() && OB_SUCC(ret); i++) {
1646
      ObSchemaGetterGuard schema_guard;
1647
      id = table_ids.at(i);
1648
      int64_t new_schema_version = OB_INVALID_VERSION;
1649
      ObTableSchema tmp_schema;
1650
      if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1651
        RS_LOG(WARN, "get schema guard failed", K(ret), K(tenant_id), K(id));
1652
      } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, id, schema))) {
1653
        LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(id));
1654
      } else if (!schema) {
1655
        ret = OB_ERR_UNEXPECTED;
1656
        LOG_WARN("schema is NULL", K(ret));
1657
      } else if (OB_FAIL(tmp_schema.assign(*schema))) {
1658
        LOG_WARN("fail to assign schema", K(ret), KPC(schema));
1659
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
1660
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
1661
      } else if (OB_FAIL(schema_service->get_table_sql_service().sync_schema_version_for_history(
1662
              trans,
1663
              tmp_schema,
1664
              new_schema_version))) {
1665
        RS_LOG(WARN, "fail to sync schema version", K(ret));
1666
      } else {
1667
        LOG_INFO("synced schema version for depend table", K(id),
1668
            "from", schema->get_schema_version(), "to", new_schema_version);
1669
      }
1670
    }
1671
  }
1672

1673
  return ret;
1674
}
1675

1676
// Notice that, truncate table, offline ddl should sync origin sequence values.
1677
int ObDDLOperator::create_sequence_in_create_table(ObTableSchema &table_schema,
1678
                                                   common::ObMySQLTransaction &trans,
1679
                                                   share::schema::ObSchemaGetterGuard &schema_guard,
1680
                                                   const obrpc::ObSequenceDDLArg *sequence_ddl_arg)
1681
{
1682
  int ret = OB_SUCCESS;
1683
  if (!(table_schema.is_user_table() || table_schema.is_oracle_tmp_table())) {
1684
    // do nothing
1685
  } else {
1686
    for (ObTableSchema::const_column_iterator iter = table_schema.column_begin();
1687
         OB_SUCC(ret) && iter != table_schema.column_end(); ++iter) {
1688
      ObColumnSchemaV2 &column_schema = (**iter);
1689
      if (!column_schema.is_identity_column()) {
1690
        continue;
1691
      } else {
1692
        ObSequenceDDLProxy ddl_operator(schema_service_);
1693
        char temp_sequence_name[OB_MAX_SEQUENCE_NAME_LENGTH + 1] = { 0 };
1694
        int32_t len = snprintf(temp_sequence_name, sizeof(temp_sequence_name), "%s%lu%c%lu",
1695
                              IDENTITY_COLUMN_SEQUENCE_OBJECT_NAME_PREFIX,
1696
                              ObSchemaUtils::get_extract_schema_id(table_schema.get_tenant_id(), table_schema.get_table_id()),
1697
                              '_',
1698
                              column_schema.get_column_id());
1699
        if (OB_UNLIKELY(len < 0)) {
1700
          ret = OB_ERR_UNEXPECTED;
1701
          LOG_WARN("create sequence name fail", K(ret), K(column_schema));
1702
        } else {
1703
          ObString sequence_name = ObString::make_string(temp_sequence_name);
1704
          ObSequenceSchema sequence_schema;
1705
          if (nullptr != sequence_ddl_arg) {
1706
            sequence_schema = sequence_ddl_arg->seq_schema_;
1707
          } else {
1708
            const ObSequenceSchema *tmp_sequence_schema = NULL;
1709
            if (OB_FAIL(schema_guard.get_sequence_schema(table_schema.get_tenant_id(),
1710
                                                         column_schema.get_sequence_id(),
1711
                                                         tmp_sequence_schema))) {
1712
              LOG_WARN("get sequence schema failed", K(ret), K(column_schema));
1713
            } else if (OB_ISNULL(tmp_sequence_schema)) {
1714
              ret = OB_NOT_INIT;
1715
              LOG_WARN("sequence not found", K(ret), K(column_schema));
1716
            } else if (OB_FAIL(sequence_schema.assign(*tmp_sequence_schema))) {
1717
              LOG_WARN("fail to assign sequence schema", KR(ret));
1718
            } else {}
1719
          }
1720
          if (OB_SUCC(ret)) {
1721
            sequence_schema.set_database_id(table_schema.get_database_id());
1722
            sequence_schema.set_sequence_name(sequence_name);
1723
            if (nullptr == sequence_ddl_arg) {
1724
              // In some scenes like trunctae table and offline ddl, should inherit the sequce object from origin table except sequence id, etc.
1725
              // Validity check and set of option bitset are completed in creating origin table phase,
1726
              // thus we do not have to check the validity of option_bitset again for the hidden table.
1727
              if (OB_FAIL(ddl_operator.create_sequence_without_bitset(sequence_schema,
1728
                                                                      trans,
1729
                                                                      schema_guard,
1730
                                                                      nullptr))) {
1731
              LOG_WARN("create sequence fail", K(ret), K(table_schema));
1732
              } else {/* do nothing. */}
1733
            } else if (OB_FAIL(ddl_operator.create_sequence(sequence_schema,
1734
                                                            sequence_ddl_arg->option_bitset_,
1735
                                                            trans,
1736
                                                            schema_guard,
1737
                                                            NULL))) {
1738
              LOG_WARN("create sequence fail", K(ret), K(table_schema));
1739
            }
1740
            if (OB_SUCC(ret)) {
1741
              column_schema.set_sequence_id(sequence_schema.get_sequence_id());
1742
              char sequence_string[OB_MAX_SEQUENCE_NAME_LENGTH + 1] = { 0 };
1743
              uint64_t pure_sequence_id = ObSchemaUtils::get_extract_schema_id(table_schema.get_tenant_id(), sequence_schema.get_sequence_id());
1744
              len = snprintf(sequence_string, sizeof(sequence_string), "%lu", pure_sequence_id);
1745
              if (OB_UNLIKELY(len < 0)) {
1746
                ret = OB_ERR_UNEXPECTED;
1747
                LOG_WARN("create sequence name fail", K(ret), K(table_schema));
1748
              } else {
1749
                ObObjParam cur_default_value;  // for desc table
1750
                ObObjParam orig_default_value; // for store pure_sequence_id
1751
                cur_default_value.set_varchar("SEQUENCE.NEXTVAL");
1752
                cur_default_value.set_collation_type(ObCharset::get_system_collation());
1753
                cur_default_value.set_collation_level(CS_LEVEL_IMPLICIT);
1754
                cur_default_value.set_param_meta();
1755
                orig_default_value.set_varchar(sequence_string);
1756
                orig_default_value.set_collation_type(ObCharset::get_system_collation());
1757
                orig_default_value.set_collation_level(CS_LEVEL_IMPLICIT);
1758
                orig_default_value.set_param_meta();
1759
                if (OB_FAIL(column_schema.set_cur_default_value(cur_default_value))) {
1760
                  LOG_WARN("set current default value fail", K(ret));
1761
                } else if (OB_FAIL(column_schema.set_orig_default_value(orig_default_value))) {
1762
                  LOG_WARN("set origin default value fail", K(ret), K(column_schema));
1763
                }
1764
              }
1765
            }
1766
          }
1767
        }
1768
      }
1769
    }
1770
  }
1771
  return ret;
1772
}
1773

1774
// Sequence_schema and table_schema have a one-to-one relationship.
1775
// Sequence can only be changed through interfaces such as alter/drop table,
1776
// So there is no need to increase the schema version number separately.
1777
int ObDDLOperator::drop_sequence_in_drop_table(const ObTableSchema &table_schema,
1778
                                               common::ObMySQLTransaction &trans,
1779
                                               share::schema::ObSchemaGetterGuard &schema_guard)
1780
{
1781
  int ret = OB_SUCCESS;
1782
  if (table_schema.is_user_table() || table_schema.is_oracle_tmp_table()) {
1783
    for (ObTableSchema::const_column_iterator iter = table_schema.column_begin();
1784
         OB_SUCC(ret) && iter != table_schema.column_end(); ++iter) {
1785
      ObColumnSchemaV2 &column_schema = (**iter);
1786
      if (OB_FAIL(drop_sequence_in_drop_column(column_schema, trans, schema_guard))) {
1787
        LOG_WARN("drop sequence in drop column fail", K(ret), K(column_schema));
1788
      }
1789
    }
1790
  }
1791
  return ret;
1792
}
1793

1794
int ObDDLOperator::create_sequence_in_add_column(const ObTableSchema &table_schema,
1795
    ObColumnSchemaV2 &column_schema,
1796
    ObMySQLTransaction &trans,
1797
    ObSchemaGetterGuard &schema_guard,
1798
    ObSequenceDDLArg &sequence_ddl_arg)
1799
{
1800
  int ret = OB_SUCCESS;
1801
  if (column_schema.is_identity_column()) {
1802
    ObSequenceDDLProxy ddl_operator(schema_service_);
1803
    ObSequenceSchema sequence_schema = sequence_ddl_arg.sequence_schema();
1804
    char temp_sequence_name[OB_MAX_SEQUENCE_NAME_LENGTH + 1] = { 0 };
1805
    int32_t len = snprintf(temp_sequence_name, sizeof(temp_sequence_name), "%s%lu%c%lu",
1806
                          "ISEQ$$_",
1807
                          ObSchemaUtils::get_extract_schema_id(column_schema.get_tenant_id(), column_schema.get_table_id()),
1808
                          '_',
1809
                          column_schema.get_column_id());
1810
    if (OB_UNLIKELY(len < 0)) {
1811
      ret = OB_ERR_UNEXPECTED;
1812
      LOG_WARN("create sequence name fail", K(ret), K(column_schema));
1813
    } else {
1814
      ObString sequence_name = ObString::make_string(temp_sequence_name);
1815
      sequence_schema.set_database_id(table_schema.get_database_id());
1816
      sequence_schema.set_sequence_name(sequence_name);
1817
      if (OB_FAIL(ddl_operator.create_sequence(sequence_schema,
1818
                                              sequence_ddl_arg.option_bitset_,
1819
                                              trans,
1820
                                              schema_guard,
1821
                                              NULL))) {
1822
        LOG_WARN("create sequence fail", K(ret));
1823
      } else {
1824
        column_schema.set_sequence_id(sequence_schema.get_sequence_id());
1825
        char sequence_string[OB_MAX_SEQUENCE_NAME_LENGTH + 1] = { 0 };
1826
        uint64_t pure_sequence_id = ObSchemaUtils::get_extract_schema_id(column_schema.get_tenant_id(), column_schema.get_sequence_id());
1827
        len = snprintf(sequence_string, sizeof(sequence_string), "%lu", pure_sequence_id);
1828
        if (OB_UNLIKELY(len < 0)) {
1829
          ret = OB_ERR_UNEXPECTED;
1830
          LOG_WARN("create sequence name fail", K(ret), K(column_schema));
1831
        } else {
1832
          ObObjParam cur_default_value;  // for desc table
1833
          ObObjParam orig_default_value; // for store pure_sequence_id
1834
          cur_default_value.set_varchar("SEQUENCE.NEXTVAL");
1835
          cur_default_value.set_collation_type(ObCharset::get_system_collation());
1836
          cur_default_value.set_collation_level(CS_LEVEL_IMPLICIT);
1837
          cur_default_value.set_param_meta();
1838
          orig_default_value.set_varchar(sequence_string);
1839
          orig_default_value.set_collation_type(ObCharset::get_system_collation());
1840
          orig_default_value.set_collation_level(CS_LEVEL_IMPLICIT);
1841
          orig_default_value.set_param_meta();
1842
          if (OB_FAIL(column_schema.set_cur_default_value(cur_default_value))) {
1843
            LOG_WARN("set current default value fail", K(ret));
1844
          } else if (OB_FAIL(column_schema.set_orig_default_value(orig_default_value))) {
1845
            LOG_WARN("set origin default value fail", K(ret), K(column_schema));
1846
          }
1847
        }
1848
      }
1849
    }
1850
  }
1851
  return ret;
1852
}
1853

1854
int ObDDLOperator::drop_sequence_in_drop_column(const ObColumnSchemaV2 &column_schema,
1855
    common::ObMySQLTransaction &trans,
1856
    share::schema::ObSchemaGetterGuard &schema_guard)
1857
{
1858
  int ret = OB_SUCCESS;
1859
  if (column_schema.is_identity_column()) {
1860
    ObSequenceDDLProxy ddl_operator(schema_service_);
1861
    const ObSequenceSchema *temp_sequence_schema = NULL;
1862
    ObSequenceSchema sequence_schema;
1863
    if (OB_FAIL(schema_guard.get_sequence_schema(column_schema.get_tenant_id(),
1864
                                                 column_schema.get_sequence_id(),
1865
                                                 temp_sequence_schema))) {
1866
      LOG_WARN("get sequence schema fail", K(ret), K(column_schema));
1867
      if (ret == OB_ERR_UNEXPECTED) {
1868
        // sequence has been deleted externally.
1869
        // Oracle does not allow sequences internally created to be deleted externally.
1870
        // In the future, it will be solved by adding columns to the internal table,
1871
        // and then the error code conversion can be removed.
1872
        ret = OB_SUCCESS;
1873
      }
1874
    } else if (OB_ISNULL(temp_sequence_schema)) {
1875
      ret = OB_ERR_UNEXPECTED;
1876
      LOG_WARN("sequence not exist", KR(ret), K(column_schema));
1877
    } else if (OB_FAIL(sequence_schema.assign(*temp_sequence_schema))) {
1878
      LOG_WARN("fail to assign sequence schema", KR(ret));
1879
    } else if (OB_FAIL(ddl_operator.drop_sequence(sequence_schema,
1880
                                           trans,
1881
                                           schema_guard,
1882
                                           NULL,
1883
                                           FROM_TABLE_DDL))) {
1884
      LOG_WARN("drop sequence fail", K(ret), K(column_schema));
1885
    }
1886
  }
1887
  return ret;
1888
}
1889

1890
int ObDDLOperator::reinit_autoinc_row(const ObTableSchema &table_schema,
1891
                                      common::ObMySQLTransaction &trans)
1892
{
1893
  int ret = OB_SUCCESS;
1894
  int64_t start_time = ObTimeUtility::current_time();
1895
  uint64_t table_id = table_schema.get_table_id();
1896
  ObString table_name = table_schema.get_table_name();
1897
  int64_t truncate_version = table_schema.get_truncate_version();
1898
  uint64_t column_id = table_schema.get_autoinc_column_id();
1899
  ObAutoincrementService &autoinc_service = share::ObAutoincrementService::get_instance();
1900

1901
  if (0 != column_id) {
1902
    bool is_oracle_mode = false;
1903
    if (OB_FAIL(table_schema.check_if_oracle_compat_mode(is_oracle_mode))) {
1904
      LOG_WARN("fail to check is oracle mode",
1905
                KR(ret), K(table_id), K(table_name), K(truncate_version), K(column_id));
1906
    } else if (is_oracle_mode) {
1907
      ret = OB_ERR_UNEXPECTED;
1908
      LOG_WARN("in oracle mode, autoic_column_id must be illegal",
1909
              KR(ret), K(table_id), K(table_name), K(truncate_version), K(column_id));
1910
    } else {
1911
      // reinit auto_increment value
1912
      uint64_t tenant_id = table_schema.get_tenant_id();
1913
      if (OB_FAIL(autoinc_service.reinit_autoinc_row(tenant_id, table_id,
1914
                                                     column_id, truncate_version, trans))) {
1915
        LOG_WARN("failed to reint auto_increment",
1916
                KR(ret), K(tenant_id), K(table_id), K(table_name), K(truncate_version), K(column_id));
1917
      }
1918
    }
1919
  }
1920
  int64_t finish_time = ObTimeUtility::current_time();
1921
  LOG_INFO("finish reinit_auto_row", KR(ret), "cost_ts", finish_time - start_time);
1922
  return ret;
1923
}
1924

1925
int ObDDLOperator::try_reinit_autoinc_row(const ObTableSchema &table_schema,
1926
                                          common::ObMySQLTransaction &trans)
1927
{
1928
  int ret = OB_SUCCESS;
1929
  bool need_reinit_inner_table = false;
1930
  const uint64_t table_id = table_schema.get_table_id();
1931
  const uint64_t tenant_id = table_schema.get_tenant_id();
1932
  const int64_t truncate_version = table_schema.get_truncate_version();
1933
  const uint64_t column_id = table_schema.get_autoinc_column_id();
1934
  ObAutoincrementService &autoinc_service = share::ObAutoincrementService::get_instance();
1935
  if (OB_FAIL(autoinc_service.try_lock_autoinc_row(tenant_id, table_id, column_id, truncate_version,
1936
                                                    need_reinit_inner_table, trans))) {
1937
    LOG_WARN("fail to check inner autoinc version", KR(ret), K(tenant_id), K(table_id), K(column_id));
1938
  } else if (need_reinit_inner_table) {
1939
    if (OB_FAIL(autoinc_service.reset_autoinc_row(tenant_id, table_id, column_id,
1940
                                                  truncate_version, trans))) {
1941
      LOG_WARN("fail to reinit autoinc row", KR(ret), K(tenant_id), K(table_id), K(column_id));
1942
    }
1943
  }
1944
  return ret;
1945
}
1946

1947
// Notice: this function process index.
1948
int ObDDLOperator::alter_table_drop_aux_column(
1949
    ObTableSchema &new_table_schema,
1950
    const ObColumnSchemaV2 &orig_column_schema,
1951
    common::ObMySQLTransaction &trans,
1952
    const ObTableType table_type)
1953
{
1954
  int ret = OB_SUCCESS;
1955
  //should update the aux table
1956
  const uint64_t tenant_id = orig_column_schema.get_tenant_id();
1957
  int64_t new_schema_version = OB_INVALID_VERSION;
1958
  const bool is_index = USER_INDEX == table_type;
1959
  ObSEArray<uint64_t, 16> aux_vp_tid_array; // for VP
1960
  ObSEArray<ObAuxTableMetaInfo, 16> simple_index_infos;
1961
  ObSchemaGetterGuard schema_guard;
1962
  ObSchemaService *schema_service = schema_service_.get_schema_service();
1963
  if (OB_ISNULL(schema_service)) {
1964
    ret = OB_ERR_SYS;
1965
    RS_LOG(ERROR, "schema_service must not null");
1966
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
1967
    RS_LOG(WARN, "get schema guard failed", K(ret));
1968
  } else if (!is_index
1969
             && OB_FAIL(new_table_schema.get_aux_vp_tid_array(aux_vp_tid_array))) {
1970
    LOG_WARN("get_aux_tid_array failed", K(ret), K(is_index));
1971
  } else if (OB_FAIL(new_table_schema.get_simple_index_infos(
1972
                     simple_index_infos))) {
1973
    LOG_WARN("get simple_index_infos failed", K(ret));
1974
  }
1975

1976
  //update all aux table schema
1977
  int64_t N = is_index ? simple_index_infos.count() : aux_vp_tid_array.count();
1978
  for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) {
1979
    const ObTableSchema *aux_table_schema = NULL;
1980
    uint64_t tid = is_index ? simple_index_infos.at(i).table_id_ : aux_vp_tid_array.at(i);
1981
    if (OB_FAIL(schema_guard.get_table_schema(
1982
                tenant_id, tid, aux_table_schema))) {
1983
      LOG_WARN("get table schema failed", K(ret), K(tenant_id), K(tid));
1984
    } else if (OB_ISNULL(aux_table_schema)) {
1985
      ret = OB_ERR_UNEXPECTED;
1986
      LOG_WARN("table schema should not be null", K(ret));
1987
    } else if (aux_table_schema->is_in_recyclebin()) {
1988
      ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
1989
      LOG_WARN("aux table is in recyclebin", K(ret));
1990
    } else {
1991
      const ObColumnSchemaV2 *delete_column_schema =
1992
          aux_table_schema->get_column_schema(orig_column_schema.get_column_id());
1993
      if (NULL != delete_column_schema) {
1994
        if (delete_column_schema->is_index_column()) {
1995
          ret = OB_ERR_ALTER_INDEX_COLUMN;
1996
          RS_LOG(WARN, "can't not drop index column", K(ret));
1997
        } else {
1998
          // Notice: when the last VP column is deleted, the VP table should be deleted.
1999
          // If other VP column is hidden, the VP partition should be deleted.
2000
          int64_t normal_column_count = 0;
2001
          for (int64_t i = 0; OB_SUCC(ret) && (normal_column_count < 2) && (i < aux_table_schema->get_column_count()); ++i) {
2002
            if (!aux_table_schema->get_column_schema_by_idx(i)->is_hidden()) {
2003
              ++normal_column_count;
2004
            }
2005
          }
2006
          if (OB_FAIL(ret)) {
2007
          } else if (normal_column_count < 1) {
2008
            ret = OB_ERR_UNEXPECTED;
2009
            LOG_WARN("normal_column_count is error", K(ret), K(normal_column_count));
2010
          } else if (1 == normal_column_count) {
2011
            // DROP AUX_VERTIAL_PARTITION_TABLE
2012
            ObSEArray<uint64_t, 16> tmp_aux_vp_tid_array;
2013
            if (OB_FAIL(drop_table(*aux_table_schema, trans))) {
2014
              LOG_WARN("drop aux vertial partition table failed", K(ret), K(*aux_table_schema));
2015
            } else {
2016
              for (int64_t i = 0; OB_SUCC(ret) && (i < aux_vp_tid_array.count()); ++i) {
2017
                if (aux_vp_tid_array.at(i) == aux_table_schema->get_table_id()) {
2018
                  // skip
2019
                } else if (OB_FAIL(tmp_aux_vp_tid_array.push_back(aux_vp_tid_array.at(i)))) {
2020
                  LOG_WARN("push back to tmp_aux_vp_tid_array failed", K(ret), K(i), K(aux_vp_tid_array.at(i)));
2021
                }
2022
              }
2023
              if (OB_SUCC(ret)) {
2024
                // update aux_vp_tid_array of new_table_schema
2025
                if (OB_FAIL(new_table_schema.set_aux_vp_tid_array(tmp_aux_vp_tid_array))) {
2026
                  LOG_WARN("set aux_vp_tid_array to new_table_schema failed", K(ret), K(tmp_aux_vp_tid_array));
2027
                }
2028
              }
2029
            }
2030
          } else {
2031
            ObTableSchema tmp_aux_table_schema;
2032
            if (OB_FAIL(tmp_aux_table_schema.assign(*aux_table_schema))) {
2033
              LOG_WARN("fail to assign schema", K(ret));
2034
            } else if (OB_FAIL(update_prev_id_for_delete_column(
2035
                *aux_table_schema,
2036
                tmp_aux_table_schema,
2037
                *delete_column_schema,
2038
                trans))) {
2039
              LOG_WARN("failed to update column previous id for delete column", K(ret));
2040
            } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2041
              LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2042
            } else if (OB_FAIL(schema_service->get_table_sql_service().delete_single_column(
2043
                new_schema_version,
2044
                trans,
2045
                *aux_table_schema,
2046
                *delete_column_schema))) {
2047
              RS_LOG(WARN, "failed to delete non-aux column!",
2048
                  "table schema", *aux_table_schema, K(ret));
2049
            } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2050
              LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2051
            } else if (OB_FAIL(schema_service->get_table_sql_service().sync_aux_schema_version_for_history(
2052
                trans,
2053
                *aux_table_schema,
2054
                new_schema_version
2055
                ))) {
2056
              RS_LOG(WARN, "fail to update aux schema version for update column");
2057
            }
2058
          }
2059
        }
2060
      }
2061
    }
2062
  }
2063

2064
  return ret;
2065
}
2066

2067
int ObDDLOperator::update_prev_id_for_delete_column(const ObTableSchema &origin_table_schema,
2068
    ObTableSchema &new_table_schema,
2069
    const ObColumnSchemaV2 &ori_column_schema,
2070
    common::ObMySQLTransaction &trans)
2071
{
2072
  int ret = OB_SUCCESS;
2073
  const uint64_t tenant_id = origin_table_schema.get_tenant_id();
2074
  int64_t new_schema_version = OB_INVALID_VERSION;
2075
  // When a transaction currently add/drop column: origin_table_schema don't update prev&next column ID, so it need fetch from new table.
2076
  ObColumnSchemaV2 *new_origin_col = new_table_schema.get_column_schema(ori_column_schema.get_column_name());
2077
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2078
  if (OB_ISNULL(schema_service)) {
2079
    ret = OB_ERR_SYS;
2080
    RS_LOG(ERROR, "schema_service must not null");
2081
  } else if (OB_ISNULL(new_origin_col)) {
2082
    ret = OB_ERR_UNEXPECTED;
2083
    LOG_WARN("Failed to get column from new table schema", K(ret));
2084
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2085
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2086
  } else {
2087
    ObColumnSchemaV2 *next_col = new_table_schema.get_column_schema_by_prev_next_id(new_origin_col->get_next_column_id());
2088
    if (OB_ISNULL(next_col)) {
2089
      // do nothing since local_column is tail column
2090
    } else {
2091
      next_col->set_prev_column_id(new_origin_col->get_prev_column_id());
2092
      next_col->set_schema_version(new_schema_version);
2093
      if (OB_FAIL(schema_service->get_table_sql_service().update_single_column(
2094
          trans,
2095
          origin_table_schema,
2096
          new_table_schema,
2097
          *next_col,
2098
          true /* record_ddl_operation */))) {
2099
        LOG_WARN("Failed to update single column", K(ret), K(next_col->get_column_name_str()));
2100
      }
2101
    }
2102
  }
2103
  return ret;
2104
}
2105

2106
int ObDDLOperator::update_table_foreign_keys(share::schema::ObTableSchema &new_table_schema,
2107
                                             common::ObMySQLTransaction &trans,
2108
                                             bool in_offline_ddl_white_list)
2109
{
2110
  int ret = OB_SUCCESS;
2111
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2112
  int64_t new_schema_version = OB_INVALID_VERSION;
2113
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2114

2115
  if (OB_ISNULL(schema_service)) {
2116
    ret = OB_ERR_UNEXPECTED;
2117
    LOG_WARN("schema_service is NULL", K(ret));
2118
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2119
    LOG_WARN("generate new schema version failed", K(ret));
2120
  } else if (FALSE_IT(new_table_schema.set_schema_version(new_schema_version))) {
2121
  } else if (OB_FAIL(schema_service->get_table_sql_service().update_foreign_key_state(
2122
             trans, new_table_schema))) {
2123
    LOG_WARN("update foreign keys enable option into inner table failed", K(ret));
2124
  } else {
2125
    uint64_t id = OB_INVALID_ID;
2126
    const ObTableSchema *schema = NULL;
2127
    const ObIArray<uint64_t> &table_ids = new_table_schema.get_depend_table_ids();
2128
    for (int64_t i = 0; i < table_ids.count() && OB_SUCC(ret); i++) {
2129
      ObSchemaGetterGuard schema_guard;
2130
      id = table_ids.at(i);
2131
      ObTableSchema tmp_schema;
2132
      if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
2133
        RS_LOG(WARN, "get schema guard failed", K(ret), K(id));
2134
      } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, id, schema))) {
2135
        LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(id));
2136
      } else if (!schema) {
2137
        ret = OB_ERR_UNEXPECTED;
2138
        LOG_WARN("schema is NULL", K(ret));
2139
      } else if (OB_FAIL(tmp_schema.assign(*schema))) {
2140
        LOG_WARN("fail to assign schema", K(ret), KPC(schema));
2141
      } else if (FALSE_IT(tmp_schema.set_in_offline_ddl_white_list(in_offline_ddl_white_list))) {
2142
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2143
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2144
      } else if (OB_FAIL(schema_service->get_table_sql_service().sync_schema_version_for_history(
2145
                trans,
2146
                tmp_schema,
2147
                new_schema_version))) {
2148
        RS_LOG(WARN, "fail to sync schema version", K(ret));
2149
      } else {
2150
        ObSchemaOperationType operation_type = OB_DDL_ALTER_TABLE;
2151
        if (OB_FAIL(update_table_attribute(new_table_schema,
2152
                                          trans,
2153
                                          operation_type))) {
2154
          LOG_WARN("failed to update data table schema attribute", K(ret));
2155
        }
2156
      }
2157
    }
2158
  }
2159
  return ret;
2160
}
2161

2162
int ObDDLOperator::add_table_foreign_keys(const share::schema::ObTableSchema &orig_table_schema,
2163
                                          share::schema::ObTableSchema &inc_table_schema,
2164
                                          common::ObMySQLTransaction &trans)
2165
{
2166
  int ret = OB_SUCCESS;
2167
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2168
  int64_t new_schema_version = OB_INVALID_VERSION;
2169
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2170

2171
  if (OB_ISNULL(schema_service)) {
2172
    ret = OB_ERR_UNEXPECTED;
2173
    LOG_WARN("schema_service is NULL", K(ret));
2174
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2175
    LOG_WARN("generate new schema version failed", K(ret));
2176
  } else {
2177
    inc_table_schema.set_schema_version(new_schema_version);
2178
  }
2179
  if (OB_SUCC(ret)) {
2180
    if (OB_FAIL(schema_service->get_table_sql_service().add_foreign_key(trans, inc_table_schema, false))) {
2181
      LOG_WARN("insert foreign keys into inner tables failed", K(ret));
2182
    } else if (OB_FAIL(schema_service->get_table_sql_service().update_foreign_key_state(trans, inc_table_schema))) {
2183
      LOG_WARN("update foreign keys enable option into inner table failed", K(ret));
2184
    } else if (OB_FAIL(sync_version_for_cascade_table(tenant_id, inc_table_schema.get_depend_table_ids(), trans))) {
2185
      LOG_WARN("fail to sync cascade depend table", K(ret));
2186
    } else if (OB_FAIL(sync_version_for_cascade_mock_fk_parent_table(orig_table_schema.get_tenant_id(), inc_table_schema.get_depend_mock_fk_parent_table_ids(), trans))) {
2187
      LOG_WARN("fail to sync cascade depend_mock_fk_parent_table_ids table", K(ret));
2188
    }
2189
  }
2190

2191
  return ret;
2192
}
2193

2194
int ObDDLOperator::modify_check_constraints_state(
2195
    const ObTableSchema &orig_table_schema,
2196
    const ObTableSchema &inc_table_schema,
2197
    ObTableSchema &new_table_schema,
2198
    ObMySQLTransaction &trans)
2199
{
2200
  int ret = OB_SUCCESS;
2201
  UNUSED(orig_table_schema);
2202
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2203
  int64_t new_schema_version = OB_INVALID_VERSION;
2204
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2205
  ObTableSchema::const_constraint_iterator iter = inc_table_schema.constraint_begin();
2206

2207
  if (OB_ISNULL(schema_service)) {
2208
    ret = OB_ERR_UNEXPECTED;
2209
    LOG_WARN("schema_service is NULL", K(ret));
2210
  } else if (inc_table_schema.constraint_end() == iter) {
2211
    ret = OB_ERR_UNEXPECTED;
2212
    LOG_WARN("table doesn't have a check constraint", K(ret), K(inc_table_schema));
2213
  } else if (inc_table_schema.constraint_end() != iter + 1) {
2214
    ret = OB_ERR_UNEXPECTED;
2215
    LOG_WARN("update check constraint state couldn't be executed with other DDLs", K(ret), K(inc_table_schema));
2216
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2217
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2218
  } else {
2219
    (*iter)->set_schema_version(new_schema_version);
2220
    if (OB_FAIL(schema_service->get_table_sql_service().update_check_constraint_state(trans, new_table_schema, **iter))) {
2221
      LOG_WARN("insert single constraint failed", K(ret));
2222
    }
2223
  }
2224

2225
  return ret;
2226
}
2227

2228
int ObDDLOperator::add_table_constraints(const ObTableSchema &inc_table_schema,
2229
                                         ObTableSchema &new_table_schema,
2230
                                         ObMySQLTransaction &trans,
2231
                                         ObSArray<uint64_t> *cst_ids/*NULL*/)
2232
{
2233
  int ret = OB_SUCCESS;
2234
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2235
  int64_t new_schema_version = OB_INVALID_VERSION;
2236
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2237
  if (OB_ISNULL(schema_service)) {
2238
    ret = OB_ERR_UNEXPECTED;
2239
    LOG_WARN("schema_service is NULL", K(ret));
2240
  }
2241
  for (ObTableSchema::const_constraint_iterator iter = inc_table_schema.constraint_begin(); OB_SUCC(ret) &&
2242
    iter != inc_table_schema.constraint_end(); iter ++) {
2243
    uint64_t new_cst_id = OB_INVALID_ID;
2244
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2245
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2246
    } else if (OB_FAIL(schema_service->fetch_new_constraint_id(tenant_id, new_cst_id))) {
2247
      LOG_WARN("failed to fetch new constraint id", K(ret));
2248
    } else {
2249
      (*iter)->set_schema_version(new_schema_version);
2250
      (*iter)->set_tenant_id(new_table_schema.get_tenant_id());
2251
      (*iter)->set_table_id(new_table_schema.get_table_id());
2252
      (*iter)->set_constraint_id(new_cst_id);
2253
      (*iter)->set_constraint_type((*iter)->get_constraint_type());
2254
      if (OB_FAIL(schema_service->get_table_sql_service().insert_single_constraint(trans, new_table_schema, **iter))) {
2255
        LOG_WARN("insert single constraint failed", K(ret));
2256
      } else {
2257
        if (OB_NOT_NULL(cst_ids)) {
2258
          OZ(cst_ids->push_back(new_cst_id));
2259
        }
2260
      }
2261
    }
2262
  }
2263
  return ret;
2264
}
2265

2266
int ObDDLOperator::add_table_partitions(const ObTableSchema &orig_table_schema,
2267
                                        ObTableSchema &inc_table_schema,
2268
                                        ObTableSchema &new_table_schema,
2269
                                        ObMySQLTransaction &trans)
2270
{
2271
  int ret = OB_SUCCESS;
2272
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2273
  int64_t new_schema_version = OB_INVALID_VERSION;
2274
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2275
  if (OB_ISNULL(schema_service)) {
2276
    ret = OB_ERR_UNEXPECTED;
2277
    LOG_WARN("schema_service is NULL", K(ret));
2278
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2279
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2280
  } else if (OB_FAIL(schema_service->get_table_sql_service().add_inc_partition_info(trans,
2281
                                                                                    orig_table_schema,
2282
                                                                                    inc_table_schema,
2283
                                                                                    new_schema_version,
2284
                                                                                    false,
2285
                                                                                    false))) {
2286
    LOG_WARN("add inc part info failed", K(ret));
2287
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2288
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2289
  } else {
2290
    const int64_t part_num = orig_table_schema.get_part_option().get_part_num();
2291
    const int64_t inc_part_num = inc_table_schema.get_partition_num();
2292
    const int64_t all_part_num = part_num + inc_part_num;
2293
    new_table_schema.get_part_option().set_part_num(all_part_num);
2294
    new_table_schema.set_schema_version(new_schema_version);
2295
    if (OB_FAIL(schema_service->get_table_sql_service()
2296
                           .update_partition_option(trans, new_table_schema))) {
2297
      LOG_WARN("update partition option failed", K(ret), K(part_num), K(inc_part_num));
2298
    }
2299
  }
2300
  return ret;
2301
}
2302

2303
int ObDDLOperator::add_table_subpartitions(const ObTableSchema &orig_table_schema,
2304
                                           ObTableSchema &inc_table_schema,
2305
                                           ObTableSchema &new_table_schema,
2306
                                           ObMySQLTransaction &trans)
2307
{
2308
  int ret = OB_SUCCESS;
2309
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2310
  int64_t new_schema_version = OB_INVALID_VERSION;
2311
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2312
  ObArray<ObPartition*> update_part_array;
2313
  //FIXME:should move the related logic to ObDDLService
2314
  if (OB_ISNULL(schema_service)) {
2315
    ret = OB_ERR_UNEXPECTED;
2316
    LOG_WARN("schema_service is NULL", K(ret));
2317
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2318
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2319

2320
  } else if (OB_FAIL(get_part_array_from_table(new_table_schema, inc_table_schema, update_part_array))) {
2321
    LOG_WARN("fail to get_part_array_from_table", KR(ret));
2322
  } else if (update_part_array.count() <= 0) {
2323
    ret = OB_ERR_UNEXPECTED;
2324
    LOG_WARN("update part array count is not more than 0", KR(ret), K(update_part_array.count()));
2325
  } else if (update_part_array.count() != inc_table_schema.get_partition_num()) {
2326
    ret = OB_ERR_UNEXPECTED;
2327
    LOG_WARN("update_part_array count not equal inc_table part count",
2328
              KR(ret), K(update_part_array.count()), K(inc_table_schema.get_partition_num()));
2329
  } else {
2330
    for (int64_t i = 0; OB_SUCC(ret) && i < update_part_array.count(); i++) {
2331
      ObPartition *part = update_part_array.at(i);
2332
      if (OB_ISNULL(part)) {
2333
        ret = OB_ERR_UNEXPECTED;
2334
        LOG_WARN("update_part_array[i]", KR(ret), K(i));
2335
      } else if (i >= inc_table_schema.get_partition_num()) {
2336
        ret = OB_ERR_UNEXPECTED;
2337
        LOG_WARN("update_part_array[i] out of inc_part_array", KR(ret), K(i), K(inc_table_schema.get_partition_num()));
2338
      } else if (OB_ISNULL(inc_table_schema.get_part_array()[i])) {
2339
        ret = OB_ERR_UNEXPECTED;
2340
        LOG_WARN("inc_table_part_array[i]", KR(ret), K(i));
2341
      } else {
2342
        const int64_t subpart_num = part->get_subpartition_num();
2343
        const int64_t inc_subpart_num = inc_table_schema.get_part_array()[i]->get_subpartition_num();
2344
        part->set_sub_part_num(subpart_num + inc_subpart_num);
2345
        part->set_schema_version(new_schema_version);
2346
      }
2347
    }
2348
    if (OB_SUCC(ret)) {
2349
      if (OB_FAIL(schema_service->get_table_sql_service().add_inc_partition_info(trans,
2350
                                                          orig_table_schema,
2351
                                                          inc_table_schema,
2352
                                                          new_schema_version,
2353
                                                          false,
2354
                                                          true))) {
2355
        LOG_WARN("add inc part info failed", K(ret));
2356
      }
2357
      new_table_schema.set_schema_version(new_schema_version);
2358
      if (FAILEDx(schema_service->get_table_sql_service().update_subpartition_option(trans,
2359
          new_table_schema, update_part_array))) {
2360
        LOG_WARN("update sub partition option failed");
2361
      }
2362
    }
2363
  }
2364
  return ret;
2365
}
2366

2367
int ObDDLOperator::truncate_table(const ObString *ddl_stmt_str,
2368
                                  const share::schema::ObTableSchema &orig_table_schema,
2369
                                  const share::schema::ObTableSchema &new_table_schema,
2370
                                  common::ObMySQLTransaction &trans)
2371
{
2372
  int ret = OB_SUCCESS;
2373
  bool is_truncate_table = true;
2374
  bool is_truncate_partition = false;
2375
  uint64_t table_id = new_table_schema.get_table_id();
2376
  uint64_t schema_version = new_table_schema.get_schema_version();
2377
  ObSchemaOperationType operation_type = OB_DDL_TRUNCATE_TABLE;
2378
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2379
  if (OB_ISNULL(schema_service)) {
2380
    ret = OB_ERR_UNEXPECTED;
2381
    LOG_WARN("schema_service is NULL", KR(ret));
2382
  } else if (new_table_schema.is_partitioned_table()) {
2383
    if (OB_INVALID_VERSION == schema_version) {
2384
      ret  = OB_ERR_UNEXPECTED;
2385
      LOG_WARN("schema version is not legal", KR(ret), K(table_id), K(schema_version));
2386
    } else if (OB_FAIL(schema_service->get_table_sql_service()
2387
                                      .drop_inc_part_info(trans,
2388
                                                          orig_table_schema,
2389
                                                          orig_table_schema,
2390
                                                          schema_version,
2391
                                                          is_truncate_partition,
2392
                                                          is_truncate_table))) {
2393
      LOG_WARN("delete part info failed", KR(ret), K(table_id), K(schema_version));
2394
    } else if (OB_FAIL(schema_service->get_table_sql_service()
2395
                                      .add_inc_part_info(trans,
2396
                                                        orig_table_schema,
2397
                                                        new_table_schema,
2398
                                                        schema_version,
2399
                                                        is_truncate_table))) {
2400
      LOG_WARN("add part info failed", KR(ret), K(table_id), K(schema_version));
2401
    }
2402
  }
2403
  if (FAILEDx(schema_service->get_table_sql_service()
2404
                            .update_table_attribute(trans,
2405
                                                    new_table_schema,
2406
                                                    operation_type,
2407
                                                    false,
2408
                                                    ddl_stmt_str))) {
2409
    LOG_WARN("failed to update table schema attribute", KR(ret), K(table_id), K(schema_version));
2410
  }
2411
  return ret;
2412
}
2413

2414
int ObDDLOperator::update_boundary_schema_version(const uint64_t &tenant_id,
2415
                                                  const uint64_t &boundary_schema_version,
2416
                                                  common::ObMySQLTransaction &trans)
2417
{
2418
  int ret = OB_SUCCESS;
2419
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2420

2421
  if (OB_ISNULL(schema_service)) {
2422
    ret = OB_ERR_UNEXPECTED;
2423
    LOG_WARN("schema_service is NULL", KR(ret));
2424
  } else {
2425
    ObSchemaOperation schema_operation;
2426
    schema_operation.tenant_id_ = tenant_id;
2427
    schema_operation.op_type_ = OB_DDL_END_SIGN;
2428
    share::schema::ObDDLSqlService ddl_sql_service(*schema_service);
2429

2430
    if (OB_FAIL(ddl_sql_service.log_nop_operation(schema_operation,
2431
                                                  boundary_schema_version,
2432
                                                  NULL,
2433
                                                  trans))) {
2434
      LOG_WARN("log end ddl operation failed", KR(ret), K(tenant_id), K(boundary_schema_version));
2435
    }
2436
  }
2437
  return ret;
2438
}
2439

2440
int ObDDLOperator::truncate_table_partitions(const share::schema::ObTableSchema &orig_table_schema,
2441
                                             share::schema::ObTableSchema &inc_table_schema,
2442
                                             share::schema::ObTableSchema &del_table_schema,
2443
                                             common::ObMySQLTransaction &trans)
2444
{
2445
  int ret = OB_SUCCESS;
2446
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2447
  int64_t new_schema_version = OB_INVALID_VERSION;
2448
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2449
  if (OB_ISNULL(schema_service)) {
2450
    ret = OB_ERR_UNEXPECTED;
2451
    LOG_WARN("schema_service is NULL", KR(ret));
2452
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2453
    LOG_WARN("fail to gen new schema_version", KR(ret), K(tenant_id));
2454
  } else if (OB_FAIL(schema_service->get_table_sql_service().truncate_part_info(
2455
                     trans,
2456
                     orig_table_schema,
2457
                     inc_table_schema,
2458
                     del_table_schema,
2459
                     new_schema_version))) {
2460
    LOG_WARN("delete inc part info failed", KR(ret));
2461
  }
2462

2463
  return ret;
2464
}
2465

2466
int ObDDLOperator::truncate_table_subpartitions(const share::schema::ObTableSchema &orig_table_schema,
2467
                                                share::schema::ObTableSchema &inc_table_schema,
2468
                                                share::schema::ObTableSchema &del_table_schema,
2469
                                                common::ObMySQLTransaction &trans)
2470
{
2471
  int ret = OB_SUCCESS;
2472
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2473
  int64_t new_schema_version = OB_INVALID_VERSION;
2474
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2475
  if (OB_ISNULL(schema_service)) {
2476
    ret = OB_ERR_UNEXPECTED;
2477
    LOG_WARN("schema_service is NULL", KR(ret));
2478
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2479
    LOG_WARN("fail to gen new schema_version", KR(ret), K(tenant_id));
2480
  } else if (OB_FAIL(schema_service->get_table_sql_service().truncate_subpart_info(
2481
                     trans,
2482
                     orig_table_schema,
2483
                     inc_table_schema,
2484
                     del_table_schema,
2485
                     new_schema_version))) {
2486
    LOG_WARN("delete inc part info failed", KR(ret));
2487
  }
2488

2489
  return ret;
2490
}
2491

2492
int ObDDLOperator::add_table_partitions(const ObTableSchema &orig_table_schema,
2493
                                        ObTableSchema &alter_table_schema,
2494
                                        const int64_t schema_version,
2495
                                        ObMySQLTransaction &trans)
2496
{
2497
  int ret = OB_SUCCESS;
2498
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2499
  if (OB_ISNULL(schema_service)) {
2500
    ret = OB_ERR_UNEXPECTED;
2501
    LOG_WARN("schema_service is NULL", K(ret));
2502
  } else if (schema_version <= 0) {
2503
    ret = OB_INVALID_ARGUMENT;
2504
    LOG_WARN("schema_version is invalid", K(ret), K(schema_version));
2505
  } else {
2506
    const int64_t inc_part_num = alter_table_schema.get_part_option().get_part_num();
2507
    if (OB_FAIL(schema_service->get_table_sql_service().add_inc_partition_info(trans,
2508
                                                                               orig_table_schema,
2509
                                                                               alter_table_schema,
2510
                                                                               schema_version,
2511
                                                                               false,
2512
                                                                               false))) {
2513
      LOG_WARN("add inc part info failed", K(ret));
2514
    } else {
2515
      const int64_t part_num = orig_table_schema.get_part_option().get_part_num();
2516
      const int64_t all_part_num = part_num + inc_part_num;
2517
      ObTableSchema new_table_schema;
2518
      if (OB_FAIL(new_table_schema.assign(orig_table_schema))) {
2519
        LOG_WARN("fail to assign schema", K(ret));
2520
      } else {
2521
        new_table_schema.get_part_option().set_part_num(all_part_num);
2522
      }
2523
      if (OB_FAIL(ret)) {
2524
      } else if (OB_FAIL(schema_service->get_table_sql_service()
2525
                  .update_partition_option(trans, new_table_schema, schema_version))) {
2526
        LOG_WARN("update partition option failed", K(ret), K(part_num), K(inc_part_num));
2527
      }
2528
    }
2529
  }
2530
  return ret;
2531
}
2532

2533
int ObDDLOperator::get_part_array_from_table(const ObTableSchema &new_table_schema,
2534
                                             const ObTableSchema &inc_table_schema,
2535
                                             ObIArray<ObPartition*> &out_part_array)
2536
{
2537
  int ret = OB_SUCCESS;
2538

2539
  ObPartition **inc_part_array = inc_table_schema.get_part_array();
2540
  const int64_t inc_part_sum = inc_table_schema.get_partition_num();
2541
  for (int64_t i = 0; OB_SUCC(ret) && i < inc_part_sum; i++) {
2542
    ObPartition *inc_part = inc_part_array[i];
2543
    if (OB_ISNULL(inc_part)) {
2544
      ret = OB_ERR_UNEXPECTED;
2545
      LOG_WARN("inc_part_array[i] is null", KR(ret), K(i));
2546
    } else {
2547
      ObPartition **part_array = new_table_schema.get_part_array();
2548
      const int64_t part_sum = new_table_schema.get_partition_num();
2549
      int64_t j = 0;
2550
      for (j = 0; OB_SUCC(ret) && j < part_sum; j++) {
2551
        ObPartition *part = part_array[j];
2552
        if (OB_ISNULL(part)) {
2553
          ret = OB_ERR_UNEXPECTED;
2554
          LOG_WARN("part_array[j] is NULL", K(ret), K(j));
2555
        } else if (part->get_part_id() == inc_part->get_part_id()) {
2556
          if (OB_FAIL(out_part_array.push_back(part))) {
2557
            LOG_WARN("push back failed", KR(ret), K(j));
2558
          }
2559
          break;
2560
        }
2561
      }
2562
      if (OB_SUCC(ret) && j >= part_sum) {
2563
        ret = OB_ERR_UNEXPECTED;
2564
        LOG_WARN("inc_part_array[i] is not in part_array",
2565
                 KR(ret), K(i), KPC(inc_part), K(new_table_schema));
2566
      }
2567
    }
2568
  }
2569
  return ret;
2570
}
2571

2572
bool ObDDLOperator::is_list_values_equal(const common::ObRowkey &fir_values,
2573
                                         const common::ObIArray<common::ObNewRow> &sed_values)
2574
{
2575
  bool equal = false;
2576
  int64_t s_count = sed_values.count();
2577
  common::ObRowkey rowkey;
2578
  for (int64_t j = 0; j < s_count; ++j) {
2579
    rowkey.reset();
2580
    rowkey.assign(sed_values.at(j).cells_, sed_values.at(j).count_);
2581
    if (fir_values == rowkey) {
2582
      equal = true;
2583
      break;
2584
    }
2585
  }
2586
  return equal;
2587
}
2588

2589
int ObDDLOperator::check_part_equal(
2590
    const share::schema::ObPartitionFuncType part_type,
2591
    const share::schema::ObPartition *r_part,
2592
    const share::schema::ObPartition *l_part,
2593
    bool &is_equal)
2594
{
2595
  int ret = OB_SUCCESS;
2596
  is_equal = false;
2597

2598
  if (OB_ISNULL(r_part) || OB_ISNULL(l_part)) {
2599
    ret = OB_ERR_UNEXPECTED;
2600
    LOG_WARN("ptr is NULL", K(ret), K(r_part), K(l_part));
2601
  } else if (share::schema::is_range_part(part_type)) {
2602
    if (r_part->get_high_bound_val() == l_part->get_high_bound_val()) {
2603
      is_equal = true;
2604
    }
2605
  } else if (share::schema::is_list_part(part_type)) {
2606
    if (0 == r_part->get_list_row_values().count()) {
2607
      ret = OB_ERR_UNEXPECTED;
2608
      LOG_WARN("list values is empty", K(ret));
2609
    } else {
2610
      common::ObRowkey rowkey;
2611
      rowkey.assign(r_part->get_list_row_values().at(0).cells_,
2612
                    r_part->get_list_row_values().at(0).count_);
2613
      if (is_list_values_equal(rowkey, l_part->get_list_row_values())) {
2614
        is_equal = true;
2615
      }
2616
    }
2617
  }
2618

2619
  return ret;
2620
}
2621

2622
int ObDDLOperator::rename_table_partitions(const ObTableSchema &orig_table_schema,
2623
                                         ObTableSchema &inc_table_schema,
2624
                                         ObTableSchema &new_table_schema,
2625
                                         ObMySQLTransaction &trans)
2626
{
2627
  int ret = OB_SUCCESS;
2628
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2629
  int64_t new_schema_version = OB_INVALID_VERSION;
2630
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2631
  if (OB_ISNULL(schema_service)) {
2632
    ret = OB_ERR_UNEXPECTED;
2633
    LOG_WARN("schema_service is NULL", KR(ret));
2634
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2635
    LOG_WARN("fail to gen new schema version", KR(ret), K(tenant_id));
2636
  } else if (OB_FAIL(schema_service->get_table_sql_service().rename_inc_part_info(trans,
2637
                                                                          orig_table_schema,
2638
                                                                          inc_table_schema,
2639
                                                                          new_schema_version))) {
2640
    LOG_WARN("rename inc part info failed", KR(ret));
2641
  }
2642
  return ret;
2643
}
2644

2645
int ObDDLOperator::rename_table_subpartitions(const ObTableSchema &orig_table_schema,
2646
                                         ObTableSchema &inc_table_schema,
2647
                                         ObTableSchema &new_table_schema,
2648
                                         ObMySQLTransaction &trans)
2649
{
2650
  int ret = OB_SUCCESS;
2651
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2652
  int64_t new_schema_version = OB_INVALID_VERSION;
2653
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2654
  if (OB_ISNULL(schema_service)) {
2655
    ret = OB_ERR_UNEXPECTED;
2656
    LOG_WARN("schema_service is NULL", KR(ret));
2657
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2658
    LOG_WARN("fail to gen new schema version", KR(ret), K(tenant_id));
2659
  } else if (OB_FAIL(schema_service->get_table_sql_service().rename_inc_subpart_info(trans,
2660
                                                                          orig_table_schema,
2661
                                                                          inc_table_schema,
2662
                                                                          new_schema_version))) {
2663
    LOG_WARN("rename inc subpart info failed", KR(ret));
2664
  }
2665
  return ret;
2666
}
2667

2668
int ObDDLOperator::drop_table_partitions(const ObTableSchema &orig_table_schema,
2669
                                         ObTableSchema &inc_table_schema,
2670
                                         ObTableSchema &new_table_schema,
2671
                                         ObMySQLTransaction &trans)
2672
{
2673
  int ret = OB_SUCCESS;
2674
  bool is_truncate_table = false;
2675
  bool is_truncate_partition = false;
2676
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2677
  int64_t new_schema_version = OB_INVALID_VERSION;
2678
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2679
  if (OB_ISNULL(schema_service)) {
2680
    ret = OB_ERR_UNEXPECTED;
2681
    LOG_WARN("schema_service is NULL", K(ret));
2682
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2683
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2684
  }
2685
  if (OB_FAIL(ret)) {
2686
  } else if (OB_FAIL(schema_service->get_table_sql_service().drop_inc_part_info(trans,
2687
                                                                         orig_table_schema,
2688
                                                                         inc_table_schema,
2689
                                                                         new_schema_version,
2690
                                                                         is_truncate_partition,
2691
                                                                         is_truncate_table))) {
2692
    LOG_WARN("delete inc part info failed", K(ret));
2693
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2694
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2695
  } else {
2696
    const int64_t part_num = orig_table_schema.get_part_option().get_part_num();
2697
    const int64_t inc_part_num = inc_table_schema.get_partition_num();
2698
    const int64_t all_part_num = part_num - inc_part_num;
2699
    new_table_schema.get_part_option().set_part_num(all_part_num);
2700
    new_table_schema.set_schema_version(new_schema_version);
2701
    if (OB_FAIL(schema_service->get_table_sql_service()
2702
                            .update_partition_option(trans, new_table_schema))) {
2703
      LOG_WARN("update partition option failed", K(ret), K(part_num), K(inc_part_num));
2704
    }
2705
  }
2706
  return ret;
2707
}
2708

2709
int ObDDLOperator::drop_table_subpartitions(const ObTableSchema &orig_table_schema,
2710
                                            ObTableSchema &inc_table_schema,
2711
                                            ObTableSchema &new_table_schema,
2712
                                            ObMySQLTransaction &trans)
2713
{
2714
  int ret = OB_SUCCESS;
2715
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2716
  int64_t new_schema_version = OB_INVALID_VERSION;
2717
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2718
  if (OB_ISNULL(schema_service)) {
2719
    ret = OB_ERR_UNEXPECTED;
2720
    LOG_WARN("schema_service is NULL", K(ret));
2721
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2722
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2723
  } else if (OB_FAIL(schema_service->get_table_sql_service().drop_inc_subpart_info(trans,
2724
                                                                         orig_table_schema,
2725
                                                                         inc_table_schema,
2726
                                                                         new_schema_version))) {
2727
    LOG_WARN("delete inc part info failed", K(ret));
2728
  } else {
2729
    //FIXME:should move the related logic to ObDDLService
2730
    ObArray<ObPartition*> update_part_array;
2731
    if (OB_FAIL(get_part_array_from_table(new_table_schema, inc_table_schema, update_part_array))) {
2732
      LOG_WARN("fail to get part array from tableschema", KR(ret));
2733
    } else if (update_part_array.count() <= 0) {
2734
      ret = OB_ERR_UNEXPECTED;
2735
      LOG_WARN("update_part_array count less than 0", K(ret), K(update_part_array.count()));
2736
    } else if (update_part_array.count() != inc_table_schema.get_partition_num()) {
2737
      ret = OB_ERR_UNEXPECTED;
2738
      LOG_WARN("update_part_array count not equal inc_table part count",
2739
                KR(ret), K(update_part_array.count()), K(inc_table_schema.get_partition_num()));
2740
    } else {
2741
      for (int64_t i = 0; OB_SUCC(ret) && i < update_part_array.count(); i++) {
2742
        ObPartition *part = update_part_array.at(i);
2743
        if (i >= inc_table_schema.get_partition_num()) {
2744
          ret = OB_ERR_UNEXPECTED;
2745
          LOG_WARN("update_part_array[i] out of inc_part_array", KR(ret), K(i), K(inc_table_schema.get_partition_num()));
2746
        } else if (OB_ISNULL(part)) {
2747
          ret = OB_ERR_UNEXPECTED;
2748
          LOG_WARN("update_part_array[i]", KR(ret), K(i));
2749
        } else if (OB_ISNULL(inc_table_schema.get_part_array()[i])) {
2750
          ret = OB_ERR_UNEXPECTED;
2751
          LOG_WARN("inc_table_part_array[i]", KR(ret), K(i));
2752
        } else {
2753
          const int64_t subpart_num = part->get_sub_part_num();
2754
          const int64_t inc_subpart_num = inc_table_schema.get_part_array()[i]->get_subpartition_num();
2755
          part->set_sub_part_num(subpart_num - inc_subpart_num);
2756
          part->set_schema_version(new_schema_version);
2757
        }
2758
      }
2759
      if (OB_SUCC(ret)) {
2760
        new_table_schema.set_schema_version(new_schema_version);
2761
        if (OB_FAIL(schema_service->get_table_sql_service().update_subpartition_option(trans,
2762
            new_table_schema, update_part_array))) {
2763
          LOG_WARN("update sub partition option failed");
2764
        }
2765
      }
2766
    }
2767
  }
2768
  return ret;
2769
}
2770

2771
int ObDDLOperator::drop_table_constraints(const ObTableSchema &orig_table_schema,
2772
                                          const ObTableSchema &inc_table_schema,
2773
                                          ObTableSchema &new_table_schema,
2774
                                          ObMySQLTransaction &trans)
2775
{
2776
  int ret = OB_SUCCESS;
2777
  const uint64_t tenant_id = orig_table_schema.get_tenant_id();
2778
  int64_t new_schema_version = OB_INVALID_VERSION;
2779
  UNUSED(orig_table_schema);
2780

2781
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2782
  if (OB_ISNULL(schema_service)) {
2783
    ret = OB_ERR_UNEXPECTED;
2784
    LOG_WARN("schema_service is NULL", K(ret));
2785
  } else {
2786
    for (ObTableSchema::const_constraint_iterator iter = inc_table_schema.constraint_begin(); OB_SUCC(ret) &&
2787
      iter != inc_table_schema.constraint_end(); iter ++) {
2788
      (*iter)->set_tenant_id(orig_table_schema.get_tenant_id());
2789
      (*iter)->set_table_id(orig_table_schema.get_table_id());
2790
      if (nullptr == new_table_schema.get_constraint((*iter)->get_constraint_id())) {
2791
        LOG_INFO("constraint has already been dropped", K(ret), K(**iter));
2792
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2793
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2794
      } else if (OB_FAIL(schema_service->get_table_sql_service().delete_single_constraint(
2795
                           new_schema_version, trans, new_table_schema, **iter))) {
2796
        RS_LOG(WARN, "failed to delete constraint", K(ret));
2797
      }
2798
    }
2799
  }
2800
  return ret;
2801
}
2802

2803
int ObDDLOperator::drop_table_partitions(const ObTableSchema &orig_table_schema,
2804
                                         ObTableSchema &inc_table_schema,
2805
                                         const int64_t schema_version,
2806
                                         ObMySQLTransaction &trans)
2807
{
2808
  int ret = OB_SUCCESS;
2809
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2810
  bool is_truncate_table = false;
2811
  bool is_truncate_partition = false;
2812
  if (OB_ISNULL(schema_service)) {
2813
    ret = OB_ERR_UNEXPECTED;
2814
    LOG_WARN("schema_service is NULL", K(ret));
2815
  } else if (schema_version <= 0) {
2816
    ret = OB_INVALID_ARGUMENT;
2817
    LOG_WARN("schema_version is invalid", K(ret), K(schema_version));
2818
  } else if (OB_FAIL(schema_service->get_table_sql_service().drop_inc_part_info(
2819
                     trans,
2820
                     orig_table_schema,
2821
                     inc_table_schema,
2822
                     schema_version,
2823
                     is_truncate_partition,
2824
                     is_truncate_table))) {
2825
    LOG_WARN("delete inc part info failed", K(ret));
2826
  } else {
2827
    ObTableSchema new_table_schema;
2828
    if (OB_FAIL(new_table_schema.assign(orig_table_schema))) {
2829
      LOG_WARN("fail to assign schema", K(ret));
2830
    } else {
2831
      const int64_t part_num = orig_table_schema.get_part_option().get_part_num();
2832
      const int64_t inc_part_num = inc_table_schema.get_part_option().get_part_num();
2833
      const int64_t all_part_num = part_num - inc_part_num;
2834
      new_table_schema.get_part_option().set_part_num(all_part_num);
2835
      if (OB_FAIL(schema_service->get_table_sql_service()
2836
                              .update_partition_option(trans, new_table_schema, schema_version))) {
2837
        LOG_WARN("update partition option failed", K(ret), K(part_num), K(inc_part_num));
2838
      }
2839
    }
2840
  }
2841
  return ret;
2842
}
2843

2844
int ObDDLOperator::insert_column_groups(ObMySQLTransaction &trans, const ObTableSchema &new_table_schema)
2845
{
2846
  int ret = OB_SUCCESS;
2847
  int64_t new_schema_version = OB_INVALID_VERSION;
2848
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2849
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2850
  if (OB_ISNULL(schema_service)) {
2851
    ret = OB_ERR_UNEXPECTED;
2852
    LOG_WARN("schema_service is NULL", K(ret));
2853
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2854
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2855
  } else if (OB_FAIL(schema_service->get_table_sql_service().add_column_groups(trans, new_table_schema, new_schema_version))) {
2856
    LOG_WARN("insert alter column group failed", K(ret), K(new_table_schema));
2857
  }
2858
  return ret;
2859
}
2860

2861
int ObDDLOperator::insert_column_ids_into_column_group(ObMySQLTransaction &trans,
2862
                                                      const ObTableSchema &new_table_schema,
2863
                                                      const ObIArray<uint64_t> &column_ids,
2864
                                                      const ObColumnGroupSchema &column_group)
2865
{
2866
  int ret = OB_SUCCESS;
2867
  int64_t new_schema_version = OB_INVALID_VERSION;
2868
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2869
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2870
  if (OB_ISNULL(schema_service)) {
2871
    ret = OB_ERR_UNEXPECTED;
2872
    LOG_WARN("schema_service is NULL", K(ret));
2873
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2874
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2875
  } else if (OB_FAIL(schema_service->get_table_sql_service().insert_column_ids_into_column_group(trans, new_table_schema, new_schema_version, column_ids, column_group))) {
2876
    LOG_WARN("insert alter column group failed", K(ret), K(new_table_schema), K(column_group));
2877
  }
2878
  return ret;
2879
}
2880

2881

2882
int ObDDLOperator::insert_single_column(ObMySQLTransaction &trans,
2883
                                        const ObTableSchema &new_table_schema,
2884
                                        ObColumnSchemaV2 &new_column)
2885
{
2886
  int ret = OB_SUCCESS;
2887
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2888
  int64_t new_schema_version = OB_INVALID_VERSION;
2889
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2890
  if (OB_ISNULL(schema_service)) {
2891
    ret = OB_ERR_UNEXPECTED;
2892
    LOG_WARN("schema_service is NULL", K(ret));
2893
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2894
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2895
  } else if (FALSE_IT(new_column.set_schema_version(new_schema_version))) {
2896
    //do nothing
2897
  } else if (OB_FAIL(schema_service->get_table_sql_service().insert_single_column(
2898
             trans, new_table_schema, new_column, true))) {
2899
    LOG_WARN("insert single column failed", K(ret));
2900
  }
2901
  return ret;
2902
}
2903

2904
int ObDDLOperator::delete_single_column(ObMySQLTransaction &trans,
2905
                                        ObTableSchema &new_table_schema,
2906
                                        const ObString &column_name)
2907
{
2908
  int ret = OB_SUCCESS;
2909
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2910
  int64_t new_schema_version = OB_INVALID_VERSION;
2911
  ObColumnSchemaV2 *orig_column = NULL;
2912
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2913
  if (OB_ISNULL(schema_service)) {
2914
    ret = OB_ERR_UNEXPECTED;
2915
    LOG_WARN("schema_service is NULL", K(ret));
2916
  } else if (OB_ISNULL(orig_column = new_table_schema.get_column_schema(column_name))) {
2917
    ret = OB_ERR_UNEXPECTED;
2918
    LOG_WARN("get column schema from table failed", K(column_name));
2919
  } else if (OB_FAIL(new_table_schema.delete_column(column_name))) {
2920
    //drop column will do some check on the new table schema
2921
    RS_LOG(WARN, "failed to drop column schema", K(ret), K(column_name));
2922
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2923
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2924
  } else if (OB_FAIL(schema_service->get_table_sql_service().delete_single_column(
2925
      new_schema_version, trans, new_table_schema, *orig_column))) {
2926
    RS_LOG(WARN, "failed to delete column", K(orig_column), K(ret));
2927
  }
2928
  return ret;
2929
}
2930

2931
int ObDDLOperator::alter_table_create_index(const ObTableSchema &new_table_schema,
2932
                                            ObIArray<ObColumnSchemaV2*> &gen_columns,
2933
                                            ObTableSchema &index_schema,
2934
                                            common::ObMySQLTransaction &trans)
2935
{
2936
  int ret = OB_SUCCESS;
2937
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
2938
  int64_t new_schema_version = OB_INVALID_VERSION;
2939
  ObSchemaService *schema_service = schema_service_.get_schema_service();
2940
  if (OB_ISNULL(schema_service)) {
2941
    ret = OB_ERR_UNEXPECTED;
2942
    LOG_WARN("schema_service is NULL", K(ret));
2943
  } else {
2944
    uint64_t index_table_id = OB_INVALID_ID;
2945
    //index schema can't not create with specified table id
2946
    if (OB_UNLIKELY(index_schema.get_table_id() != OB_INVALID_ID)) {
2947
      ret = OB_ERR_UNEXPECTED;
2948
      LOG_WARN("table_id of index should be invalid", K(ret), K(index_schema.get_table_id()));
2949
    } else if (OB_FAIL(schema_service->fetch_new_table_id(
2950
            new_table_schema.get_tenant_id(), index_table_id))) {
2951
      RS_LOG(WARN, "failed to update_max_used_table_id, ", K(ret));
2952
    } else {
2953
      index_schema.set_table_id(index_table_id);
2954
    }
2955
    if (OB_SUCC(ret)) {
2956
      if (gen_columns.empty()) {
2957
        //create normal index table.
2958
        if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2959
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2960
        } else {
2961
          index_schema.set_schema_version(new_schema_version);
2962
          if (OB_FAIL(schema_service->get_table_sql_service().create_table(index_schema, trans))) {
2963
            RS_LOG(WARN, "alter table create index failed", K(index_schema), K(ret));
2964
          }
2965
        }
2966
      } else {
2967
        // First increase internal generated column, and then create an index on the column
2968
        for (int64_t i = 0; OB_SUCC(ret) && i < gen_columns.count(); ++i) {
2969
          ObColumnSchemaV2 *new_column_schema = gen_columns.at(i);
2970
          if (OB_ISNULL(new_column_schema)) {
2971
            ret = OB_ERR_UNEXPECTED;
2972
            LOG_WARN("new column schema is null");
2973
          } else if (OB_FAIL(insert_single_column(trans, new_table_schema, *new_column_schema))) {
2974
            LOG_WARN("failed to create table schema, ", K(ret));
2975
          }
2976
        }
2977
        if (OB_SUCC(ret)) {
2978
          if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
2979
            LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
2980
          } else {
2981
            index_schema.set_schema_version(new_schema_version);
2982
            if (OB_FAIL(schema_service->get_table_sql_service().create_table(index_schema, trans))) {
2983
              LOG_WARN("failed to create index schema", K(ret));
2984
            }
2985
          }
2986
        }
2987
      }
2988
    }
2989
  }
2990
  return ret;
2991
}
2992

2993
int ObDDLOperator::alter_table_drop_index(
2994
    const ObTableSchema *index_table_schema,
2995
    ObTableSchema &new_data_table_schema,
2996
    common::ObMySQLTransaction &trans)
2997
{
2998
  int ret = OB_SUCCESS;
2999
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3000
  //drop inner generated index column
3001
  ObSchemaGetterGuard schema_guard;
3002
  if (OB_ISNULL(index_table_schema)) {
3003
    ret = OB_INVALID_ARGUMENT;
3004
    LOG_WARN("invalid arguments", K(ret), KP(index_table_schema));
3005
  } else if (OB_ISNULL(schema_service)) {
3006
    ret = OB_ERR_UNEXPECTED;
3007
    LOG_WARN("schema_service is NULL", K(ret));
3008
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(index_table_schema->get_tenant_id(), schema_guard))) {
3009
    LOG_WARN("failed to get schema guard", K(ret));
3010
  } else if (OB_FAIL(drop_inner_generated_index_column(trans, schema_guard, *index_table_schema, new_data_table_schema))) {
3011
    LOG_WARN("drop inner generated index column failed", K(ret));
3012
  } else if (OB_FAIL(drop_table(*index_table_schema, trans))) {  // drop index table
3013
    RS_LOG(WARN, "ddl_operator drop_table failed",
3014
        "table schema", *index_table_schema, K(ret));
3015
  }
3016
  if (OB_SUCC(ret)) {
3017
    RS_LOG(INFO, "finish drop index", K(*index_table_schema), K(ret));
3018
  }
3019
  return ret;
3020
}
3021

3022
int ObDDLOperator::alter_table_alter_index(
3023
    const uint64_t tenant_id,
3024
    const uint64_t data_table_id,
3025
    const uint64_t database_id,
3026
    const ObAlterIndexArg &alter_index_arg,
3027
    ObMySQLTransaction &trans)
3028
{
3029
  int ret = OB_SUCCESS;
3030
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3031
  ObSchemaGetterGuard schema_guard;
3032
  if (OB_ISNULL(schema_service)) {
3033
    ret = OB_ERR_UNEXPECTED;
3034
    LOG_WARN("schema_service is NULL", K(ret));
3035
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
3036
    LOG_WARN("failed to get schema guard", K(ret));
3037
  } else {
3038
    const uint64_t tenant_id = alter_index_arg.tenant_id_;
3039
    int64_t new_schema_version = OB_INVALID_VERSION;
3040
    RS_LOG(INFO, "start alter table alter index", K(alter_index_arg));
3041
    const ObTableSchema *index_table_schema = NULL;
3042
    ObString index_table_name;
3043
    ObArenaAllocator allocator(ObModIds::OB_SCHEMA);
3044
    const ObString &index_name = alter_index_arg.index_name_;
3045

3046
    //build index name and get index schema
3047
    if (OB_FAIL(ObTableSchema::build_index_table_name(allocator,
3048
                                                      data_table_id,
3049
                                                      index_name,
3050
                                                      index_table_name))) {
3051
      RS_LOG(WARN, "build_index_table_name failed", K(data_table_id), K(index_name), K(ret));
3052
    } else {
3053
      const bool is_index = true;
3054
      ObTableSchema new_index_table_schema;
3055
      if (OB_FAIL(schema_guard.get_table_schema(tenant_id,
3056
                                                database_id,
3057
                                                index_table_name,
3058
                                                is_index,
3059
                                                index_table_schema))) {
3060
        LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(database_id), K(index_table_schema));
3061
      } else if (OB_UNLIKELY(NULL == index_table_schema)) {
3062
        ret = OB_ERR_UNEXPECTED;
3063
        RS_LOG(WARN, "get index table schema failed", K(tenant_id),
3064
               K(database_id), K(index_table_name), K(ret));
3065
      } else if (index_table_schema->is_in_recyclebin()) {
3066
        ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
3067
        RS_LOG(WARN, "index table is in recyclebin", K(ret));
3068
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3069
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3070
      } else if (OB_FAIL(new_index_table_schema.assign(*index_table_schema))) {
3071
        LOG_WARN("fail to assign schema", K(ret));
3072
      } else {
3073
        new_index_table_schema.set_index_visibility(alter_index_arg.index_visibility_);
3074
        new_index_table_schema.set_schema_version(new_schema_version);
3075
        if(OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3076
                    trans,
3077
                    *index_table_schema,
3078
                    new_index_table_schema,
3079
                    index_table_schema->is_global_index_table() ? OB_DDL_ALTER_GLOBAL_INDEX: OB_DDL_ALTER_TABLE))) {
3080
          RS_LOG(WARN, "schema service update_table_options failed",
3081
                 K(*index_table_schema), K(ret));
3082
        }
3083
      }
3084
    }
3085
    RS_LOG(INFO, "finish alter table alter index", K(alter_index_arg), K(ret));
3086
  }
3087
  return ret;
3088
}
3089

3090
// description: delete foreign key of table in a transaction
3091
//
3092
// @param [in] table_schema
3093
// @param [in] drop_foreign_key_arg
3094
// @param [in] trans
3095
//
3096
// @return oceanbase error code defined in lib/ob_errno.def
3097
int ObDDLOperator::alter_table_drop_foreign_key(const ObTableSchema &table_schema,
3098
                                                const ObDropForeignKeyArg &drop_foreign_key_arg,
3099
                                                ObMySQLTransaction &trans,
3100
                                                const ObForeignKeyInfo *&parent_table_mock_foreign_key_info,
3101
                                                const bool parent_table_in_offline_ddl_white_list)
3102
{
3103
  int ret = OB_SUCCESS;
3104
  const uint64_t tenant_id = table_schema.get_tenant_id();
3105
  int64_t new_schema_version = OB_INVALID_VERSION;
3106
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
3107
  ObTableSqlService *table_sql_service = NULL;
3108
  const ObString &foreign_key_name = drop_foreign_key_arg.foreign_key_name_;
3109
  if (OB_ISNULL(schema_service_impl)) {
3110
    ret = OB_ERR_SYS;
3111
    LOG_ERROR("schema_service_impl must not null", K(ret));
3112
  } else if (FALSE_IT(table_sql_service = &schema_service_impl->get_table_sql_service())) {
3113
  } else {
3114
    const ObIArray<ObForeignKeyInfo> &foreign_key_infos = table_schema.get_foreign_key_infos();
3115
    const ObForeignKeyInfo *foreign_key_info = NULL;
3116
    for (int64_t i = 0; OB_SUCC(ret) && i < foreign_key_infos.count(); i++) {
3117
      if (0 == foreign_key_name.case_compare(foreign_key_infos.at(i).foreign_key_name_)
3118
          && table_schema.get_table_id() == foreign_key_infos.at(i).child_table_id_) {
3119
        foreign_key_info = &foreign_key_infos.at(i);
3120
        break;
3121
      }
3122
    }
3123
    if (OB_SUCC(ret) && OB_ISNULL(foreign_key_info)) {
3124
      bool is_oracle_mode = false;
3125
      if (OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_table_id(
3126
         table_schema.get_tenant_id(), table_schema.get_table_id(), is_oracle_mode))) {
3127
       LOG_WARN("fail to check is oracle mode", K(ret), K(table_schema));
3128
      } else if (is_oracle_mode) {
3129
       ret = OB_ERR_NONEXISTENT_CONSTRAINT;
3130
       LOG_WARN("Cannot drop foreign key constraint  - nonexistent constraint", K(ret), K(foreign_key_name), K(table_schema.get_table_name_str()));
3131
      } else {
3132
       ret = OB_ERR_CANT_DROP_FIELD_OR_KEY;
3133
       LOG_USER_ERROR(OB_ERR_CANT_DROP_FIELD_OR_KEY, foreign_key_name.length(), foreign_key_name.ptr());
3134
       LOG_WARN("Cannot drop foreign key constraint  - nonexistent constraint", K(ret), K(foreign_key_name), K(table_schema.get_table_name_str()));
3135
      }
3136
    }
3137
    if (OB_FAIL(ret)) {
3138
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3139
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3140
    } else if (OB_FAIL(table_sql_service->drop_foreign_key(
3141
                       new_schema_version, trans, table_schema, foreign_key_info, parent_table_in_offline_ddl_white_list))) {
3142
      LOG_WARN("failed to drop foreign key", K(ret), K(foreign_key_name));
3143
    } else if (foreign_key_info->is_parent_table_mock_) {
3144
      parent_table_mock_foreign_key_info = foreign_key_info;
3145
    }
3146
  }
3147
  return ret;
3148
}
3149

3150
int ObDDLOperator::create_mock_fk_parent_table(
3151
    ObMySQLTransaction &trans,
3152
    const share::schema::ObMockFKParentTableSchema &mock_fk_parent_table_schema,
3153
    const bool need_update_foreign_key)
3154
{
3155
  int ret = OB_SUCCESS;
3156
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
3157
  if (OB_FAIL(schema_service_impl->get_table_sql_service().add_mock_fk_parent_table(
3158
              &trans, mock_fk_parent_table_schema, need_update_foreign_key))) {
3159
    LOG_WARN("insert mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema));
3160
  } else if (need_update_foreign_key) { // if need_update_foreign_key, then need_sync_version_for_cascade_child_table
3161
    ObArray<uint64_t> child_table_ids;
3162
    for (int64_t i = 0; OB_SUCC(ret) && i < mock_fk_parent_table_schema.get_foreign_key_infos().count(); ++i) {
3163
      if (OB_FAIL(child_table_ids.push_back(mock_fk_parent_table_schema.get_foreign_key_infos().at(i).child_table_id_))) {
3164
        LOG_WARN("fail to push back child_table_id", K(ret), K(mock_fk_parent_table_schema.get_foreign_key_infos().at(i)));
3165
      }
3166
    }
3167
    if (FAILEDx(sync_version_for_cascade_table(mock_fk_parent_table_schema.get_tenant_id(), child_table_ids, trans))) {
3168
      LOG_WARN("fail to sync versin for children tables", K(ret), K(child_table_ids));
3169
    }
3170
  }
3171
  return ret;
3172
}
3173

3174
int ObDDLOperator::alter_mock_fk_parent_table(
3175
    ObMySQLTransaction &trans,
3176
    share::schema::ObMockFKParentTableSchema &mock_fk_parent_table_schema)
3177
{
3178
  int ret = OB_SUCCESS;
3179
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
3180
  if (OB_FAIL(schema_service_impl->get_table_sql_service().alter_mock_fk_parent_table(
3181
              &trans, mock_fk_parent_table_schema))) {
3182
    LOG_WARN("alter mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema));
3183
  }
3184
  return ret;
3185
}
3186

3187
int ObDDLOperator::drop_mock_fk_parent_table(
3188
    ObMySQLTransaction &trans,
3189
    const share::schema::ObMockFKParentTableSchema &mock_fk_parent_table_schema)
3190
{
3191
  int ret = OB_SUCCESS;
3192
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
3193
  if (OB_FAIL(schema_service_impl->get_table_sql_service().drop_mock_fk_parent_table(
3194
              &trans, mock_fk_parent_table_schema))) {
3195
    LOG_WARN("drop mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema));
3196
  }
3197
  return ret;
3198
}
3199

3200
int ObDDLOperator::replace_mock_fk_parent_table(
3201
    ObMySQLTransaction &trans,
3202
    share::schema::ObSchemaGetterGuard &schema_guard,
3203
    const share::schema::ObMockFKParentTableSchema &mock_fk_parent_table_schema)
3204
{
3205
  int ret = OB_SUCCESS;
3206
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
3207
  const ObMockFKParentTableSchema *ori_mock_fk_parent_table_schema_ptr = NULL;
3208
  if (OB_FAIL(schema_guard.get_mock_fk_parent_table_schema_with_id(
3209
      mock_fk_parent_table_schema.get_tenant_id(), mock_fk_parent_table_schema.get_mock_fk_parent_table_id(),
3210
      ori_mock_fk_parent_table_schema_ptr))) {
3211
    LOG_WARN("check_mock_fk_parent_table_exist_by_id failed", K(ret), K(mock_fk_parent_table_schema.get_tenant_id()), K(mock_fk_parent_table_schema));
3212
  } else if (OB_ISNULL(ori_mock_fk_parent_table_schema_ptr)) {
3213
    ret = OB_ERR_UNEXPECTED;
3214
    LOG_WARN("ori_mock_fk_parent_table_schema_ptr is null", K(ret), KPC(ori_mock_fk_parent_table_schema_ptr), K(mock_fk_parent_table_schema));
3215
  } else if (mock_fk_parent_table_schema.get_foreign_key_infos().count() <= 0) {
3216
    ret = OB_ERR_UNEXPECTED;
3217
    LOG_WARN("count of foreign_key_infos in mock_fk_parent_table_schema is zero", K(ret), KPC(ori_mock_fk_parent_table_schema_ptr), K(mock_fk_parent_table_schema.get_foreign_key_infos().count()));
3218
  } else if (OB_FAIL(schema_service_impl->get_table_sql_service().replace_mock_fk_parent_table(
3219
                     &trans, mock_fk_parent_table_schema, ori_mock_fk_parent_table_schema_ptr))) {
3220
    LOG_WARN("replace mock_fk_parent_table failed", K(ret), KPC(ori_mock_fk_parent_table_schema_ptr), K(mock_fk_parent_table_schema));
3221
  } else { // update schema version of child tables and new parent table after replace mock_fk_parent_table with new parent table
3222
    ObArray<uint64_t> child_table_ids;
3223
    uint64_t new_parent_table_id = mock_fk_parent_table_schema.get_foreign_key_infos().at(0).parent_table_id_;
3224
    for (int64_t i = 0; OB_SUCC(ret) && i < mock_fk_parent_table_schema.get_foreign_key_infos().count(); ++i) {
3225
      if (OB_FAIL(child_table_ids.push_back(mock_fk_parent_table_schema.get_foreign_key_infos().at(i).child_table_id_))) {
3226
        LOG_WARN("fail to push back child_table_id", K(ret), K(mock_fk_parent_table_schema.get_foreign_key_infos().at(i)));
3227
      }
3228
    }
3229
    if (FAILEDx(sync_version_for_cascade_table(mock_fk_parent_table_schema.get_tenant_id(), child_table_ids, trans))) {
3230
      LOG_WARN("fail to sync versin for children tables", K(ret), K(child_table_ids));
3231
    }
3232
    if (FAILEDx(schema_service_impl->get_table_sql_service().update_data_table_schema_version(trans, mock_fk_parent_table_schema.get_tenant_id(), new_parent_table_id, false))) {
3233
      LOG_WARN("failed to update parent table schema version", K(ret), K(mock_fk_parent_table_schema.get_foreign_key_infos().at(0)));
3234
    }
3235
  }
3236
  return ret;
3237
}
3238

3239
int ObDDLOperator::sync_version_for_cascade_mock_fk_parent_table(
3240
    const uint64_t tenant_id,
3241
    const common::ObIArray<uint64_t> &table_ids,
3242
    common::ObMySQLTransaction &trans)
3243
{
3244
  int ret = OB_SUCCESS;
3245
  uint64_t id = OB_INVALID_ID;
3246
  const ObMockFKParentTableSchema *schema = NULL;
3247
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3248
  if (OB_ISNULL(schema_service)) {
3249
    ret = OB_ERR_SYS;
3250
    RS_LOG(ERROR, "schema_service must not null");
3251
  } else {
3252
    for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count() ; ++i) {
3253
      ObSchemaGetterGuard schema_guard;
3254
      id = table_ids.at(i);
3255
      ObMockFKParentTableSchema tmp_schema;
3256
      if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
3257
        RS_LOG(WARN, "get schema guard failed", K(ret), K(tenant_id), K(id));
3258
      } else if (OB_FAIL(schema_guard.get_mock_fk_parent_table_schema_with_id(tenant_id, id, schema))) {
3259
        LOG_WARN("fail to get table schema", K(ret), K(id));
3260
      } else if (!schema) {
3261
        ret = OB_ERR_UNEXPECTED;
3262
        LOG_WARN("schema is NULL", K(ret));
3263
      } else if (OB_FAIL(tmp_schema.assign(*schema))) {
3264
        LOG_WARN("fail to assign schema", K(ret), KPC(schema));
3265
      } else if (OB_FAIL(schema_service->get_table_sql_service().update_mock_fk_parent_table_schema_version(
3266
              &trans,
3267
              tmp_schema))) {
3268
        RS_LOG(WARN, "fail to sync schema version", K(ret), K(tmp_schema));
3269
      }
3270
    }
3271
  }
3272

3273
  return ret;
3274
}
3275

3276
int ObDDLOperator::deal_with_mock_fk_parent_table(
3277
    ObMySQLTransaction &trans,
3278
    share::schema::ObSchemaGetterGuard &schema_guard,
3279
    ObMockFKParentTableSchema &mock_fk_parent_table_schema)
3280
{
3281
  int ret = OB_SUCCESS;
3282
  int64_t new_schema_version = OB_INVALID_VERSION;
3283
  if (OB_FAIL(schema_service_.gen_new_schema_version(mock_fk_parent_table_schema.get_tenant_id(), new_schema_version))) {
3284
    LOG_WARN("fail to gen new schema version", K(ret), K(mock_fk_parent_table_schema.get_tenant_id()));
3285
  } else if (FALSE_IT(mock_fk_parent_table_schema.set_schema_version(new_schema_version))) {
3286
  } else if (MOCK_FK_PARENT_TABLE_OP_CREATE_TABLE_BY_DROP_PARENT_TABLE == mock_fk_parent_table_schema.get_operation_type()) {
3287
    // One scenes :
3288
    // 1. dropped real parent table
3289
    if (OB_FAIL(create_mock_fk_parent_table(trans, mock_fk_parent_table_schema, true))) {
3290
      LOG_WARN("create mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema));
3291
    }
3292
  } else if (MOCK_FK_PARENT_TABLE_OP_CREATE_TABLE_BY_ADD_FK_IN_CHILD_TBALE == mock_fk_parent_table_schema.get_operation_type()) {
3293
    // Two scenes :
3294
    // 1. create child table with a fk references a mock fk parent table
3295
    // 2. alter child table add fk references a mock fk parent table
3296
    if (OB_FAIL(create_mock_fk_parent_table(trans, mock_fk_parent_table_schema, false))) {
3297
      LOG_WARN("create mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema));
3298
    }
3299
  } else if (MOCK_FK_PARENT_TABLE_OP_DROP_TABLE == mock_fk_parent_table_schema.get_operation_type()) {
3300
    // Three scenes :
3301
    // 1. drop child table with a fk references a mock fk parent table existed
3302
    // 2. drop fk from a child table with a fk references a mock fk parent table existed
3303
    // 3. drop database
3304
    if (OB_FAIL(drop_mock_fk_parent_table(trans, mock_fk_parent_table_schema))) {
3305
      LOG_WARN("drop mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema.get_operation_type()), K(mock_fk_parent_table_schema));
3306
    }
3307
  } else if (MOCK_FK_PARENT_TABLE_OP_ADD_COLUMN == mock_fk_parent_table_schema.get_operation_type()
3308
             || MOCK_FK_PARENT_TABLE_OP_DROP_COLUMN == mock_fk_parent_table_schema.get_operation_type()
3309
             || MOCK_FK_PARENT_TABLE_OP_UPDATE_SCHEMA_VERSION == mock_fk_parent_table_schema.get_operation_type()) {
3310
    // Three scenes :
3311
    // 1. create child table with a fk references a mock fk parent table existed
3312
    // 2. alter child table add fk references a mock fk parent table existed
3313
    // 3. drop fk from a child table with a fk references a mock fk parent table existed
3314
    if (OB_FAIL(alter_mock_fk_parent_table(trans, mock_fk_parent_table_schema))) {
3315
      LOG_WARN("alter mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema.get_operation_type()), K(mock_fk_parent_table_schema));
3316
    }
3317
  } else if (MOCK_FK_PARENT_TABLE_OP_REPLACED_BY_REAL_PREANT_TABLE == mock_fk_parent_table_schema.get_operation_type()) {
3318
    // Five scenes :
3319
    // 1. create table (as select)
3320
    // 2. create table like
3321
    // 3. rename table
3322
    // 4. alter table rename to
3323
    // 5. flashback table to before drop
3324
    if (OB_FAIL(replace_mock_fk_parent_table(trans, schema_guard, mock_fk_parent_table_schema))) {
3325
      LOG_WARN("replace mock_fk_parent_table failed", K(ret), K(mock_fk_parent_table_schema.get_operation_type()), K(mock_fk_parent_table_schema));
3326
    }
3327
  } else {
3328
    ret = OB_ERR_UNEXPECTED;
3329
    LOG_WARN("operation_type is INVALID", K(ret), K(mock_fk_parent_table_schema.get_operation_type()), K(mock_fk_parent_table_schema), K(lbt()));
3330
  }
3331
  return ret;
3332
}
3333

3334
int ObDDLOperator::deal_with_mock_fk_parent_tables(
3335
    ObMySQLTransaction &trans,
3336
    share::schema::ObSchemaGetterGuard &schema_guard,
3337
    ObIArray<ObMockFKParentTableSchema> &mock_fk_parent_table_schema_array)
3338
{
3339
  int ret = OB_SUCCESS;
3340
  for (int64_t i = 0; OB_SUCC(ret) && i < mock_fk_parent_table_schema_array.count(); ++i) {
3341
    if (OB_FAIL(deal_with_mock_fk_parent_table(trans, schema_guard, mock_fk_parent_table_schema_array.at(i)))) {
3342
      LOG_WARN("deal_with_mock_fk_parent_tables failed", K(ret), K(mock_fk_parent_table_schema_array.at(i)));
3343
    }
3344
  }
3345
  return ret;
3346
}
3347

3348
int ObDDLOperator::alter_index_drop_options(const ObTableSchema &index_table_schema,
3349
                                            const ObString &table_name,
3350
                                            ObTableSchema &new_index_table_schema,
3351
                                            ObMySQLTransaction &trans) {
3352
  int ret = OB_SUCCESS;
3353
  const int INVISIBLE = 1;
3354
  const uint64_t DROPINDEX = 1;
3355
  const uint64_t tenant_id = index_table_schema.get_tenant_id();
3356
  int64_t new_schema_version = OB_INVALID_VERSION;
3357
  ObArenaAllocator allocator(ObModIds::OB_SCHEMA);
3358
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3359
  if (OB_ISNULL(schema_service)) {
3360
    ret = OB_ERR_UNEXPECTED;
3361
    LOG_WARN("schema_service is NULL", K(ret));
3362
  } else if (!index_table_schema.is_index_table()) {
3363
    ret = OB_ERR_UNEXPECTED;
3364
    LOG_WARN("index_table_schema is not index", K(ret));
3365
  } else if (OB_FAIL(new_index_table_schema.assign(index_table_schema))) {
3366
    LOG_WARN("fail to assign schema", K(ret));
3367
  } else {
3368
    uint64_t INVISIBLEBEFORE = 0;
3369
    if (!new_index_table_schema.is_index_visible()) {
3370
      INVISIBLEBEFORE = 1;
3371
    } else {
3372
      INVISIBLEBEFORE = 0;
3373
      new_index_table_schema.set_index_visibility(INVISIBLE);
3374
    }
3375
    new_index_table_schema.set_invisible_before(INVISIBLEBEFORE);
3376
    new_index_table_schema.set_drop_index(DROPINDEX);
3377

3378
    ObSqlString sql;
3379
    ObString index_name;
3380
    if (OB_FAIL(ObTableSchema::get_index_name(allocator,
3381
            index_table_schema.get_data_table_id(),
3382
            index_table_schema.get_table_name_str(),
3383
            index_name))) {
3384
      LOG_WARN("failed to build index table name", K(ret));
3385
    } else if (OB_FAIL(sql.append_fmt("DROP INDEX %.*s on %.*s",
3386
            index_name.length(),
3387
            index_name.ptr(),
3388
            table_name.length(),
3389
            table_name.ptr()))) {
3390
      LOG_WARN("failed to append sql", K(ret));
3391
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3392
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3393
    } else {
3394
      ObString ddl_stmt_str = sql.string();
3395
      new_index_table_schema.set_schema_version(new_schema_version);
3396
      if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3397
              trans,
3398
              index_table_schema,
3399
              new_index_table_schema,
3400
              OB_DDL_DROP_INDEX_TO_RECYCLEBIN,
3401
              &ddl_stmt_str))) {
3402
        RS_LOG(WARN, "schema service update_table_optinos failed", K(index_table_schema), K(ret));
3403
      }
3404
    }
3405
  }
3406
  return ret;
3407
}
3408

3409
int ObDDLOperator::alter_table_rename_index(
3410
    const uint64_t tenant_id,
3411
    const uint64_t data_table_id,
3412
    const uint64_t database_id,
3413
    const obrpc::ObRenameIndexArg &rename_index_arg,
3414
    const ObIndexStatus *new_index_status,
3415
    common::ObMySQLTransaction &trans,
3416
    schema::ObTableSchema &new_index_table_schema)
3417
{
3418
  int ret = OB_SUCCESS;
3419
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3420
  ObSchemaGetterGuard schema_guard;
3421
  if (OB_ISNULL(schema_service)) {
3422
    ret = OB_ERR_UNEXPECTED;
3423
    LOG_WARN("schema_service is NULL", K(ret));
3424
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
3425
    LOG_WARN("failed to get schema guard", K(ret));
3426
  } else {
3427
    int64_t new_schema_version = OB_INVALID_VERSION;
3428
    RS_LOG(INFO, "start alter table rename index", K(rename_index_arg));
3429
    const ObTableSchema *index_table_schema = NULL;
3430
    ObString index_table_name;
3431
    ObString new_index_table_name;
3432
    ObArenaAllocator allocator(ObModIds::OB_SCHEMA);
3433
    const ObString &index_name = rename_index_arg.origin_index_name_;
3434
    const ObString &new_index_name = rename_index_arg.new_index_name_;
3435

3436
    if (OB_FAIL(ObTableSchema::build_index_table_name(allocator,
3437
                                                      data_table_id,
3438
                                                      index_name,
3439
                                                      index_table_name))) {
3440
      RS_LOG(WARN, "build_index_table_name failed", K(data_table_id), K(index_name), K(ret));
3441
    } else if (OB_FAIL(ObTableSchema::build_index_table_name(allocator,
3442
                                                      data_table_id,
3443
                                                      new_index_name,
3444
                                                      new_index_table_name))) {
3445
      RS_LOG(WARN, "build_index_table_name failed", K(data_table_id), K(index_name), K(ret));
3446
    } else {
3447
      const bool is_index = true;
3448
      if (OB_FAIL(schema_guard.get_table_schema(tenant_id,
3449
                                                database_id,
3450
                                                index_table_name,
3451
                                                is_index,
3452
                                                index_table_schema))) {
3453
        LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(database_id), K(index_table_schema));
3454
      } else if (OB_UNLIKELY(NULL == index_table_schema)) {
3455
        ret = OB_ERR_UNEXPECTED;
3456
        RS_LOG(WARN, "get index table schema failed", K(tenant_id), K(database_id), K(index_table_name), K(ret));
3457
      } else if (index_table_schema->is_in_recyclebin()) {
3458
        ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
3459
        LOG_WARN("index table is in recyclebin", K(ret));
3460
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3461
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3462
      } else {
3463
        if (OB_FAIL(new_index_table_schema.assign(*index_table_schema))) {
3464
          LOG_WARN("fail to assign schema", K(ret));
3465
        } else {
3466
          new_index_table_schema.set_schema_version(new_schema_version);
3467
          if (nullptr != new_index_status) {
3468
            new_index_table_schema.set_index_status(*new_index_status);
3469
          }
3470
          new_index_table_schema.set_name_generated_type(GENERATED_TYPE_USER);
3471
        }
3472
        if (OB_FAIL(ret)) {
3473
        } else if (OB_FAIL(new_index_table_schema.set_table_name(new_index_table_name))) {
3474
          RS_LOG(WARN, "failed to set new table name!", K(new_index_table_schema), K(ret));
3475
        } else if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3476
                    trans,
3477
                    *index_table_schema,
3478
                    new_index_table_schema,
3479
                    index_table_schema->is_global_index_table() ? OB_DDL_RENAME_GLOBAL_INDEX: OB_DDL_RENAME_INDEX))) {
3480
          RS_LOG(WARN, "schema service update_table_options failed", K(*index_table_schema), K(ret));
3481
        }
3482
      }
3483
    }
3484
  }
3485
  return ret;
3486
}
3487

3488
int ObDDLOperator::alter_index_table_parallel(
3489
    const uint64_t tenant_id,
3490
    const uint64_t data_table_id,
3491
    const uint64_t database_id,
3492
    const obrpc::ObAlterIndexParallelArg &alter_parallel_arg,
3493
    common::ObMySQLTransaction &trans)
3494
{
3495
  int ret = OB_SUCCESS;
3496
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3497
  ObSchemaGetterGuard schema_guard;
3498
  if (OB_ISNULL(schema_service)) {
3499
    ret = OB_ERR_UNEXPECTED;
3500
    LOG_WARN("schema_service is NULL", K(ret));
3501
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
3502
    LOG_WARN("failed to get schema guard", K(ret));
3503
  } else {
3504
    int64_t new_schema_version = OB_INVALID_VERSION;
3505
    RS_LOG(INFO, "start alter table alter index parallel", K(alter_parallel_arg));
3506
    const ObTableSchema *index_table_schema = NULL;
3507
    ObString index_table_name;
3508
    ObArenaAllocator allocator(ObModIds::OB_SCHEMA);
3509
    const ObString &index_name = alter_parallel_arg.index_name_;
3510

3511
    if (OB_FAIL(ObTableSchema::build_index_table_name(allocator,
3512
                                                      data_table_id,
3513
                                                      index_name,
3514
                                                      index_table_name))) {
3515
      RS_LOG(WARN, "build_index_table_name failed", K(data_table_id), K(index_name), K(ret));
3516
    } else {
3517
      const bool is_index = true;
3518
      if (OB_FAIL(schema_guard.get_table_schema(tenant_id,
3519
                                                database_id,
3520
                                                index_table_name,
3521
                                                is_index,
3522
                                                index_table_schema))) {
3523
        LOG_WARN("fail to get table schema",
3524
          K(ret), K(tenant_id), K(database_id), K(index_table_schema));
3525
      } else if (OB_UNLIKELY(NULL == index_table_schema)) {
3526
        ret = OB_ERR_UNEXPECTED;
3527
        RS_LOG(WARN, "get index table schema failed",
3528
          K(tenant_id), K(database_id), K(index_table_name), K(ret));
3529
      } else if (index_table_schema->is_in_recyclebin()) {
3530
        ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
3531
        LOG_WARN("index table is in recyclebin", K(ret));
3532
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3533
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3534
      } else {
3535
        ObTableSchema new_index_table_schema;
3536
        if (OB_FAIL(new_index_table_schema.assign(*index_table_schema))) {
3537
          LOG_WARN("fail to assign schema", K(ret));
3538
        } else {
3539
          new_index_table_schema.set_schema_version(new_schema_version);
3540
        }
3541
        if (OB_SUCC(ret)) {
3542
          new_index_table_schema.set_dop(alter_parallel_arg.new_parallel_);
3543
          if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3544
                    trans,
3545
                    *index_table_schema,
3546
                    new_index_table_schema,
3547
                    OB_DDL_ALTER_INDEX_PARALLEL))) {
3548
            RS_LOG(WARN, "schema service update_table_options failed",
3549
              K(*index_table_schema), K(ret));
3550
          }
3551
        }
3552
      }
3553
    }
3554
  }
3555
  return ret;
3556
}
3557

3558
int ObDDLOperator::alter_index_table_tablespace(const uint64_t data_table_id,
3559
                                                const uint64_t database_id,
3560
                                                const obrpc::ObAlterIndexTablespaceArg &alter_tablespace_arg,
3561
                                                ObSchemaGetterGuard &schema_guard,
3562
                                                common::ObMySQLTransaction &trans)
3563
{
3564
  int ret = OB_SUCCESS;
3565
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3566
  if (OB_ISNULL(schema_service)) {
3567
    ret = OB_ERR_UNEXPECTED;
3568
    LOG_WARN("schema_service is NULL", K(ret));
3569
  } else {
3570
    const uint64_t tenant_id = alter_tablespace_arg.tenant_id_;
3571
    int64_t new_schema_version = OB_INVALID_VERSION;
3572
    const ObTableSchema *index_table_schema = NULL;
3573
    ObString index_table_name;
3574
    ObArenaAllocator allocator(ObModIds::OB_SCHEMA);
3575
    const ObString &index_name = alter_tablespace_arg.index_name_;
3576

3577
    if (OB_FAIL(ObTableSchema::build_index_table_name(allocator,
3578
                                                      data_table_id,
3579
                                                      index_name,
3580
                                                      index_table_name))) {
3581
      RS_LOG(WARN, "build_index_table_name failed", K(data_table_id), K(index_name), K(ret));
3582
    } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id,
3583
                                                database_id,
3584
                                                index_table_name,
3585
                                                true,
3586
                                                index_table_schema))) {
3587
      LOG_WARN("fail to get table schema",
3588
        K(ret), K(tenant_id), K(database_id), K(index_table_schema));
3589
    } else if (OB_ISNULL(index_table_schema)) {
3590
      ret = OB_ERR_UNEXPECTED;
3591
      RS_LOG(WARN, "get index table schema failed",
3592
        K(tenant_id), K(database_id), K(index_table_name), K(ret));
3593
    } else if (index_table_schema->is_in_recyclebin()) {
3594
      ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
3595
      LOG_WARN("index table is in recyclebin", K(ret));
3596
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3597
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3598
    } else {
3599
      ObTableSchema new_index_table_schema;
3600
      if (OB_FAIL(new_index_table_schema.assign(*index_table_schema))) {
3601
        LOG_WARN("fail to assign schema", K(ret));
3602
      } else {
3603
        new_index_table_schema.set_schema_version(new_schema_version);
3604
        new_index_table_schema.set_tablespace_id(alter_tablespace_arg.tablespace_id_);
3605
        new_index_table_schema.set_encryption_str(alter_tablespace_arg.encryption_);
3606
        if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3607
                        trans,
3608
                        *index_table_schema,
3609
                        new_index_table_schema,
3610
                        OB_DDL_ALTER_TABLE))) {
3611
          RS_LOG(WARN, "schema service update_table_options failed",
3612
            K(*index_table_schema), K(ret));
3613
        }
3614
      }
3615
    }
3616
  }
3617
  return ret;
3618
}
3619

3620
//hualong delete later
3621
//int ObDDLOperator::log_ddl_operation(ObSchemaOperation &ddl_operation,
3622
//                                     ObMySQLTransaction &trans)
3623
//{
3624
//  int ret = OB_SUCCESS;
3625
//  ObSchemaService *schema_service = schema_service_.get_schema_service();
3626
//  if (OB_ISNULL(schema_service)) {
3627
//    ret = OB_ERR_UNEXPECTED;
3628
//    LOG_WARN("schema_service is NULL", K(ret));
3629
//  } else if (OB_FAIL(schema_service->log_operation(ddl_operation, &trans))) {
3630
//    RS_LOG(WARN, "failed to log ddl operation!", K(ret));
3631
//  } else {
3632
//    // do-nothing
3633
//  }
3634
//  return ret;
3635
//}
3636

3637
int ObDDLOperator::alter_table_options(
3638
    ObSchemaGetterGuard &schema_guard,
3639
    ObTableSchema &new_table_schema,
3640
    const ObTableSchema &table_schema,
3641
    const bool update_index_table,
3642
    ObMySQLTransaction &trans,
3643
    const ObIArray<ObTableSchema> *global_idx_schema_array/*=NULL*/)
3644
{
3645
  int ret = OB_SUCCESS;
3646
  const uint64_t tenant_id = table_schema.get_tenant_id();
3647
  int64_t new_schema_version = OB_INVALID_VERSION;
3648
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3649
  if (OB_ISNULL(schema_service)) {
3650
    ret = OB_ERR_SYS;
3651
    RS_LOG(WARN, "schema sql service must not be null",
3652
           K(schema_service), K(ret));
3653
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3654
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3655
  } else {
3656
    new_table_schema.set_schema_version(new_schema_version);
3657
    if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3658
        trans,
3659
        table_schema,
3660
        new_table_schema,
3661
        OB_DDL_ALTER_TABLE))) {
3662
      RS_LOG(WARN, "failed to alter table option!", K(ret));
3663
    } else if (update_index_table) {
3664
      if (OB_FAIL(update_aux_table(table_schema,
3665
          new_table_schema,
3666
          schema_guard,
3667
          trans,
3668
          USER_INDEX,
3669
          global_idx_schema_array))) {
3670
        RS_LOG(WARN, "failed to update_index_table!", K(ret), K(table_schema), K(new_table_schema));
3671
      } else if (OB_FAIL(update_aux_table(table_schema,
3672
          new_table_schema,
3673
          schema_guard,
3674
          trans,
3675
          AUX_VERTIAL_PARTITION_TABLE))) {
3676
        RS_LOG(WARN, "failed to update_aux_vp_table!", K(ret), K(table_schema), K(new_table_schema));
3677
      } else if (OB_FAIL(update_aux_table(table_schema,
3678
          new_table_schema,
3679
          schema_guard,
3680
          trans,
3681
          AUX_LOB_META))) {
3682
        RS_LOG(WARN, "failed to update_aux_vp_table!", K(ret), K(table_schema), K(new_table_schema));
3683
      } else if (OB_FAIL(update_aux_table(table_schema,
3684
          new_table_schema,
3685
          schema_guard,
3686
          trans,
3687
          AUX_LOB_PIECE))) {
3688
        RS_LOG(WARN, "failed to update_aux_vp_table!", K(ret), K(table_schema), K(new_table_schema));
3689
      }
3690
    }
3691
  }
3692
  return ret;
3693
}
3694

3695
int ObDDLOperator::update_aux_table(
3696
    const ObTableSchema &table_schema,
3697
    const ObTableSchema &new_table_schema,
3698
    ObSchemaGetterGuard &schema_guard,
3699
    ObMySQLTransaction &trans,
3700
    const ObTableType table_type,
3701
    const ObIArray<ObTableSchema> *global_idx_schema_array/*=NULL*/)
3702
{
3703
  int ret = OB_SUCCESS;
3704
  const uint64_t tenant_id = table_schema.get_tenant_id();
3705
  const bool is_index = USER_INDEX == table_type;
3706
  ObSEArray<uint64_t, 16> aux_tid_array;
3707
  ObSEArray<ObAuxTableMetaInfo, 16> simple_index_infos;
3708
  uint64_t lob_meta_table_id = OB_INVALID_ID;
3709
  uint64_t lob_piece_table_id = OB_INVALID_ID;
3710
  int64_t N = 0;
3711
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3712
  if (OB_ISNULL(schema_service)) {
3713
    ret = OB_ERR_SYS;
3714
    RS_LOG(WARN, "schema sql service must not be null",
3715
           K(schema_service), K(ret));
3716
  } else {
3717
    if (table_type == USER_INDEX) {
3718
      if (OB_FAIL(new_table_schema.get_simple_index_infos(simple_index_infos))) {
3719
        LOG_WARN("get_aux_tid_array failed", K(ret), K(table_type));
3720
      } else {
3721
        N = simple_index_infos.count();
3722
      }
3723
    } else if (table_type == AUX_VERTIAL_PARTITION_TABLE) {
3724
      if (OB_FAIL(new_table_schema.get_aux_vp_tid_array(aux_tid_array))) {
3725
        LOG_WARN("get_aux_tid_array failed", K(ret), K(table_type));
3726
      } else {
3727
        N = aux_tid_array.count();
3728
      }
3729
    } else if (table_type == AUX_LOB_META) {
3730
      lob_meta_table_id = new_table_schema.get_aux_lob_meta_tid();
3731
      N = (table_schema.has_lob_aux_table() && new_table_schema.has_lob_aux_table()) ? 1 : 0;
3732
    } else if (table_type == AUX_LOB_PIECE) {
3733
      lob_piece_table_id = new_table_schema.get_aux_lob_piece_tid();
3734
      N = (table_schema.has_lob_aux_table() && new_table_schema.has_lob_aux_table()) ? 1 : 0;
3735
    } else {
3736
      ret = OB_ERR_UNEXPECTED;
3737
      LOG_WARN("invalid table type", K(ret), K(table_type));
3738
    }
3739
  }
3740
  if (OB_SUCC(ret)) {
3741
    ObTableSchema new_aux_table_schema;
3742
    for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) {
3743
      const ObTableSchema *aux_table_schema = NULL;
3744
      if (is_index && OB_NOT_NULL(global_idx_schema_array) && !global_idx_schema_array->empty()) {
3745
        for (int64_t j = 0; OB_SUCC(ret) && j < global_idx_schema_array->count(); ++j) {
3746
          if (simple_index_infos.at(i).table_id_ == global_idx_schema_array->at(j).get_table_id()) {
3747
            aux_table_schema = &(global_idx_schema_array->at(j));
3748
            break;
3749
          }
3750
        }
3751
      }
3752
      uint64_t tid = 0;
3753
      if (table_type == USER_INDEX) {
3754
        tid = simple_index_infos.at(i).table_id_;
3755
      } else if (table_type == AUX_VERTIAL_PARTITION_TABLE) {
3756
        tid = aux_tid_array.at(i);
3757
      } else if (table_type == AUX_LOB_META) {
3758
        tid = lob_meta_table_id;
3759
      } else if (table_type == AUX_LOB_PIECE) {
3760
        tid = lob_piece_table_id;
3761
      }
3762
      if (OB_FAIL(ret)) {
3763
      } else if (OB_ISNULL(aux_table_schema)
3764
                 && OB_FAIL(schema_guard.get_table_schema(tenant_id, tid, aux_table_schema))) {
3765
        RS_LOG(WARN, "get_table_schema failed", K(tenant_id), "table id", tid, K(ret));
3766
      } else if (OB_ISNULL(aux_table_schema)) {
3767
        ret = OB_ERR_UNEXPECTED;
3768
        RS_LOG(WARN, "table schema should not be null", K(ret));
3769
      } else {
3770
        new_aux_table_schema.reset();
3771
        if (OB_FAIL(new_aux_table_schema.assign(*aux_table_schema))) {
3772
          LOG_WARN("fail to assign schema", K(ret));
3773
        } else {
3774
          if (!aux_table_schema->is_global_index_table()) {
3775
            // tablegroup of global index should not inherit the tablegroup of the data table.
3776
            // the partitions numbers of all table of tablegroup are equal.
3777
            new_aux_table_schema.set_tablegroup_id(new_table_schema.get_tablegroup_id());
3778
          }
3779
          new_aux_table_schema.set_database_id(new_table_schema.get_database_id());
3780
          new_aux_table_schema.set_read_only(new_table_schema.is_read_only());
3781
          new_aux_table_schema.set_progressive_merge_num(new_table_schema.get_progressive_merge_num());
3782
          new_aux_table_schema.set_tablet_size(new_table_schema.get_tablet_size());
3783
          new_aux_table_schema.set_pctfree(new_table_schema.get_pctfree());
3784
          new_aux_table_schema.set_block_size(new_table_schema.get_block_size());
3785
          new_aux_table_schema.set_row_store_type(new_table_schema.get_row_store_type());
3786
          new_aux_table_schema.set_store_format(new_table_schema.get_store_format());
3787
          new_aux_table_schema.set_progressive_merge_round(new_table_schema.get_progressive_merge_round());
3788
          new_aux_table_schema.set_storage_format_version(new_table_schema.get_storage_format_version());
3789
          // index table should only inherit table mode and table state flag from data table
3790
          new_aux_table_schema.set_table_mode(new_table_schema.get_table_mode_flag());
3791
          new_aux_table_schema.set_table_state_flag(new_table_schema.get_table_state_flag());
3792
        }
3793
        if (OB_FAIL(ret)) {
3794
        } else if (OB_FAIL(new_aux_table_schema.set_compress_func_name(new_table_schema.get_compress_func_name()))) {
3795
          LOG_WARN("set_compress_func_name failed", K(new_table_schema));
3796
        } else if (aux_table_schema->is_in_recyclebin()) {
3797
          const uint64_t tenant_id = aux_table_schema->get_tenant_id();
3798
          ObArray<ObRecycleObject> recycle_objs;
3799
          ObRecycleObject::RecycleObjType recycle_type = ObRecycleObject::get_type_by_table_schema(*aux_table_schema);
3800
          new_aux_table_schema.set_database_id(aux_table_schema->get_database_id());
3801
          if (OB_INVALID_ID == tenant_id) {
3802
            ret = OB_INVALID_ARGUMENT;
3803
            LOG_WARN("tenant_id is invalid", K(ret));
3804
          } else if (OB_FAIL(schema_service->fetch_recycle_object(
3805
                  tenant_id,
3806
                  aux_table_schema->get_table_name_str(),
3807
                  recycle_type,
3808
                  trans,
3809
                  recycle_objs))) {
3810
            LOG_WARN("get recycle object failed", K(tenant_id), K(ret));
3811
          } else if (recycle_objs.size() != 1) {
3812
            ret = OB_ERR_UNEXPECTED;
3813
            LOG_WARN("unexpected recycle object num", K(ret), K(*aux_table_schema), "size", recycle_objs.size());
3814
          } else if (OB_FAIL(schema_service->delete_recycle_object(
3815
                  tenant_id,
3816
                  recycle_objs.at(0),
3817
                  trans))) {
3818
            LOG_WARN("delete recycle object failed", K(ret));
3819
          } else {
3820
            ObRecycleObject &recycle_obj = recycle_objs.at(0);
3821
            recycle_obj.set_database_id(new_table_schema.get_database_id());
3822
            recycle_obj.set_tablegroup_id(new_table_schema.get_tablegroup_id());
3823
            if (OB_FAIL(schema_service->insert_recyclebin_object(recycle_obj, trans))) {
3824
              LOG_WARN("insert recyclebin object failed", K(ret));
3825
            }
3826
          }
3827
        }
3828
        int64_t new_schema_version = OB_INVALID_VERSION;
3829
        if (OB_FAIL(ret)) {
3830
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3831
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3832
        } else {
3833
          new_aux_table_schema.set_schema_version(new_schema_version);
3834
          if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3835
                  trans,
3836
                  *aux_table_schema,
3837
                  new_aux_table_schema,
3838
                  OB_DDL_ALTER_TABLE))) {
3839
            RS_LOG(WARN, "schema service update_table_options failed",
3840
                K(*aux_table_schema), K(ret));
3841
          }
3842
        }
3843
      }
3844
    }
3845
  }
3846
  return ret;
3847
}
3848

3849
int ObDDLOperator::rename_table(const ObTableSchema &table_schema,
3850
                                const ObString &new_table_name,
3851
                                const uint64_t new_db_id,
3852
                                const bool need_reset_object_status,
3853
                                ObMySQLTransaction &trans,
3854
                                const ObString *ddl_stmt_str)
3855
{
3856
  int ret = OB_SUCCESS;
3857
  const uint64_t tenant_id = table_schema.get_tenant_id();
3858
  int64_t new_schema_version = OB_INVALID_VERSION;
3859
  ObSchemaGetterGuard schema_guard;
3860
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3861
  if (OB_ISNULL(schema_service)) {
3862
    ret = OB_ERR_SYS;
3863
    RS_LOG(WARN, "schema sql service must not be null",
3864
           K(schema_service), K(ret));
3865
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
3866
    RS_LOG(WARN, "get schema guard failed", K(ret));
3867
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3868
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3869
  } else {
3870
    bool update_aux_table = false;
3871
    ObTableSchema new_table_schema;
3872
    if (OB_FAIL(new_table_schema.assign(table_schema))) {
3873
      LOG_WARN("fail to assign schema", K(ret));
3874
    } else {
3875
      new_table_schema.set_schema_version(new_schema_version);
3876
    }
3877
    if (need_reset_object_status) {
3878
      new_table_schema.set_object_status(ObObjectStatus::INVALID);
3879
    }
3880
    if (OB_FAIL(ret)) {
3881
    } else if (OB_FAIL(new_table_schema.set_table_name(new_table_name))) {
3882
      RS_LOG(WARN, "failed to set new table name!", K(new_table_name), K(table_schema), K(ret));
3883
    } else if (new_db_id != table_schema.get_database_id()) {
3884
      update_aux_table = true;
3885
      new_table_schema.set_database_id(new_db_id);
3886
    }
3887

3888
    if (OB_SUCC(ret)) {
3889
      if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3890
          trans,
3891
          table_schema,
3892
          new_table_schema,
3893
          OB_DDL_TABLE_RENAME,
3894
          ddl_stmt_str))) {
3895
        RS_LOG(WARN, "failed to alter table option!", K(ret));
3896
      } else if (update_aux_table) {
3897
        HEAP_VAR(ObTableSchema, new_aux_table_schema) {
3898
          { // update index table
3899
            ObSEArray<ObAuxTableMetaInfo, 16> simple_index_infos;
3900
            if (OB_FAIL(table_schema.get_simple_index_infos(simple_index_infos))) {
3901
              RS_LOG(WARN, "get_index_tid_array failed", K(ret));
3902
            } else {
3903
              for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
3904
                if (OB_FAIL(rename_aux_table(new_table_schema,
3905
                                             simple_index_infos.at(i).table_id_,
3906
                                             schema_guard,
3907
                                             trans,
3908
                                             new_aux_table_schema))) {
3909
                  RS_LOG(WARN, "fail to rename update index table", K(ret));
3910
                }
3911
              }
3912
            }
3913
          }
3914
          if (OB_SUCC(ret) && table_schema.has_lob_aux_table()) {
3915
            uint64_t mtid = table_schema.get_aux_lob_meta_tid();
3916
            uint64_t ptid = table_schema.get_aux_lob_piece_tid();
3917
            if (OB_INVALID_ID == mtid || OB_INVALID_ID == ptid) {
3918
              ret = OB_ERR_UNEXPECTED;
3919
              RS_LOG(WARN, "Expect meta tid and piece tid valid", KR(ret), K(mtid), K(ptid));
3920
            } else if (OB_FAIL(rename_aux_table(new_table_schema,
3921
                                                mtid,
3922
                                                schema_guard,
3923
                                                trans,
3924
                                                new_aux_table_schema))) {
3925
              RS_LOG(WARN, "fail to rename update lob meta table", KR(ret), K(mtid));
3926
            } else if (OB_FAIL(rename_aux_table(new_table_schema,
3927
                                                ptid,
3928
                                                schema_guard,
3929
                                                trans,
3930
                                                new_aux_table_schema))) {
3931
              RS_LOG(WARN, "fail to rename update lob piece table", KR(ret), K(ptid));
3932
            }
3933
          }
3934
        }
3935
      }
3936
    }
3937
  }
3938
  return ret;
3939
}
3940

3941
int ObDDLOperator::rename_aux_table(
3942
    const ObTableSchema &new_table_schema,
3943
    const uint64_t table_id,
3944
    ObSchemaGetterGuard &schema_guard,
3945
    ObMySQLTransaction &trans,
3946
    ObTableSchema &new_aux_table_schema)
3947
{
3948
  int ret = OB_SUCCESS;
3949
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
3950
  ObSchemaService *schema_service = schema_service_.get_schema_service();
3951
  const ObTableSchema *aux_table_schema = NULL;
3952
  int64_t new_schema_version = OB_INVALID_VERSION;
3953
  if (OB_FAIL(schema_guard.get_table_schema(
3954
              tenant_id, table_id, aux_table_schema))) {
3955
    RS_LOG(WARN, "get_table_schema failed", K(tenant_id),
3956
            "table id", table_id, K(ret));
3957
  } else if (OB_ISNULL(aux_table_schema)) {
3958
    ret = OB_ERR_UNEXPECTED;
3959
    RS_LOG(WARN, "table schema should not be null", K(ret));
3960
  } else {
3961
    new_aux_table_schema.reset();
3962
    if (OB_FAIL(new_aux_table_schema.assign(*aux_table_schema))) {
3963
      LOG_WARN("fail to assign schema", K(ret));
3964
    } else {
3965
      new_aux_table_schema.set_database_id(new_table_schema.get_database_id());
3966
    }
3967
    if (OB_FAIL(ret)) {
3968
    } else if (aux_table_schema->is_in_recyclebin()) {
3969
      ret = OB_ERR_UNEXPECTED;
3970
      LOG_WARN("aux table is in recycle bin while main table not in", K(ret), KPC(aux_table_schema));
3971
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
3972
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
3973
    } else {
3974
      new_aux_table_schema.set_schema_version(new_schema_version);
3975
      if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
3976
              trans,
3977
              *aux_table_schema,
3978
              new_aux_table_schema,
3979
              OB_DDL_TABLE_RENAME))) {
3980
        RS_LOG(WARN, "schema service update_table_options failed",
3981
            K(*aux_table_schema), K(ret));
3982
      }
3983
    }
3984
  }
3985
  return ret;
3986
}
3987

3988
int ObDDLOperator::update_index_status(
3989
    const uint64_t tenant_id,
3990
    const uint64_t data_table_id,
3991
    const uint64_t index_table_id,
3992
    const share::schema::ObIndexStatus status,
3993
    const bool in_offline_ddl_white_list,
3994
    common::ObMySQLTransaction &trans,
3995
    const common::ObString *ddl_stmt_str)
3996
{
3997
  int ret = OB_SUCCESS;
3998
  int64_t new_schema_version = OB_INVALID_VERSION;
3999
  ObSchemaService *schema_service = schema_service_.get_schema_service();
4000
  ObSchemaGetterGuard schema_guard;
4001
  const ObTableSchema *data_table_schema = nullptr;
4002
  ObTableSchema copy_data_table_schema;
4003

4004
  if (OB_INVALID_ID == data_table_id || OB_INVALID_ID == index_table_id
4005
      || status <= INDEX_STATUS_NOT_FOUND || status >= INDEX_STATUS_MAX) {
4006
    ret = OB_INVALID_ARGUMENT;
4007
    LOG_WARN("invalid argument", K(data_table_id), K(index_table_id), K(status));
4008
  } else if (OB_ISNULL(schema_service)) {
4009
    ret = OB_ERR_SYS;
4010
    LOG_WARN("schema service should not be NULL");
4011
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
4012
    LOG_WARN("get tenant schema guard failed", K(ret), K(tenant_id));
4013
  } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, data_table_id, data_table_schema))) {
4014
    LOG_WARN("get table schema failed", K(ret));
4015
  } else if (nullptr == data_table_schema) {
4016
    ret = OB_ERR_UNEXPECTED;
4017
    LOG_WARN("error unexpected, table schema must not be nullptr", K(ret));
4018
  } else if (OB_FAIL(copy_data_table_schema.assign(*data_table_schema))) {
4019
    LOG_WARN("assign data table schema failed", K(ret));
4020
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4021
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4022
  } else if (FALSE_IT(copy_data_table_schema.set_in_offline_ddl_white_list(in_offline_ddl_white_list))) {
4023
  } else if (OB_FAIL(schema_service->get_table_sql_service().update_index_status(
4024
      copy_data_table_schema, index_table_id, status, new_schema_version, trans, ddl_stmt_str))) {
4025
    LOG_WARN("update index status failed",
4026
        K(ret), K(data_table_id), K(index_table_id), K(status));
4027
  }
4028
  return ret;
4029
}
4030

4031
int ObDDLOperator::update_table_attribute(ObTableSchema &new_table_schema,
4032
                                          common::ObMySQLTransaction &trans,
4033
                                          const ObSchemaOperationType operation_type,
4034
                                          const ObString *ddl_stmt_str/*=NULL*/)
4035
{
4036
  int ret = OB_SUCCESS;
4037
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
4038
  int64_t new_schema_version = OB_INVALID_VERSION;
4039
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4040
  const bool update_object_status_ignore_version = false;
4041
  if (OB_ISNULL(schema_service_impl)) {
4042
    ret = OB_ERR_SYS;
4043
    RS_LOG(WARN, "schema_service_impl must not null", K(ret));
4044
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4045
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4046
  } else {
4047
    new_table_schema.set_schema_version(new_schema_version);
4048
    if (OB_FAIL(schema_service_impl->get_table_sql_service().update_table_attribute(
4049
        trans,
4050
        new_table_schema,
4051
        operation_type,
4052
        update_object_status_ignore_version,
4053
        ddl_stmt_str))) {
4054
      RS_LOG(WARN, "failed to update table attribute!" ,K(ret));
4055
    }
4056
  }
4057
  return ret;
4058
}
4059

4060
int ObDDLOperator::update_single_column(common::ObMySQLTransaction &trans,
4061
                                        const ObTableSchema &origin_table_schema,
4062
                                        const ObTableSchema &new_table_schema,
4063
                                        ObColumnSchemaV2 &column_schema)
4064
{
4065
  int ret = OB_SUCCESS;
4066
  const uint64_t tenant_id = origin_table_schema.get_tenant_id();
4067
  int64_t new_schema_version = OB_INVALID_VERSION;
4068
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4069
  if (OB_ISNULL(schema_service_impl)) {
4070
    ret = OB_ERR_SYS;
4071
    RS_LOG(WARN, "schema_service_impl must not null", K(ret));
4072
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4073
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4074
  } else {
4075
    column_schema.set_schema_version(new_schema_version);
4076
    const ObColumnSchemaV2 *orig_column_schema = origin_table_schema.get_column_schema(column_schema.get_column_id());
4077
    if (OB_FAIL(schema_service_impl->get_table_sql_service().update_single_column(
4078
              trans, origin_table_schema, new_table_schema, column_schema,
4079
              true /* record_ddl_operation */))) {
4080
      RS_LOG(WARN, "failed to update single column", K(ret));
4081
    }
4082
  }
4083
  return ret;
4084
}
4085

4086
int ObDDLOperator::update_single_column_group(common::ObMySQLTransaction &trans,
4087
                                              const ObTableSchema &origin_table_schema,
4088
                                              const ObColumnSchemaV2 &column_schema)
4089
{
4090
  int ret = OB_SUCCESS;
4091
  bool is_each_cg_exist = false;
4092
  const ObColumnSchemaV2 *orig_column_schema = nullptr;
4093
  char cg_name[OB_MAX_COLUMN_GROUP_NAME_LENGTH] = {'\0'};
4094
  ObString cg_name_str(OB_MAX_COLUMN_GROUP_NAME_LENGTH, 0, cg_name);
4095
  const uint64_t tenant_id = origin_table_schema.get_tenant_id();
4096
  ObColumnGroupSchema *ori_cg = nullptr;
4097
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4098
  orig_column_schema = origin_table_schema.get_column_schema(column_schema.get_column_id());
4099
  if (!origin_table_schema.is_valid() || !column_schema.is_valid()) {
4100
    ret = OB_INVALID_ARGUMENT;
4101
    RS_LOG(WARN, "Invalid arguemnt", K(ret), K(origin_table_schema), K(column_schema));
4102
  } else if (OB_ISNULL(orig_column_schema)) {
4103
    ret = OB_ERR_UNEXPECTED;
4104
    RS_LOG(WARN, "column should not be null", K(ret), K(column_schema), K(origin_table_schema));
4105
  } else if (orig_column_schema->get_column_name_str() == column_schema.get_column_name_str()) {
4106
    /* now only rename column will use this func, other skip*/
4107
  } else if (!origin_table_schema.is_column_store_supported()) {
4108
    /* only support table need column group*/
4109
  } else if (OB_FAIL(origin_table_schema.is_column_group_exist(OB_EACH_COLUMN_GROUP_NAME, is_each_cg_exist))) {
4110
    RS_LOG(WARN, "fail check whether each cg exist", K(ret));
4111
  } else if (!is_each_cg_exist) {
4112
    /* if each cg not exist skip*/
4113
  } else if (column_schema.is_virtual_generated_column()) {
4114
    /* skip virtual generated_column*/
4115
  } else if (OB_FAIL(orig_column_schema->get_each_column_group_name(cg_name_str))) {
4116
    RS_LOG(WARN, "fail to get each column group name", K(ret));
4117
  } else if (OB_FAIL(origin_table_schema.get_column_group_by_name(cg_name_str, ori_cg))) {
4118
    RS_LOG(WARN, "column group cannot get", K(cg_name_str), K(origin_table_schema));
4119
  } else if (OB_ISNULL(ori_cg)) {
4120
    ret = OB_ERR_UNEXPECTED;
4121
    RS_LOG(WARN, "column group should not be null", K(ret), K(cg_name_str),
4122
           KPC(orig_column_schema), K(origin_table_schema));
4123
  } else {
4124
    ObColumnGroupSchema new_cg;
4125
    if (OB_FAIL(new_cg.assign(*ori_cg))) {
4126
      RS_LOG(WARN, "fail to assign column group", K(ret), K(ori_cg));
4127
    } else {
4128
      new_cg.set_schema_version(column_schema.get_schema_version());
4129
      cg_name_str.set_length(0);
4130
      if (OB_FAIL(column_schema.get_each_column_group_name(cg_name_str))) {
4131
        RS_LOG(WARN, "fail to gen column group related column group name", K(ret), K(column_schema));
4132
      } else if (OB_FAIL(new_cg.set_column_group_name(cg_name_str))) {
4133
        RS_LOG(WARN, "fail to set column group name", K(ret), K(new_cg), K(cg_name_str));
4134
      } else if (OB_FAIL(schema_service_impl->get_table_sql_service().update_single_column_group(trans,
4135
                                                                                origin_table_schema,
4136
                                                                                *ori_cg,
4137
                                                                                new_cg))) {
4138
        RS_LOG(WARN,"fail to update single column_group", K(ret));
4139
      }
4140
    }
4141
  }
4142
  return ret;
4143
}
4144

4145
int ObDDLOperator::batch_update_system_table_columns(
4146
    common::ObMySQLTransaction &trans,
4147
    const share::schema::ObTableSchema &orig_table_schema,
4148
    share::schema::ObTableSchema &new_table_schema,
4149
    const common::ObIArray<uint64_t> &add_column_ids,
4150
    const common::ObIArray<uint64_t> &alter_column_ids,
4151
    const common::ObString *ddl_stmt_str/*=NULL*/)
4152
{
4153
  int ret = OB_SUCCESS;
4154
  const uint64_t tenant_id = new_table_schema.get_tenant_id();
4155
  const uint64_t table_id = new_table_schema.get_table_id();
4156
  int64_t new_schema_version = OB_INVALID_VERSION;
4157
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4158
  const bool update_object_status_ignore_version = false;
4159
  if (OB_ISNULL(schema_service_impl)) {
4160
    ret = OB_ERR_SYS;
4161
    LOG_WARN("schema_service_impl must not null", KR(ret));
4162
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4163
    LOG_WARN("fail to gen new schema_version", KR(ret), K(tenant_id));
4164
  } else {
4165
    (void) new_table_schema.set_schema_version(new_schema_version);
4166
    ObColumnSchemaV2 *new_column = NULL;
4167
    for (int64_t i = 0; OB_SUCC(ret) && i < add_column_ids.count(); i++) {
4168
      const uint64_t column_id = add_column_ids.at(i);
4169
      if (OB_ISNULL(new_column = new_table_schema.get_column_schema(column_id))) {
4170
        ret = OB_ERR_UNEXPECTED;
4171
        LOG_WARN("fail to get column", KR(ret), K(tenant_id), K(table_id), K(column_id));
4172
      } else if (FALSE_IT(new_column->set_schema_version(new_schema_version))) {
4173
      } else if (OB_FAIL(schema_service_impl->get_table_sql_service().insert_single_column(
4174
                 trans, new_table_schema, *new_column, false))) {
4175
        LOG_WARN("fail to insert column", KR(ret), K(tenant_id), K(table_id), K(column_id));
4176
      }
4177
    } // end for
4178

4179
    for (int64_t i = 0; OB_SUCC(ret) && i < alter_column_ids.count(); i++) {
4180
      const uint64_t column_id = alter_column_ids.at(i);
4181
      if (OB_ISNULL(new_column = new_table_schema.get_column_schema(column_id))) {
4182
        ret = OB_ERR_UNEXPECTED;
4183
        LOG_WARN("fail to get column", KR(ret), K(tenant_id), K(table_id), K(column_id));
4184
      } else if (FALSE_IT(new_column->set_schema_version(new_schema_version))) {
4185
      } else if (OB_FAIL(schema_service_impl->get_table_sql_service().update_single_column(
4186
                 trans, orig_table_schema, new_table_schema, *new_column, false))) {
4187
        LOG_WARN("fail to insert column", KR(ret), K(tenant_id), K(table_id), K(column_id));
4188
      }
4189
    } // end for
4190

4191
    if (FAILEDx(schema_service_impl->get_table_sql_service().update_table_attribute(
4192
        trans, new_table_schema, OB_DDL_ALTER_TABLE, update_object_status_ignore_version, ddl_stmt_str))) {
4193
      LOG_WARN("failed to update table attribute", KR(ret), K(tenant_id), K(table_id));
4194
    }
4195
  }
4196
  return ret;
4197
}
4198

4199
int ObDDLOperator::update_partition_option(common::ObMySQLTransaction &trans,
4200
                                           ObTableSchema &table_schema)
4201
{
4202
  int ret = OB_SUCCESS;
4203
  const uint64_t tenant_id = table_schema.get_tenant_id();
4204
  int64_t new_schema_version = OB_INVALID_VERSION;
4205
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4206
  if (OB_ISNULL(schema_service_impl)) {
4207
    ret = OB_ERR_SYS;
4208
    RS_LOG(WARN, "schema_service_impl must not null", K(ret));
4209
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4210
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4211
  } else {
4212
    if (OB_FAIL(schema_service_impl->get_table_sql_service().update_partition_option(
4213
        trans, table_schema, new_schema_version))) {
4214
      RS_LOG(WARN, "failed to update partition option", K(table_schema), K(ret));
4215
    }
4216
  }
4217
  return ret;
4218
}
4219

4220
int ObDDLOperator::update_check_constraint_state(common::ObMySQLTransaction &trans,
4221
                                                 const ObTableSchema &table_schema,
4222
                                                 ObConstraint &cst)
4223
{
4224
  int ret = OB_SUCCESS;
4225
  const uint64_t tenant_id = table_schema.get_tenant_id();
4226
  int64_t new_schema_version = OB_INVALID_VERSION;
4227
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4228
  if (OB_ISNULL(schema_service_impl)) {
4229
    ret = OB_ERR_SYS;
4230
    RS_LOG(WARN, "schema_service_impl must not null", K(ret));
4231
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4232
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4233
  } else {
4234
    cst.set_schema_version(new_schema_version);
4235
    if (OB_FAIL(schema_service_impl->get_table_sql_service().update_check_constraint_state(trans,
4236
                table_schema, cst))) {
4237
      RS_LOG(WARN, "failed to update check constraint state", K(table_schema), K(ret));
4238
    }
4239
  }
4240
  return ret;
4241
}
4242

4243
int ObDDLOperator::sync_aux_schema_version_for_history(common::ObMySQLTransaction &trans,
4244
                                                      const ObTableSchema &index_schema)
4245
{
4246
  int ret = OB_SUCCESS;
4247
  const uint64_t tenant_id = index_schema.get_tenant_id();
4248
  int64_t new_schema_version = OB_INVALID_VERSION;
4249
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4250
  if (OB_ISNULL(schema_service_impl)) {
4251
    ret = OB_ERR_SYS;
4252
    RS_LOG(WARN, "schema_service_impl must not null", K(ret));
4253
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4254
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4255
  } else {
4256
    if (OB_FAIL(schema_service_impl->get_table_sql_service().sync_aux_schema_version_for_history(
4257
                trans, index_schema, new_schema_version))) {
4258
      RS_LOG(WARN, "failed to update check constraint state", K(index_schema), K(ret));
4259
    }
4260
  }
4261
  return ret;
4262
}
4263

4264
int ObDDLOperator::drop_obj_privs(
4265
    const uint64_t tenant_id,
4266
    const uint64_t obj_id,
4267
    const uint64_t obj_type,
4268
    ObMySQLTransaction &trans,
4269
    ObMultiVersionSchemaService &schema_service,
4270
    ObSchemaGetterGuard &schema_guard)
4271
{
4272
  int ret = OB_SUCCESS;
4273
  ObSchemaService *schema_sql_service = schema_service.get_schema_service();
4274
  ObArray<const ObObjPriv *> obj_privs;
4275

4276
  CK (OB_NOT_NULL(schema_sql_service));
4277
  OZ (schema_guard.get_obj_priv_with_obj_id(tenant_id, obj_id, obj_type, obj_privs, true));
4278
  for (int64_t i = 0; OB_SUCC(ret) && i < obj_privs.count(); ++i) {
4279
    const ObObjPriv *obj_priv = obj_privs.at(i);
4280
    int64_t new_schema_version = OB_INVALID_VERSION;
4281

4282
    if (OB_ISNULL(obj_priv)) {
4283
      LOG_WARN("obj_priv priv is NULL", K(ret), K(obj_priv));
4284
    } else {
4285
      OZ (schema_service.gen_new_schema_version(tenant_id, new_schema_version));
4286
      OZ (schema_sql_service->get_priv_sql_service().delete_obj_priv(
4287
                *obj_priv, new_schema_version, trans));
4288
      // In order to prevent being deleted, but there is no time to refresh the schema.
4289
      // for example, obj priv has deleted, but obj schema unrefresh
4290
      if (ret == OB_SEARCH_NOT_FOUND) {
4291
        ret = OB_SUCCESS;
4292
      }
4293
    }
4294
  }
4295
  return ret;
4296
}
4297

4298

4299
int ObDDLOperator::drop_obj_privs(
4300
    const uint64_t tenant_id,
4301
    const uint64_t obj_id,
4302
    const uint64_t obj_type,
4303
    ObMySQLTransaction &trans)
4304
{
4305
  int ret = OB_SUCCESS;
4306
  ObSchemaGetterGuard schema_guard;
4307

4308
  OZ (schema_service_.get_tenant_schema_guard(tenant_id, schema_guard));
4309
  OZ (drop_obj_privs(tenant_id, obj_id, obj_type, trans, schema_service_, schema_guard));
4310

4311
  return ret;
4312
}
4313

4314
int ObDDLOperator::drop_tablet_of_table(
4315
    const ObTableSchema &table_schema,
4316
    ObMySQLTransaction &trans)
4317
{
4318
  int ret = OB_SUCCESS;
4319
  if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(GCTX.lst_operator_)) {
4320
    ret = OB_ERR_UNEXPECTED;
4321
    LOG_WARN("global variable is null", KR(ret), K(GCTX.srv_rpc_proxy_), K(GCTX.lst_operator_));
4322
  } else {
4323
    const uint64_t tenant_id = table_schema.get_tenant_id();
4324
    int64_t new_schema_version = OB_INVALID_VERSION;
4325
    ObSEArray<const ObTableSchema*, 1> schemas;
4326
    if (table_schema.is_vir_table()
4327
        || table_schema.is_view_table()
4328
        || is_inner_table(table_schema.get_table_id())) {
4329
      // skip
4330
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4331
      LOG_WARN("fail to gen new schema_version", KR(ret), K(tenant_id));
4332
    } else {
4333
      ObTabletDrop tablet_drop(tenant_id, trans, new_schema_version);
4334
      if (OB_FAIL(schemas.push_back(&table_schema))) {
4335
        LOG_WARN("failed to push_back", KR(ret), K(table_schema));
4336
      } else if (OB_FAIL(tablet_drop.init())) {
4337
        LOG_WARN("fail to init tablet drop", KR(ret), K(table_schema));
4338
      } else if (OB_FAIL(tablet_drop.add_drop_tablets_of_table_arg(schemas))) {
4339
        LOG_WARN("failed to add drop tablets", KR(ret), K(tenant_id), K(table_schema));
4340
      } else if (OB_FAIL(tablet_drop.execute())) {
4341
        LOG_WARN("failed to execute", KR(ret), K(schemas), K(table_schema));
4342
      }
4343
    }
4344
  }
4345
  return ret;
4346
}
4347

4348
int ObDDLOperator::drop_table(
4349
    const ObTableSchema &table_schema,
4350
    ObMySQLTransaction &trans,
4351
    const ObString *ddl_stmt_str/*=NULL*/,
4352
    const bool is_truncate_table/*false*/,
4353
    DropTableIdHashSet *drop_table_set/*=NULL*/,
4354
    const bool is_drop_db/*false*/)
4355
{
4356
  int ret = OB_SUCCESS;
4357
  bool tmp = false;
4358
  const uint64_t tenant_id = table_schema.get_tenant_id();
4359
  if (OB_FAIL(ObDependencyInfo::modify_dep_obj_status(trans, tenant_id, table_schema.get_table_id(),
4360
                                                      *this, schema_service_))) {
4361
    LOG_WARN("failed to modify obj status", K(ret));
4362
  } else if (OB_FAIL(drop_table_for_not_dropped_schema(
4363
              table_schema, trans, ddl_stmt_str, is_truncate_table,
4364
              drop_table_set, is_drop_db))) {
4365
    LOG_WARN("drop table for not dropped shema failed", K(ret));
4366
  } else if (table_schema.is_view_table()
4367
            && OB_FAIL(ObDependencyInfo::delete_schema_object_dependency(
4368
                      trans,
4369
                      tenant_id,
4370
                      table_schema.get_table_id(),
4371
                      table_schema.get_schema_version(),
4372
                      ObObjectType::VIEW))) {
4373
    LOG_WARN("failed to delete_schema_object_dependency", K(ret), K(tenant_id),
4374
    K(table_schema.get_table_id()));
4375
  }
4376

4377
  if (OB_FAIL(ret)) {
4378
  } else if ((table_schema.is_aux_table() || table_schema.is_mlog_table())
4379
      && !is_inner_table(table_schema.get_table_id())) {
4380
    ObSnapshotInfoManager snapshot_mgr;
4381
    ObArray<ObTabletID> tablet_ids;
4382
    SCN invalid_scn;
4383
    if (OB_FAIL(snapshot_mgr.init(GCTX.self_addr()))) {
4384
      LOG_WARN("fail to init snapshot mgr", K(ret));
4385
    } else if (OB_FAIL(table_schema.get_tablet_ids(tablet_ids))) {
4386
      LOG_WARN("fail to get tablet ids", K(ret));
4387
    // when a index or lob is dropped, it should release all snapshots acquired, otherwise
4388
    // if a building index is dropped in another session, the index build task cannot release snapshots
4389
    // because the task needs schema to know tablet ids.
4390
    } else if (OB_FAIL(snapshot_mgr.batch_release_snapshot_in_trans(
4391
            trans, SNAPSHOT_FOR_DDL, tenant_id, -1/*schema_version*/, invalid_scn/*snapshot_scn*/, tablet_ids))) {
4392
      LOG_WARN("fail to release ddl snapshot acquired by this table", K(ret));
4393
    }
4394
  }
4395

4396
  if (OB_FAIL(ret)) {
4397
  } else if (table_schema.is_external_table()) {
4398
    if (OB_FAIL(ObExternalTableFileManager::get_instance().clear_inner_table_files(
4399
                  table_schema.get_tenant_id(), table_schema.get_table_id(), trans))) {
4400
      LOG_WARN("delete external table file list failed", K(ret));
4401
    }
4402
  } else {
4403
    if (OB_FAIL(drop_tablet_of_table(table_schema, trans))) {
4404
      LOG_WARN("fail to drop tablet", K(table_schema), KR(ret));
4405
    }
4406
  }
4407

4408
  if (OB_SUCC(ret)) {
4409
    const uint64_t table_id = table_schema.get_table_id();
4410
    if (table_schema.is_materialized_view()) {
4411
      if (OB_FAIL(ObMViewSchedJobUtils::remove_mview_refresh_job(
4412
          trans, tenant_id, table_id))) {
4413
        LOG_WARN("failed to remove mview refresh job",
4414
            KR(ret), K(tenant_id), K(table_id));
4415
      }
4416
    } else if (table_schema.is_mlog_table()) {
4417
      if (OB_FAIL(ObMViewSchedJobUtils::remove_mlog_purge_job(
4418
          trans, tenant_id, table_id))) {
4419
        LOG_WARN("failed to remove mlog purge job",
4420
            KR(ret), K(tenant_id), K(table_id));
4421
      }
4422
    }
4423
  }
4424

4425
  return ret;
4426
}
4427

4428
int ObDDLOperator::drop_table_for_not_dropped_schema(
4429
    const ObTableSchema &table_schema,
4430
    ObMySQLTransaction &trans,
4431
    const ObString *ddl_stmt_str/*=NULL*/,
4432
    const bool is_truncate_table/*false*/,
4433
    DropTableIdHashSet *drop_table_set/*=NULL*/,
4434
    const bool is_drop_db/*false*/)
4435
{
4436
  int ret = OB_SUCCESS;
4437
  const uint64_t tenant_id = table_schema.get_tenant_id();
4438
  int64_t new_schema_version = OB_INVALID_VERSION;
4439
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4440
  ObSchemaGetterGuard schema_guard;
4441
  if (OB_ISNULL(schema_service_impl)) {
4442
    ret = OB_ERR_SYS;
4443
    LOG_ERROR("schema_service_impl must not null", K(ret));
4444
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
4445
    LOG_WARN("failed to get schema guard", K(ret));
4446
  }
4447
  //delete all object privileges granted on the object
4448
  uint64_t obj_type = static_cast<uint64_t>(ObObjectType::TABLE);
4449
  uint64_t table_id = table_schema.get_table_id();
4450
  if (OB_SUCC(ret) && !is_drop_db) {
4451
    OZ (drop_obj_privs(tenant_id, table_id, obj_type, trans),tenant_id, table_id, obj_type);
4452
  }
4453
  if (OB_FAIL(ret)) {
4454
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4455
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4456
  } else if (OB_FAIL(cleanup_autoinc_cache(table_schema))) {
4457
    LOG_WARN("fail cleanup auto inc global cache", K(ret));
4458
  } else if (OB_FAIL(drop_sequence_in_drop_table(table_schema, trans, schema_guard))) {
4459
    LOG_WARN("drop sequence in drop table fail", K(ret));
4460
  } else if (OB_FAIL(drop_rls_object_in_drop_table(table_schema, trans, schema_guard))) {
4461
    LOG_WARN("fail to drop rls object in drop table", K(ret));
4462
  } else if (OB_FAIL(schema_service_impl->get_table_sql_service().drop_table(
4463
                     table_schema,
4464
                     new_schema_version,
4465
                     trans,
4466
                     ddl_stmt_str,
4467
                     is_truncate_table,
4468
                     is_drop_db,
4469
                     &schema_guard,
4470
                     drop_table_set))) {
4471
    LOG_WARN("schema_service_impl drop_table failed", K(table_schema), K(ret));
4472
  } else if (OB_FAIL(sync_version_for_cascade_table(tenant_id, table_schema.get_base_table_ids(), trans))
4473
             || OB_FAIL(sync_version_for_cascade_table(tenant_id, table_schema.get_depend_table_ids(), trans))) {
4474
    LOG_WARN("fail to sync versin for cascade tables", K(ret), K(tenant_id),
4475
        K(table_schema.get_base_table_ids()), K(table_schema.get_depend_table_ids()));
4476
  } else if (OB_FAIL(sync_version_for_cascade_mock_fk_parent_table(table_schema.get_tenant_id(), table_schema.get_depend_mock_fk_parent_table_ids(), trans))) {
4477
    LOG_WARN("fail to sync cascade depend_mock_fk_parent_table_ids table", K(ret));
4478
  }
4479

4480
  // delete audit in table
4481
  if (OB_SUCC(ret) && (table_schema.is_user_table() || table_schema.is_external_table())) {
4482
    ObArray<const ObSAuditSchema *> audits;
4483
    if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
4484
                                                       AUDIT_TABLE,
4485
                                                       table_schema.get_table_id(),
4486
                                                       audits))) {
4487
      LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(table_schema), K(ret));
4488
    } else {
4489
      common::ObSqlString public_sql_string;
4490
      for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
4491
        const ObSAuditSchema *audit_schema = audits.at(i);
4492
        if (OB_ISNULL(audit_schema)) {
4493
          ret = OB_ERR_UNEXPECTED;
4494
          LOG_WARN("audit_schema is NULL", K(ret));
4495
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4496
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4497
        } else if (OB_FAIL(schema_service_impl->get_audit_sql_service().handle_audit_metainfo(
4498
            *audit_schema,
4499
            AUDIT_MT_DEL,
4500
            false,
4501
            new_schema_version,
4502
            NULL,
4503
            trans,
4504
            public_sql_string))) {
4505
          LOG_WARN("drop audit_schema failed",  KPC(audit_schema), K(ret));
4506
        }
4507
      }
4508
    }
4509
  }
4510
  return ret;
4511
}
4512

4513
// ref
4514
// When tables with auto-increment columns are frequently created or deleted, if the auto-increment column cache is not cleared, the memory will grow slowly.
4515
// so every time when you drop table, if you bring auto-increment columns, clean up the corresponding cache.
4516
int ObDDLOperator::cleanup_autoinc_cache(const ObTableSchema &table_schema)
4517
{
4518
  int ret = OB_SUCCESS;
4519
  ObAutoincrementService &autoinc_service = share::ObAutoincrementService::get_instance();
4520
  uint64_t tenant_id = table_schema.get_tenant_id();
4521
  bool is_restore = false;
4522
  if (OB_FAIL(schema_service_.check_tenant_is_restore(NULL, tenant_id, is_restore))) {
4523
    LOG_WARN("fail to check if tenant is restore", KR(ret), K(tenant_id));
4524
  } else if (is_restore) {
4525
    // bugfix:
4526
    // skip
4527
  } else if (0 != table_schema.get_autoinc_column_id()) {
4528
    uint64_t table_id = table_schema.get_table_id();
4529
    uint64_t autoinc_column_id = table_schema.get_autoinc_column_id();
4530
    LOG_INFO("begin to clear all auto-increment cache",
4531
             K(tenant_id), K(table_id), K(autoinc_column_id));
4532
    if (OB_FAIL(autoinc_service.clear_autoinc_cache_all(tenant_id,
4533
                                                        table_id,
4534
                                                        autoinc_column_id,
4535
                                                        table_schema.is_order_auto_increment_mode()))) {
4536
      LOG_WARN("failed to clear auto-increment cache",
4537
               K(tenant_id), K(table_id));
4538
    }
4539
  }
4540
  return ret;
4541
}
4542

4543
bool ObDDLOperator::is_aux_object(const ObDatabaseSchema &schema)
4544
{
4545
  UNUSED(schema);
4546
  return false;
4547
}
4548

4549
bool ObDDLOperator::is_aux_object(const ObTableSchema &schema)
4550
{
4551
  return schema.is_aux_table();
4552
}
4553

4554
bool ObDDLOperator::is_aux_object(const ObTriggerInfo &schema)
4555
{
4556
  UNUSED(schema);
4557
  return false;
4558
}
4559

4560
bool ObDDLOperator::is_aux_object(const ObTenantSchema &schema)
4561
{
4562
  UNUSED(schema);
4563
  return false;
4564
}
4565

4566
bool ObDDLOperator::is_global_index_object(const ObDatabaseSchema &schema)
4567
{
4568
  UNUSED(schema);
4569
  return false;
4570
}
4571

4572
bool ObDDLOperator::is_global_index_object(const ObTableSchema &schema)
4573
{
4574
  // For global local storage, local indexes are still seen, liboblog does not need to be synchronized
4575
  return schema.is_global_index_table() && (!schema.is_index_local_storage());
4576
}
4577

4578
bool ObDDLOperator::is_global_index_object(const ObTriggerInfo &schema)
4579
{
4580
  UNUSED(schema);
4581
  return false;
4582
}
4583

4584
bool ObDDLOperator::is_global_index_object(const ObTenantSchema &schema)
4585
{
4586
  UNUSED(schema);
4587
  return false;
4588
}
4589

4590
int ObDDLOperator::drop_table_to_recyclebin(const ObTableSchema &table_schema,
4591
                                            ObSchemaGetterGuard &schema_guard,
4592
                                            ObMySQLTransaction &trans,
4593
                                            const ObString *ddl_stmt_str,/*= NULL*/
4594
                                            const bool is_truncate_table)
4595
{
4596
  int ret = OB_SUCCESS;
4597
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
4598
  const uint64_t tenant_id = table_schema.get_tenant_id();
4599
  int64_t new_schema_version = OB_INVALID_VERSION;
4600
  bool recycle_db_exist = false;
4601
  // materialized view will not be dropped into recyclebin
4602
  if (table_schema.get_table_type() == MATERIALIZED_VIEW) {
4603
    LOG_WARN("bypass recyclebin for materialized view");
4604
  } else if (OB_UNLIKELY(table_schema.has_mlog_table())) {
4605
    ret = OB_ERR_UNEXPECTED;
4606
    LOG_WARN("table with materialized view log should not come to recyclebin", KR(ret));
4607
  } else if (OB_UNLIKELY(table_schema.get_table_type() == MATERIALIZED_VIEW_LOG)) {
4608
    ret = OB_ERR_UNEXPECTED;
4609
    LOG_WARN("materialized view log should not come to recyclebin", KR(ret));
4610
  } else if (OB_ISNULL(schema_service_impl)) {
4611
    ret = OB_ERR_UNEXPECTED;
4612
    LOG_ERROR("schema_service_impl must not null", K(ret));
4613
  } else if (OB_INVALID_ID == tenant_id) {
4614
    ret = OB_INVALID_ARGUMENT;
4615
    LOG_WARN("tenant_id is invalid", K(ret));
4616
  } else if (OB_FAIL(schema_guard.check_database_exist(tenant_id,
4617
                                                       OB_RECYCLEBIN_SCHEMA_ID,
4618
                                                       recycle_db_exist))) {
4619
    LOG_WARN("check database exist failed", K(ret), K(tenant_id));
4620
  } else if (!recycle_db_exist) {
4621
    ret = OB_ERR_UNEXPECTED;
4622
    LOG_WARN("__recyclebin db not exist", K(ret));
4623
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4624
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4625
  } else if (OB_FAIL(cleanup_autoinc_cache(table_schema))) {
4626
    LOG_WARN("fail cleanup auto inc global cache", K(ret));
4627
  } else if (OB_FAIL(ObDependencyInfo::modify_dep_obj_status(trans, tenant_id, table_schema.get_table_id(),
4628
                                                             *this, schema_service_))) {
4629
    LOG_WARN("failed to modify dep obj status", K(ret));
4630
  } else if (table_schema.is_view_table()
4631
            && OB_FAIL(ObDependencyInfo::delete_schema_object_dependency(
4632
                      trans,
4633
                      tenant_id,
4634
                      table_schema.get_table_id(),
4635
                      table_schema.get_schema_version(),
4636
                      ObObjectType::VIEW))) {
4637
    LOG_WARN("failed to delete_schema_object_dependency", K(ret), K(tenant_id),
4638
    K(table_schema.get_table_id()));
4639
  } else {
4640
    ObTableSchema new_table_schema;
4641
    if (OB_FAIL(new_table_schema.assign(table_schema))) {
4642
      LOG_WARN("fail to assign schema", K(ret));
4643
    } else {
4644
      ObSqlString new_table_name;
4645
      //move to the recyclebin db
4646
      new_table_schema.set_database_id(OB_RECYCLEBIN_SCHEMA_ID);
4647
      uint64_t tablegroup_id = table_schema.get_tablegroup_id();
4648
      if (OB_INVALID_ID != tablegroup_id) {
4649
        const ObTablegroupSchema *tablegroup_schema = nullptr;
4650
        if (OB_FAIL(schema_guard.get_tablegroup_schema(
4651
                tenant_id,
4652
                tablegroup_id,
4653
                tablegroup_schema))) {
4654
          LOG_WARN("get tablegroup schema failed", K(ret), K(tenant_id));
4655
        } else {
4656
          new_table_schema.set_tablegroup_id(OB_INVALID_ID);
4657
        }
4658
      }
4659
      new_table_schema.set_schema_version(new_schema_version);
4660
      ObSchemaOperationType op_type = OB_INVALID_DDL_OP;
4661
      if (OB_FAIL(ret)) {
4662
      } else if (OB_FAIL(construct_new_name_for_recyclebin(new_table_schema, new_table_name))) {
4663
        LOG_WARN("failed to construct new name for table", K(ret));
4664
      } else if (OB_FAIL(new_table_schema.set_table_name(new_table_name.string()))) {
4665
        LOG_WARN("failed to set new table name!", K(new_table_name), K(table_schema), K(ret));
4666
      } else {
4667
        ObRecycleObject recycle_object;
4668
        recycle_object.set_object_name(new_table_name.string());
4669
        recycle_object.set_original_name(table_schema.get_table_name_str());
4670
        recycle_object.set_tenant_id(table_schema.get_tenant_id());
4671
        recycle_object.set_database_id(table_schema.get_database_id());
4672
        recycle_object.set_table_id(table_schema.get_table_id());
4673
        recycle_object.set_tablegroup_id(table_schema.get_tablegroup_id());
4674
        op_type = table_schema.is_view_table()
4675
            ? OB_DDL_DROP_VIEW_TO_RECYCLEBIN : OB_DDL_DROP_TABLE_TO_RECYCLEBIN;
4676
        if (is_truncate_table) {
4677
          op_type = OB_DDL_TRUNCATE_DROP_TABLE_TO_RECYCLEBIN;
4678
        }
4679
        if (OB_FAIL(recycle_object.set_type_by_table_schema(table_schema))) {
4680
          LOG_WARN("set type by table schema failed", K(ret));
4681
        } else if (OB_FAIL(schema_service_impl->insert_recyclebin_object(recycle_object,
4682
                                                                         trans))) {
4683
          LOG_WARN("insert recycle object failed", K(ret));
4684
        }
4685
      }
4686
      if (OB_SUCC(ret)) {
4687
        if (OB_FAIL(schema_service_impl->get_table_sql_service().update_table_options(
4688
                    trans,
4689
                    table_schema,
4690
                    new_table_schema,
4691
                    op_type,
4692
                    ddl_stmt_str))) {
4693
          LOG_WARN("failed to alter table option!", K(ret));
4694
        }
4695
      }
4696
    }
4697
  }
4698
  return ret;
4699
}
4700

4701
int ObDDLOperator::flashback_table_from_recyclebin(const ObTableSchema &table_schema,
4702
                                                   ObTableSchema &new_table_schema,
4703
                                                   ObMySQLTransaction &trans,
4704
                                                   const uint64_t new_db_id,
4705
                                                   const ObString &new_table_name,
4706
                                                   const ObString *ddl_stmt_str,
4707
                                                   ObSchemaGetterGuard &guard)
4708
{
4709
  int ret = OB_SUCCESS;
4710
  ObSchemaService *schema_service = schema_service_.get_schema_service();
4711
  ObArray<ObRecycleObject> recycle_objs;
4712
  const uint64_t tenant_id = table_schema.get_tenant_id();
4713
  int64_t new_schema_version = OB_INVALID_VERSION;
4714
  ObRecycleObject::RecycleObjType recycle_type = ObRecycleObject::get_type_by_table_schema(table_schema);
4715
  ObArenaAllocator allocator(ObModIds::OB_SCHEMA);
4716
  if (OB_ISNULL(schema_service)) {
4717
    ret = OB_ERR_UNEXPECTED;
4718
    LOG_WARN("schema_service should not be null", K(ret));
4719
  } else if (OB_INVALID_ID == table_schema.get_tenant_id()) {
4720
    ret = OB_INVALID_ARGUMENT;
4721
    LOG_WARN("tenant_id is invalid", K(ret));
4722
  } else if (OB_FAIL(schema_service->fetch_recycle_object(
4723
      tenant_id,
4724
      table_schema.get_table_name_str(),
4725
      recycle_type,
4726
      trans,
4727
      recycle_objs))) {
4728
    LOG_WARN("get_recycle_object failed", K(tenant_id), K(ret));
4729
  } else if (recycle_objs.size() != 1) {
4730
    ret = OB_ERR_UNEXPECTED;
4731
    LOG_WARN("unexpected recycle object num", K(ret),
4732
             "table_name", table_schema.get_table_name_str(),
4733
             "size", recycle_objs.size());
4734
  } else {
4735
    const ObRecycleObject &recycle_obj = recycle_objs.at(0);
4736
    if (OB_FAIL(new_table_schema.assign(table_schema))) {
4737
      LOG_WARN("fail to assign schema", K(ret));
4738
    } else if (new_db_id != OB_INVALID_ID) {//flashback to new db
4739
      new_table_schema.set_database_id(new_db_id);
4740
      if (new_table_schema.is_aux_table()) {
4741
        // should set the old name
4742
        // When flashback table to new db, distinguish between empty index name and renaming flashback index
4743
        if (!new_table_name.empty() && OB_FAIL(new_table_schema.set_table_name(new_table_name))) {
4744
          LOG_WARN("set new table name failed", K(ret));
4745
        } else if (new_table_name.empty() && OB_FAIL(new_table_schema.set_table_name(recycle_obj.get_original_name()))) {
4746
          LOG_WARN("set new table name failed", K(ret));
4747
        } else if (new_table_schema.is_index_table()) {
4748
          const int VISIBLE = 0;
4749
          const uint64_t DROPINDEX = 0;
4750
          new_table_schema.set_drop_index(DROPINDEX);
4751
          if (!table_schema.is_invisible_before()) {
4752
            new_table_schema.set_index_visibility(VISIBLE);
4753
          }
4754
          new_table_schema.set_invisible_before(0);
4755
        }
4756
        if (OB_SUCC(ret) && new_table_schema.is_index_table()) {
4757
          bool is_oracle_mode = false;
4758
          if (OB_FAIL(new_table_schema.check_if_oracle_compat_mode(is_oracle_mode))) {
4759
            LOG_WARN("fail check if oracle mode", K(ret));
4760
          } else if (is_oracle_mode) {
4761
            ObString new_idx_name;
4762
            if (OB_FAIL(ObTableSchema::create_new_idx_name_after_flashback(new_table_schema,
4763
                                                                           new_idx_name,
4764
                                                                           allocator,
4765
                                                                           guard))) {
4766
            } else if (OB_FAIL(new_table_schema.set_table_name(new_idx_name))) {
4767
              LOG_WARN("set new table name failed", K(ret));
4768
            }
4769
          }
4770
        }
4771
      } else {
4772
        if (!new_table_name.empty()) {
4773
          if (OB_FAIL(new_table_schema.set_table_name(new_table_name))) {
4774
            LOG_WARN("set new table name failed", K(ret));
4775
          }
4776
        } else {
4777
          ret = OB_ERR_UNEXPECTED;
4778
          LOG_WARN("database is valid, but no table name for data table",
4779
                   K(ret), K(new_table_name));
4780
        }
4781
      }
4782
    } else {
4783
      //set original db_id
4784
      const ObDatabaseSchema *db_schema = NULL;
4785
      if (OB_FAIL(guard.get_database_schema(tenant_id,
4786
                                            recycle_obj.get_database_id(),
4787
                                            db_schema))) {
4788
        LOG_WARN("get database schema failed", K(ret));
4789
      } else if (NULL == db_schema) {
4790
        ret = OB_ERR_UNEXPECTED;
4791
        LOG_WARN("database not exist", K(recycle_obj), K(ret));
4792
      } else if (db_schema->is_in_recyclebin()) {
4793
        ret = OB_OP_NOT_ALLOW;
4794
        LOG_WARN("flashback table to __recyclebin database is not allowed",
4795
                 K(recycle_obj), K(*db_schema), K(ret));
4796
      } else if (OB_FAIL(new_table_schema.set_table_name(recycle_obj.get_original_name()))) {
4797
        LOG_WARN("set table name failed", K(ret), K(recycle_obj));
4798
      } else {
4799
        new_table_schema.set_database_id(recycle_obj.get_database_id());
4800
      }
4801

4802
      if (OB_SUCC(ret) && new_table_schema.is_index_table()) {
4803
        const int VISIBLE = 0;
4804
        const uint64_t DROPINDEX = 0;
4805
        new_table_schema.set_drop_index(DROPINDEX);
4806
        if (!table_schema.is_invisible_before()) {
4807
          new_table_schema.set_index_visibility(VISIBLE);
4808
        }
4809
        new_table_schema.set_invisible_before(0);
4810
      }
4811
      if (OB_SUCC(ret) && new_table_schema.is_index_table()) {
4812
        bool is_oracle_mode = false;
4813
        if (OB_FAIL(new_table_schema.check_if_oracle_compat_mode(is_oracle_mode))) {
4814
          LOG_WARN("fail check if oracle mode", K(ret));
4815
        } else if (is_oracle_mode) {
4816
          ObString new_idx_name;
4817
          if (OB_FAIL(ObTableSchema::create_new_idx_name_after_flashback(new_table_schema,
4818
                                                                         new_idx_name,
4819
                                                                         allocator,
4820
                                                                         guard))) {
4821
          } else if (OB_FAIL(new_table_schema.set_table_name(new_idx_name))) {
4822
            LOG_WARN("set new table name failed", K(ret));
4823
          }
4824
        }
4825
      }
4826
    }
4827
    if (OB_SUCC(ret)) {
4828
      bool is_table_exist = true;
4829
      bool object_exist = false;
4830
      uint64_t synonym_id = OB_INVALID_ID;
4831
      const int64_t table_schema_version = OB_INVALID_VERSION; // Take the latest local schema_guard
4832
      ObSchemaOperationType op_type = new_table_schema.is_view_table()
4833
          ? OB_DDL_FLASHBACK_VIEW : OB_DDL_FLASHBACK_TABLE;
4834
      if (new_table_schema.is_index_table()) {
4835
        op_type = OB_DDL_FLASHBACK_INDEX;
4836
      }
4837
      if (OB_FAIL(schema_service_.check_synonym_exist(tenant_id,
4838
                                                       new_table_schema.get_database_id(),
4839
                                                       new_table_schema.get_table_name_str(),
4840
                                                       object_exist,
4841
                                                       synonym_id))) {
4842
        LOG_WARN("fail to check synonym exist", K(new_table_schema), K(ret));
4843
      } else if (object_exist) {
4844
        ret = OB_ERR_EXIST_OBJECT;
4845
        LOG_WARN("Name is already used by an existing object", K(new_table_schema), K(ret));
4846
      } else if (OB_FAIL(schema_service_.check_table_exist(tenant_id,
4847
                                                           new_table_schema.get_database_id(),
4848
                                                           new_table_schema.get_table_name_str(),
4849
                                                           new_table_schema.is_index_table(),
4850
                                                           table_schema_version,
4851
                                                           is_table_exist))) {
4852
        LOG_WARN("check_table exist failed", K(ret));
4853
      } else if (is_table_exist) {
4854
        ret = OB_ERR_TABLE_EXIST;
4855
        LOG_USER_ERROR(OB_ERR_TABLE_EXIST, recycle_obj.get_original_name().length(),
4856
                       recycle_obj.get_original_name().ptr());
4857
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
4858
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
4859
      } else if (FALSE_IT(new_table_schema.set_schema_version(new_schema_version))) {
4860
      } else if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
4861
          trans,
4862
          table_schema,
4863
          new_table_schema,
4864
          op_type,
4865
          ddl_stmt_str))) {
4866
        LOG_WARN("update_table_options failed", K(ret));
4867
      } else if (OB_FAIL(schema_service->delete_recycle_object(tenant_id,
4868
                                                               recycle_obj,
4869
                                                               trans))) {
4870
        LOG_WARN("delete_recycle_object failed", K(tenant_id), K(ret));
4871
      }
4872
    }
4873
  }
4874
  return ret;
4875
}
4876

4877
int ObDDLOperator::purge_table_with_aux_table(
4878
    const ObTableSchema &table_schema,
4879
    ObSchemaGetterGuard &schema_guard,
4880
    ObMySQLTransaction &trans,
4881
    const ObString *ddl_stmt_str)
4882
{
4883
  int ret = OB_SUCCESS;
4884
  if (!table_schema.is_aux_table()) {
4885
    if (OB_FAIL(purge_aux_table(table_schema, schema_guard, trans, USER_INDEX))) {
4886
      LOG_WARN("purge_aux_table failed", K(ret), K(table_schema));
4887
    } else if (OB_FAIL(purge_aux_table(table_schema, schema_guard, trans,
4888
                                       AUX_VERTIAL_PARTITION_TABLE))) {
4889
      LOG_WARN("purge_aux_table failed", K(ret), K(table_schema));
4890
    } else if (OB_FAIL(purge_aux_table(table_schema, schema_guard, trans,
4891
                                       AUX_LOB_META))) {
4892
      LOG_WARN("purge_aux_lob_meta_table failed", K(ret), K(table_schema));
4893
    } else if (OB_FAIL(purge_aux_table(table_schema, schema_guard, trans,
4894
                                       AUX_LOB_PIECE))) {
4895
      LOG_WARN("purge_aux_lob_piece_table failed", K(ret), K(table_schema));
4896
    } else if (OB_FAIL(purge_table_trigger(table_schema, schema_guard, trans))) {
4897
      LOG_WARN("purge_trigger failed", K(ret), K(table_schema));
4898
    }
4899
  }
4900
  if (OB_SUCC(ret)) {
4901
    if (OB_FAIL(purge_table_in_recyclebin(table_schema,
4902
                                          trans,
4903
                                          ddl_stmt_str))) {
4904
      LOG_WARN("purge table failed", K(ret));
4905
    }
4906
  }
4907
  return ret;
4908
}
4909

4910
int ObDDLOperator::purge_aux_table(
4911
    const ObTableSchema &table_schema,
4912
    ObSchemaGetterGuard &schema_guard,
4913
    ObMySQLTransaction &trans,
4914
    const ObTableType table_type)
4915
{
4916
  int ret = OB_SUCCESS;
4917
  const uint64_t tenant_id = table_schema.get_tenant_id();
4918
  ObSEArray<uint64_t, 16> aux_tid_array; // for aux_vp or aux_lob
4919
  ObSEArray<ObAuxTableMetaInfo, 16> simple_index_infos;
4920
  bool is_index = false;
4921
  if (USER_INDEX == table_type) {
4922
    is_index = true;
4923
    if (OB_FAIL(table_schema.get_simple_index_infos(simple_index_infos))) {
4924
      LOG_WARN("get_simple_index_infos failed", K(ret), K(table_schema));
4925
    }
4926
  } else if (AUX_LOB_META == table_type) {
4927
    const uint64_t aux_lob_meta_tid = table_schema.get_aux_lob_meta_tid();
4928
    if (OB_INVALID_ID != aux_lob_meta_tid && OB_FAIL(aux_tid_array.push_back(aux_lob_meta_tid))) {
4929
      LOG_WARN("push back aux_lob_meta_tid failed", K(ret));
4930
    }
4931
  } else if (AUX_LOB_PIECE == table_type) {
4932
    const uint64_t aux_lob_piece_tid = table_schema.get_aux_lob_piece_tid();
4933
    if (OB_INVALID_ID != aux_lob_piece_tid && OB_FAIL(aux_tid_array.push_back(aux_lob_piece_tid))) {
4934
      LOG_WARN("push back aux_lob_piece_tid failed", K(ret));
4935
    }
4936
  } else if (AUX_VERTIAL_PARTITION_TABLE == table_type) {
4937
    if (OB_FAIL(table_schema.get_aux_vp_tid_array(aux_tid_array))) {
4938
      LOG_WARN("get_aux_vp_tid_array failed", K(ret), K(table_schema));
4939
    }
4940
  } else {
4941
    ret = OB_INVALID_ARGUMENT;
4942
    LOG_WARN("invalid table type", K(ret), K(table_type));
4943
  }
4944

4945
  int64_t N = is_index ? simple_index_infos.count() : aux_tid_array.count();
4946
  for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) {
4947
    const ObTableSchema *aux_table_schema = NULL;
4948
    uint64_t tid = is_index ? simple_index_infos.at(i).table_id_ : aux_tid_array.at(i);
4949
    if (OB_FAIL(schema_guard.get_table_schema(tenant_id, tid, aux_table_schema))) {
4950
      LOG_WARN("get_table_schema failed", K(tenant_id), "table id", tid, K(ret));
4951
    } else if (OB_ISNULL(aux_table_schema)) {
4952
      ret = OB_ERR_UNEXPECTED;
4953
      LOG_WARN("table schema should not be null", K(ret));
4954
    } else if (OB_FAIL(purge_table_in_recyclebin(*aux_table_schema,
4955
                                                 trans,
4956
                                                 NULL /*ddl_stmt_str*/))) {
4957
      LOG_WARN("ddl_operator drop_table failed", K(*aux_table_schema), K(ret));
4958
    }
4959
  }
4960

4961
  return ret;
4962
}
4963

4964
int ObDDLOperator::purge_table_in_recyclebin(const ObTableSchema &table_schema,
4965
                                             ObMySQLTransaction &trans,
4966
                                             const ObString *ddl_stmt_str/*=NULL*/)
4967
{
4968
  int ret = OB_SUCCESS;
4969
  ObSchemaService *schema_service = schema_service_.get_schema_service();
4970
  ObArray<ObRecycleObject> recycle_objs;
4971
  ObRecycleObject::RecycleObjType recycle_type = ObRecycleObject::get_type_by_table_schema(table_schema);
4972

4973
  if (OB_ISNULL(schema_service)) {
4974
    ret = OB_ERR_UNEXPECTED;
4975
    LOG_WARN("schema_service should not be null", K(ret));
4976
  } else if (OB_INVALID_ID == table_schema.get_tenant_id()) {
4977
    ret = OB_INVALID_ARGUMENT;
4978
    LOG_WARN("tenant_id is invalid", K(ret));
4979
  } else if (OB_FAIL(schema_service->fetch_recycle_object(
4980
             table_schema.get_tenant_id(),
4981
             table_schema.get_table_name_str(),
4982
             recycle_type,
4983
             trans,
4984
             recycle_objs))) {
4985
    LOG_WARN("get_recycle_object failed", K(recycle_type), K(ret));
4986
  } else if (recycle_objs.size() != 1) {
4987
    ret = OB_ERR_UNEXPECTED;
4988
    LOG_WARN("unexpected recycle object num", K(ret), K(recycle_objs.size()));
4989
  } else if (OB_FAIL(schema_service->delete_recycle_object(
4990
             table_schema.get_tenant_id(),
4991
             recycle_objs.at(0),
4992
             trans))) {
4993
    LOG_WARN("delete_recycle_object failed", K(ret), "ObRecycleObject", recycle_objs.at(0));
4994
  } else if (OB_FAIL(drop_table(table_schema, trans, ddl_stmt_str, false))) {
4995
    LOG_WARN("drop table failed", K(ret));
4996
  }
4997
  return ret;
4998
}
4999

5000
int ObDDLOperator::create_index_in_recyclebin(ObTableSchema &table_schema,
5001
                                              ObSchemaGetterGuard &schema_guard,
5002
                                              ObMySQLTransaction &trans,
5003
                                              const ObString *ddl_stmt_str) {
5004
  int ret = OB_SUCCESS;
5005

5006
  if (table_schema.get_table_type() != USER_INDEX) {
5007
    ret = OB_ERR_UNEXPECTED;
5008
    LOG_WARN("table_schema type is not index", K(ret));
5009
  } else {
5010
    ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
5011
    uint64_t tenant_id = table_schema.get_tenant_id();
5012
    int64_t new_schema_version = OB_INVALID_VERSION;
5013
    bool recycle_db_exist = false;
5014
    if (OB_ISNULL(schema_service_impl)) {
5015
      ret = OB_ERR_UNEXPECTED;
5016
      LOG_ERROR("schema_service_impl must not be null", K(ret));
5017
    } else if (OB_FAIL(schema_guard.check_database_exist(tenant_id,
5018
               OB_RECYCLEBIN_SCHEMA_ID, recycle_db_exist))) {
5019
      LOG_WARN("check database exist failed", K(ret));
5020
    } else if (!recycle_db_exist) {
5021
      ret = OB_ERR_UNEXPECTED;
5022
      LOG_WARN("__recyclebin db not exist", K(ret));
5023
    } else {
5024
      ObSqlString new_table_name;
5025
      ObTableSchema new_table_schema;
5026
      if (OB_FAIL(new_table_schema.assign(table_schema))) {
5027
        LOG_WARN("fail to assign schema", K(ret));
5028
      } else {
5029
        new_table_schema.set_database_id(OB_RECYCLEBIN_SCHEMA_ID);
5030
        new_table_schema.set_tablegroup_id(OB_INVALID_ID);
5031
      }
5032
      if (OB_FAIL(ret)) {
5033
      } else if (OB_FAIL(construct_new_name_for_recyclebin(table_schema, new_table_name))) {
5034
        LOG_WARN("failed to construct new name for table", K(ret));
5035
      } else if (OB_FAIL(new_table_schema.set_table_name(new_table_name.string()))) {
5036
        LOG_WARN("failed to set new table name!", K(new_table_name), K(table_schema), K(ret));
5037
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5038
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5039
      } else {
5040
        new_table_schema.set_schema_version(new_schema_version);
5041
        ObRecycleObject recycle_object;
5042
        recycle_object.set_object_name(new_table_name.string());
5043
        recycle_object.set_original_name(table_schema.get_table_name_str());
5044
        recycle_object.set_tenant_id(tenant_id);
5045
        recycle_object.set_database_id(table_schema.get_database_id());
5046
        recycle_object.set_table_id(table_schema.get_table_id());
5047
        recycle_object.set_tablegroup_id(table_schema.get_tablegroup_id());
5048
        if (OB_FAIL(recycle_object.set_type_by_table_schema(table_schema))) {
5049
          LOG_WARN("set type by table schema failed", K(ret));
5050
        } else if (OB_FAIL(schema_service_impl->insert_recyclebin_object(recycle_object,
5051
                trans))) {
5052
          LOG_WARN("insert recycle object failed", K(ret));
5053
        } else if (OB_FAIL(schema_service_impl->get_table_sql_service().create_table(
5054
                new_table_schema,
5055
                trans,
5056
                ddl_stmt_str,
5057
                true,
5058
                true))) {
5059
          LOG_WARN("failed to create table in recyclebin", K(ret));
5060
        } else if (OB_FAIL(sync_version_for_cascade_table(
5061
                   tenant_id, new_table_schema.get_depend_table_ids(), trans))) {
5062
          LOG_WARN("fail to sync cascade depend table", K(ret));
5063
        }
5064
      }
5065
    }
5066
  }
5067
  return ret;
5068
}
5069

5070
int ObDDLOperator::update_tablegroup_id_of_tables(const ObDatabaseSchema &database_schema,
5071
                                                  ObMySQLTransaction &trans,
5072
                                                  ObSchemaGetterGuard &schema_guard)
5073
{
5074
  int ret = OB_SUCCESS;
5075
  const uint64_t tenant_id = database_schema.get_tenant_id();
5076
  int64_t new_schema_version = OB_INVALID_VERSION;
5077
  ObArray<const ObTableSchema*> table_schemas;
5078
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5079
  if (OB_FAIL(schema_guard.get_table_schemas_in_database(tenant_id,
5080
                                                         database_schema.get_database_id(),
5081
                                                         table_schemas))) {
5082
    LOG_WARN("get_table_schemas_in_database failed", K(ret), K(tenant_id));
5083
  }
5084
  bool tg_exist = false;
5085
  for (int64_t idx = 0; OB_SUCC(ret) && idx < table_schemas.count(); ++idx) {
5086
    const ObTableSchema *table = table_schemas.at(idx);
5087
    if (OB_ISNULL(table)) {
5088
      ret = OB_ERR_UNEXPECTED;
5089
      LOG_WARN("table schema should not be null", K(ret));
5090
    } else if (table->is_index_table()) {
5091
      continue;
5092
    } else if (OB_INVALID_ID != table->get_tablegroup_id() &&
5093
        OB_FAIL(schema_guard.check_tablegroup_exist(table->get_tenant_id(),
5094
                                                    table->get_tablegroup_id(), tg_exist))) {
5095
      LOG_WARN("check_tablegroup_exist failed", K(ret), KPC(table));
5096
    } else {
5097
      ObSEArray<ObAuxTableMetaInfo, 16> simple_index_infos;
5098
      if (OB_FAIL(table->get_simple_index_infos(simple_index_infos))) {
5099
        LOG_WARN("get_index_tid_array failed", K(ret));
5100
      }
5101
      for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
5102
        const ObTableSchema *index_table_schema = NULL;
5103
        if (OB_FAIL(schema_guard.get_table_schema(tenant_id,
5104
            simple_index_infos.at(i).table_id_, index_table_schema))) {
5105
          LOG_WARN("get_table_schema failed", K(tenant_id),
5106
                   "table id", simple_index_infos.at(i).table_id_, K(ret));
5107
        } else if (OB_ISNULL(index_table_schema)) {
5108
          ret = OB_ERR_UNEXPECTED;
5109
          LOG_WARN("table schema should not be null", K(ret));
5110
        } else {
5111
          ObTableSchema new_index_schema;
5112
          if (OB_FAIL(new_index_schema.assign(*index_table_schema))) {
5113
            LOG_WARN("fail to assign schema", K(ret));
5114
          } else {
5115
            if (!tg_exist) {
5116
              new_index_schema.set_tablegroup_id(OB_INVALID_ID);
5117
            }
5118
            if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5119
              LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5120
            } else if (FALSE_IT(new_index_schema.set_schema_version(new_schema_version))) {
5121
            } else if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
5122
                trans, *index_table_schema, new_index_schema,
5123
                OB_DDL_FLASHBACK_TABLE, NULL))) {
5124
              LOG_WARN("update_table_option failed", K(ret));
5125
            }
5126
          }
5127
        }
5128
      }
5129
      if (OB_SUCC(ret)) {
5130
        HEAP_VAR(ObTableSchema, new_ts) {
5131
          if (OB_FAIL(new_ts.assign(*table))) {
5132
            LOG_WARN("fail to assign schema", K(ret));
5133
          } else {
5134
            if (!tg_exist) {
5135
              new_ts.set_tablegroup_id(OB_INVALID_ID);
5136
            }
5137
            const ObSchemaOperationType op_type = new_ts.is_view_table()
5138
                ? OB_DDL_FLASHBACK_VIEW : OB_DDL_FLASHBACK_TABLE;
5139
            if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5140
                LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5141
            } else if (FALSE_IT(new_ts.set_schema_version(new_schema_version))) {
5142
            } else if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(
5143
                trans, *table, new_ts, op_type, NULL))) {
5144
              LOG_WARN("update_table_option failed", K(ret));
5145
            }
5146
          }
5147
        }
5148
      }
5149
    }
5150
  }
5151
  return ret;
5152
}
5153

5154
int ObDDLOperator::flashback_database_from_recyclebin(const ObDatabaseSchema &database_schema,
5155
                                                      ObMySQLTransaction &trans,
5156
                                                      const ObString &new_db_name,
5157
                                                      ObSchemaGetterGuard &schema_guard,
5158
                                                      const ObString &ddl_stmt_str)
5159
{
5160
  int ret = OB_SUCCESS;
5161
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5162
  ObArray<ObRecycleObject> recycle_objs;
5163
  if (OB_ISNULL(schema_service)) {
5164
    ret = OB_ERR_UNEXPECTED;
5165
    LOG_WARN("schema_service should not be null", K(ret));
5166
  } else if (OB_INVALID_ID == database_schema.get_tenant_id()) {
5167
    ret = OB_INVALID_ARGUMENT;
5168
    LOG_WARN("tenant_id is invalid", K(ret));
5169
  } else if (OB_FAIL(schema_service->fetch_recycle_object(
5170
      database_schema.get_tenant_id(),
5171
      database_schema.get_database_name(),
5172
      ObRecycleObject::DATABASE,
5173
      trans,
5174
      recycle_objs))) {
5175
    LOG_WARN("get_recycle_object failed", K(ret));
5176
  } else if (recycle_objs.size() != 1) {
5177
    ret = OB_ERR_UNEXPECTED;
5178
    LOG_WARN("unexpected recycle object num", K(ret));
5179
  } else {
5180
    const ObRecycleObject &recycle_obj = recycle_objs.at(0);
5181
    uint64_t tg_id = OB_INVALID_ID;
5182
    if (OB_INVALID_ID != recycle_obj.get_tablegroup_id()) {
5183
      bool tg_exist = false;
5184
      if (OB_FAIL(schema_guard.check_tablegroup_exist(recycle_obj.get_tenant_id(),
5185
                                                      recycle_obj.get_tablegroup_id(),
5186
                                                      tg_exist))) {
5187
        LOG_WARN("check_tablegroup_exist failed", K(ret), K(recycle_obj));
5188
      } else if (tg_exist) {
5189
        tg_id = recycle_obj.get_tablegroup_id();
5190
      }
5191
    }
5192
    if (OB_SUCC(ret)) {
5193
      ObDatabaseSchema new_db_schema = database_schema;
5194
      new_db_schema.set_in_recyclebin(false);
5195
      new_db_schema.set_default_tablegroup_id(tg_id);
5196
      if (!new_db_name.empty()) {
5197
        if (OB_FAIL(new_db_schema.set_database_name(new_db_name))) {
5198
          LOG_WARN("set database name failed", K(new_db_name));
5199
        }
5200
      } else {
5201
        //set original db_id
5202
        if (OB_FAIL(new_db_schema.set_database_name(recycle_obj.get_original_name()))) {
5203
          LOG_WARN("set database name failed", K(recycle_obj));
5204
        }
5205
      }
5206
      if (OB_SUCC(ret)) {
5207
        bool is_database_exist = true;
5208
        const uint64_t tenant_id = database_schema.get_tenant_id();
5209
        int64_t new_schema_version = OB_INVALID_VERSION;
5210
        if (OB_FAIL(schema_guard.check_database_exist(database_schema.get_tenant_id(),
5211
                                                      new_db_schema.get_database_name_str(),
5212
                                                      is_database_exist))) {
5213
          LOG_WARN("check database exist failed", K(ret), K(new_db_schema));
5214
        } else if (is_database_exist) {
5215
          ret = OB_DATABASE_EXIST;
5216
          LOG_USER_ERROR(OB_DATABASE_EXIST, new_db_schema.get_database_name_str().length(),
5217
                         new_db_schema.get_database_name_str().ptr());
5218
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5219
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5220
        } else if (FALSE_IT(new_db_schema.set_schema_version(new_schema_version))) {
5221
        } else if (OB_FAIL(schema_service->get_database_sql_service().update_database(
5222
            new_db_schema,
5223
            trans,
5224
            OB_DDL_FLASHBACK_DATABASE,
5225
            &ddl_stmt_str))) {
5226
          LOG_WARN("update_database failed", K(ret), K(new_db_schema));
5227
        } else if (OB_FAIL(schema_service->delete_recycle_object(
5228
            database_schema.get_tenant_id(),
5229
            recycle_obj,
5230
            trans))) {
5231
          LOG_WARN("delete_recycle_object failed", K(ret), K(recycle_obj));
5232
        }
5233
      }
5234
    }
5235
    if (OB_SUCC(ret)) {
5236
      if (OB_FAIL(update_tablegroup_id_of_tables(database_schema, trans, schema_guard))) {
5237
        LOG_WARN("update tablegroup_id of tables failed", K(database_schema), K(ret));
5238
      }
5239
    }
5240
  }
5241
  return ret;
5242
}
5243

5244
int ObDDLOperator::purge_table_of_database(const ObDatabaseSchema &db_schema,
5245
                                           ObMySQLTransaction &trans)
5246
{
5247
  int ret = OB_SUCCESS;
5248
  ObSchemaGetterGuard schema_guard;
5249
  const uint64_t tenant_id = db_schema.get_tenant_id();
5250
  const uint64_t database_id = db_schema.get_database_id();
5251
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5252
  if (OB_ISNULL(schema_service)) {
5253
    ret = OB_ERR_UNEXPECTED;
5254
    LOG_WARN("schema_service should not be null", K(ret));
5255
  } else {
5256
    ObArray<ObRecycleObject> recycle_objs;
5257
    if (OB_FAIL(schema_service->fetch_recycle_objects_of_db(tenant_id,
5258
                                                            database_id,
5259
                                                            trans,
5260
                                                            recycle_objs))) {
5261
      LOG_WARN("fetch recycle objects of db failed", K(ret));
5262
    } else {
5263
      for (int i = 0; OB_SUCC(ret) && i < recycle_objs.count(); ++i) {
5264
        const ObRecycleObject &recycle_obj = recycle_objs.at(i);
5265
        const ObTableSchema* table_schema = NULL;
5266
        if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
5267
          LOG_WARN("failed to get schema guard", K(ret));
5268
        } else if (OB_FAIL(schema_guard.get_table_schema(recycle_obj.get_tenant_id(),
5269
                                                         recycle_obj.get_table_id(),
5270
                                                         table_schema))) {
5271
          LOG_WARN("fail to get table_schema", KR(ret), K(recycle_obj));
5272
        } else if (OB_ISNULL(table_schema)) {
5273
          ret = OB_TABLE_NOT_EXIST;
5274
          LOG_WARN("table is not exist", K(ret), K(recycle_obj));
5275
          LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(db_schema.get_database_name_str()),
5276
                         to_cstring(recycle_obj.get_object_name()));
5277
        } else if (OB_FAIL(purge_table_with_aux_table(*table_schema,
5278
                                                      schema_guard,
5279
                                                      trans,
5280
                                                      NULL /*ddl_stmt_str */))) {
5281
          LOG_WARN("purge table with index failed", K(ret), K(recycle_obj));
5282
        }
5283
      }
5284
    }
5285
  }
5286
  return ret;
5287
}
5288

5289
int ObDDLOperator::purge_database_in_recyclebin(const ObDatabaseSchema &database_schema,
5290
                                                ObMySQLTransaction &trans,
5291
                                                const ObString *ddl_stmt_str)
5292
{
5293
  int ret = OB_SUCCESS;
5294
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5295
  if (OB_ISNULL(schema_service)) {
5296
    ret = OB_ERR_UNEXPECTED;
5297
    LOG_WARN("schema_service should not be null", K(ret));
5298
  } else if (OB_INVALID_ID == database_schema.get_tenant_id()) {
5299
    ret = OB_INVALID_ARGUMENT;
5300
    LOG_WARN("tenant_id is invalid", K(ret));
5301
  } else {
5302
    ObArray<ObRecycleObject> recycle_objs;
5303
    if (OB_FAIL(schema_service->fetch_recycle_object(
5304
       database_schema.get_tenant_id(),
5305
       database_schema.get_database_name_str(),
5306
       ObRecycleObject::DATABASE,
5307
       trans,
5308
       recycle_objs))) {
5309
       LOG_WARN("get_recycle_object failed", K(ret));
5310
     } else if (1 != recycle_objs.size()) {
5311
       ret = OB_ERR_UNEXPECTED;
5312
       LOG_WARN("unexpected recycle object num", K(ret));
5313
     } else if (OB_FAIL(drop_database(database_schema,
5314
                                      trans,
5315
                                      ddl_stmt_str))) {
5316
       LOG_WARN("drop_table failed", K(ret));
5317
     } else if (OB_FAIL(schema_service->delete_recycle_object(
5318
         database_schema.get_tenant_id(),
5319
         recycle_objs.at(0),
5320
         trans))) {
5321
       LOG_WARN("delete_recycle_object failed", K(ret));
5322
     }
5323
  }
5324
  return ret;
5325
}
5326

5327
int ObDDLOperator::fetch_expire_recycle_objects(
5328
    const uint64_t tenant_id,
5329
    const int64_t expire_time,
5330
    ObIArray<ObRecycleObject> &recycle_objs)
5331
{
5332
  int ret = OB_SUCCESS;
5333
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5334
  if (OB_ISNULL(schema_service)) {
5335
    ret = OB_ERR_UNEXPECTED;
5336
    LOG_WARN("schema_service should not be null", K(ret));
5337
  } else if (OB_FAIL(schema_service->fetch_expire_recycle_objects(tenant_id,
5338
                                                          expire_time,
5339
                                                          sql_proxy_,
5340
                                                          recycle_objs))) {
5341
    LOG_WARN("fetch expire recycle objects failed", K(ret),
5342
             K(expire_time), K(tenant_id));
5343
  }
5344
  return ret;
5345
}
5346

5347
int ObDDLOperator::init_tenant_env(
5348
    const ObTenantSchema &tenant_schema,
5349
    const ObSysVariableSchema &sys_variable,
5350
    const share::ObTenantRole &tenant_role,
5351
    const SCN &recovery_until_scn,
5352
    const common::ObIArray<common::ObConfigPairs> &init_configs,
5353
    ObMySQLTransaction &trans)
5354
{
5355
  int ret = OB_SUCCESS;
5356
  const uint64_t tenant_id = tenant_schema.get_tenant_id();
5357

5358
  if (OB_UNLIKELY(!recovery_until_scn.is_valid_and_not_min())) {
5359
    ret = OB_INVALID_ARGUMENT;
5360
    LOG_WARN("invalid recovery_until_scn", KR(ret), K(recovery_until_scn));
5361
  } else if (OB_FAIL(init_tenant_tablegroup(tenant_id, trans))) {
5362
    LOG_WARN("insert default tablegroup failed", K(tenant_id), K(ret));
5363
  } else if (OB_FAIL(init_tenant_databases(tenant_schema, sys_variable, trans))) {
5364
    LOG_WARN("insert default databases failed,", K(tenant_id), K(ret));
5365
  } else if (OB_FAIL(init_tenant_profile(tenant_id, sys_variable, trans))) {
5366
    LOG_WARN("fail to init tenant profile", K(tenant_id), K(ret));
5367
  } else if (OB_FAIL(init_tenant_users(tenant_schema, sys_variable, trans))) {
5368
    LOG_WARN("insert default user failed", K(tenant_id), K(ret));
5369
  } else if (OB_FAIL(init_tenant_keystore(tenant_id, sys_variable, trans))) {
5370
    LOG_WARN("fail to init tenant keystore", K(ret));
5371
  } else if (OB_FAIL(init_tenant_sys_stats(tenant_id, trans))) {
5372
    LOG_WARN("insert default sys stats failed", K(tenant_id), K(ret));
5373
  } else if (OB_FAIL(init_freeze_info(tenant_id, trans))) {
5374
    LOG_WARN("insert freeze info failed", K(tenant_id), KR(ret));
5375
  } else if (OB_FAIL(init_tenant_srs(tenant_id, trans))) {
5376
    LOG_WARN("insert tenant srs failed", K(tenant_id), K(ret));
5377
  } else if (OB_SYS_TENANT_ID == tenant_id) {
5378
    if (OB_FAIL(init_sys_tenant_charset(trans))) {
5379
      LOG_WARN("insert charset failed", K(tenant_id), K(ret));
5380
    } else if (OB_FAIL(init_sys_tenant_collation(trans))) {
5381
      LOG_WARN("insert collation failed", K(tenant_id), K(ret));
5382
    } else if (OB_FAIL(init_sys_tenant_privilege(trans))) {
5383
      LOG_WARN("insert privilege failed", K(tenant_id), K(ret));
5384
    }
5385
    //TODO [profile]
5386
  }
5387
  if (OB_SUCC(ret) && !is_user_tenant(tenant_id)) {
5388
    uint64_t user_tenant_id = gen_user_tenant_id(tenant_id);
5389
    if (OB_FAIL(init_tenant_config(tenant_id, init_configs, trans))) {
5390
      LOG_WARN("insert tenant config failed", KR(ret), K(tenant_id));
5391
    } else if (is_meta_tenant(tenant_id)
5392
               && OB_FAIL(init_tenant_config(user_tenant_id, init_configs, trans))) {
5393
      LOG_WARN("insert tenant config failed", KR(ret), K(user_tenant_id));
5394
    }
5395
  }
5396

5397
  if (OB_SUCC(ret) && is_meta_tenant(tenant_id)) {
5398
    const uint64_t user_tenant_id = gen_user_tenant_id(tenant_id);
5399
    ObAllTenantInfo tenant_info;
5400
    if (OB_FAIL(tenant_info.init(user_tenant_id, tenant_role, NORMAL_SWITCHOVER_STATUS, 0,
5401
                SCN::base_scn(), SCN::base_scn(), SCN::base_scn(), recovery_until_scn))) {
5402
      LOG_WARN("failed to init tenant info", KR(ret), K(tenant_id), K(tenant_role));
5403
    } else if (OB_FAIL(ObAllTenantInfoProxy::init_tenant_info(tenant_info, &trans))) {
5404
      LOG_WARN("failed to init tenant info", KR(ret), K(tenant_info));
5405
    }
5406
  }
5407

5408
  return ret;
5409
}
5410

5411
int ObDDLOperator::init_tenant_tablegroup(const uint64_t tenant_id,
5412
                                          ObMySQLTransaction &trans)
5413
{
5414
  int ret = OB_SUCCESS;
5415
  int64_t start = ObTimeUtility::current_time();
5416
  int64_t new_schema_version = OB_INVALID_VERSION;
5417
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5418

5419
  if (OB_ISNULL(schema_service)) {
5420
    ret = OB_ERR_SYS;
5421
    LOG_ERROR("schema_service must not null");
5422
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5423
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5424
  } else {
5425
    ObTablegroupSchema tg_schema;
5426
    tg_schema.set_tenant_id(tenant_id);
5427
    tg_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID);
5428
    tg_schema.set_tablegroup_name(OB_SYS_TABLEGROUP_NAME);
5429
    tg_schema.set_comment("system tablegroup");
5430
    tg_schema.set_schema_version(OB_CORE_SCHEMA_VERSION);
5431
    tg_schema.set_part_level(PARTITION_LEVEL_ZERO);
5432
    tg_schema.set_schema_version(new_schema_version);
5433
    if (OB_FAIL(tg_schema.set_sharding(OB_PARTITION_SHARDING_ADAPTIVE))) {
5434
      LOG_WARN("set sharding failed", K(ret), K(tg_schema));
5435
    } else if (OB_FAIL(schema_service->get_tablegroup_sql_service().insert_tablegroup(tg_schema, trans))) {
5436
      LOG_WARN("insert_tablegroup failed", K(tg_schema), K(ret));
5437
    }
5438
  }
5439
  LOG_INFO("init tenant tablegroup", K(ret), K(tenant_id),
5440
           "cost", ObTimeUtility::current_time() - start);
5441
  return ret;
5442
}
5443

5444
int ObDDLOperator::init_tenant_database(const ObTenantSchema &tenant_schema,
5445
                                        const ObString &db_name,
5446
                                        const uint64_t pure_db_id,
5447
                                        const ObString &db_comment,
5448
                                        ObMySQLTransaction &trans,
5449
                                        const bool is_oracle_mode)
5450
{
5451
  int ret = OB_SUCCESS;
5452
  int64_t start = ObTimeUtility::current_time();
5453
  const uint64_t tenant_id = tenant_schema.get_tenant_id();
5454
  int64_t new_schema_version = OB_INVALID_VERSION;
5455
  if (db_name.empty() || OB_INVALID_ID == pure_db_id || db_comment.empty()) {
5456
    ret = OB_INVALID_ARGUMENT;
5457
    RS_LOG(WARN, "invalid argument", K(db_name), K(pure_db_id), K(db_comment), K(ret));
5458
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5459
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5460
  } else {
5461
    ObSchemaService *schema_service = schema_service_.get_schema_service();
5462
    ObDatabaseSchema db_schema;
5463
    db_schema.set_tenant_id(tenant_id);
5464
    db_schema.set_database_id(pure_db_id);
5465
    db_schema.set_database_name(db_name);
5466
    db_schema.set_comment(db_comment);
5467
    db_schema.set_schema_version(new_schema_version);
5468
    if (db_name == OB_RECYCLEBIN_SCHEMA_NAME
5469
        || db_name == OB_PUBLIC_SCHEMA_NAME) {
5470
      db_schema.set_read_only(true);
5471
    }
5472

5473
    if (OB_ISNULL(schema_service)) {
5474
      ret = OB_ERR_SYS;
5475
      RS_LOG(ERROR, "schema_service must not null");
5476
    } else if (OB_FAIL(ObSchema::set_charset_and_collation_options(tenant_schema.get_charset_type(),
5477
                                                                   tenant_schema.get_collation_type(),
5478
                                                                   db_schema))) {
5479
      RS_LOG(WARN, "set charset and collation options failed", K(ret));
5480
    } else if (OB_FAIL(schema_service->get_database_sql_service().insert_database(db_schema, trans))) {
5481
      RS_LOG(WARN, "insert_database failed", K(db_schema), K(ret));
5482
    }
5483
  }
5484

5485
  // init database priv
5486
  if (OB_SUCC(ret)) {
5487
    const uint64_t tenant_id = tenant_schema.get_tenant_id();
5488
    ObOriginalDBKey db_key;
5489
    db_key.tenant_id_ = tenant_id;
5490
    db_key.user_id_ = is_oracle_mode ? OB_ORA_SYS_USER_ID : OB_SYS_USER_ID;
5491
    db_key.db_ = db_name;
5492

5493
    ObSchemaService *schema_service = schema_service_.get_schema_service();
5494
    if (OB_ISNULL(schema_service)) {
5495
      ret = OB_ERR_SYS;
5496
      RS_LOG(ERROR, "schema_service must not null");
5497
    } else {
5498
      ObSqlString ddl_stmt_str;
5499
      ObString ddl_sql;
5500
      ObNeedPriv need_priv;
5501
      need_priv.db_ = db_name;
5502
      need_priv.priv_set_ = OB_PRIV_DB_ACC;//is collect?
5503
      need_priv.priv_level_ = OB_PRIV_DB_LEVEL;
5504
      if (OB_FAIL(ObDDLSqlGenerator::gen_db_priv_sql(ObAccountArg(is_oracle_mode ? OB_ORA_SYS_USER_NAME : OB_SYS_USER_NAME,
5505
                                                     OB_SYS_HOST_NAME),
5506
                                                     need_priv,
5507
                                                     true, /*is_grant*/
5508
                                                     ddl_stmt_str))) {
5509
        LOG_WARN("gen db priv sql failed", K(ret));
5510
      } else if (FALSE_IT(ddl_sql = ddl_stmt_str.string())) {
5511
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5512
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5513
      } else if (OB_FAIL(schema_service->get_priv_sql_service().grant_database(
5514
          db_key, OB_PRIV_DB_ACC, new_schema_version, &ddl_sql, trans))) {
5515
        RS_LOG(WARN, "insert database privilege failed, ", K(ret));
5516
      }
5517
    }
5518
  }
5519
  LOG_INFO("init tenant database", K(ret),
5520
           "tenant_id", tenant_schema.get_tenant_id(),
5521
           "database_name", db_name,
5522
           "cost", ObTimeUtility::current_time() - start);
5523
  return ret;
5524
}
5525

5526
int ObDDLOperator::init_tenant_databases(const ObTenantSchema &tenant_schema,
5527
                                         const ObSysVariableSchema &sys_variable,
5528
                                         ObMySQLTransaction &trans)
5529
{
5530
  int ret = OB_SUCCESS;
5531
  const uint64_t tenant_id = tenant_schema.get_tenant_id();
5532
  const bool is_sys = OB_SYS_TENANT_ID == tenant_id;
5533
  ObString oceanbase_schema(OB_SYS_DATABASE_NAME);
5534
  ObString mysql_schema(OB_MYSQL_SCHEMA_NAME);
5535
  ObString information_schema(OB_INFORMATION_SCHEMA_NAME);
5536
  ObString recyclebin_schema(OB_RECYCLEBIN_SCHEMA_NAME);
5537
  ObString public_schema(OB_PUBLIC_SCHEMA_NAME);
5538
  ObString test_schema(OB_TEST_SCHEMA_NAME);
5539
  ObString ora_sys_schema(OB_ORA_SYS_USER_NAME);
5540
  ObString ora_lbacsys_schema(OB_ORA_LBACSYS_NAME);
5541
  ObString ora_auditor_schema(OB_ORA_AUDITOR_NAME);
5542
  bool is_oracle_mode = false;
5543
  if (OB_FAIL(sys_variable.get_oracle_mode(is_oracle_mode))) {
5544
    LOG_WARN("failed to get oracle mode", K(ret));
5545
  } else if (OB_FAIL(init_tenant_database(tenant_schema, oceanbase_schema,
5546
                                   OB_SYS_DATABASE_ID, "system database",
5547
                                   trans, is_oracle_mode))) {
5548
    RS_LOG(WARN, "insert default database failed", K(tenant_id), K(ret));
5549
  } else if (OB_FAIL(init_tenant_database(tenant_schema, recyclebin_schema,
5550
                                          OB_RECYCLEBIN_SCHEMA_ID, "recyclebin schema",
5551
                                          trans, is_oracle_mode))) {
5552
    RS_LOG(WARN, "insert recyclebin schema failed", K(tenant_id), K(ret));
5553
  } else if (OB_FAIL(init_tenant_database(tenant_schema, public_schema,
5554
                                          OB_PUBLIC_SCHEMA_ID, "public schema",
5555
                                          trans, is_oracle_mode))) {
5556
    RS_LOG(WARN, "insert public schema failed", K(tenant_id), K(ret));
5557
  } else if (OB_FAIL(init_tenant_optimizer_stats_info(sys_variable, tenant_id, trans))) {
5558
    RS_LOG(WARN, "init tenant tenant optimizer control table", K(tenant_id), K(ret));
5559
  } else if (OB_FAIL(init_tenant_spm_configure(tenant_id, trans))) {
5560
    RS_LOG(WARN, "init tenant spm configure failed", K(tenant_id), K(ret));
5561
  } else {
5562
    if (!is_oracle_mode) {
5563
      if (OB_FAIL(init_tenant_database(tenant_schema, mysql_schema,
5564
                                       OB_MYSQL_SCHEMA_ID, "MySql schema",
5565
                                       trans, false))) {
5566
        RS_LOG(WARN, "insert information_schema failed", K(tenant_id), K(ret));
5567
      } else if (OB_FAIL(init_tenant_database(tenant_schema, information_schema,
5568
                                              OB_INFORMATION_SCHEMA_ID, "information_schema",
5569
                                              trans, false))) {
5570
        RS_LOG(WARN, "insert mysql schema failed", K(tenant_id), K(ret));
5571
      } else if (OB_FAIL(init_tenant_database(tenant_schema, test_schema,
5572
                                              OB_INITIAL_TEST_DATABASE_ID, "test schema",
5573
                                              trans, is_oracle_mode))) {
5574
        RS_LOG(WARN, "insert test schema failed", K(tenant_id), K(ret));
5575
      }
5576
    }
5577
    if (OB_FAIL(ret)) {
5578
      // do nothing
5579
    } else if (is_oracle_mode || is_sys) {
5580
      if (OB_FAIL(init_tenant_database(tenant_schema, ora_sys_schema,
5581
          OB_ORA_SYS_DATABASE_ID, "oracle sys schema", trans, is_oracle_mode))) {
5582
        RS_LOG(WARN, "insert oracle sys schema failed", K(ret), K(tenant_id));
5583
      } else if (OB_FAIL(init_tenant_database(tenant_schema, ora_lbacsys_schema,
5584
          OB_ORA_LBACSYS_DATABASE_ID, "oracle sys schema", trans, is_oracle_mode))) {
5585
        RS_LOG(WARN, "insert oracle lbacsys schema failed", K(ret), K(tenant_id));
5586
      } else if (OB_FAIL(init_tenant_database(tenant_schema, ora_auditor_schema,
5587
          OB_ORA_AUDITOR_DATABASE_ID, "oracle sys schema", trans, is_oracle_mode))) {
5588
        RS_LOG(WARN, "insert oracle lbacsys schema failed", K(ret), K(tenant_id));
5589
      }
5590
    }
5591
  }
5592

5593
  return ret;
5594
}
5595

5596
int ObDDLOperator::init_tenant_optimizer_stats_info(const ObSysVariableSchema &sys_variable,
5597
                                                    uint64_t tenant_id,
5598
                                                    ObMySQLTransaction &trans)
5599
{
5600
  int ret = OB_SUCCESS;
5601
  ObSqlString prefs_sql;
5602
  ObSqlString jobs_sql;
5603
  const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
5604
  int64_t expected_affected_rows1 = 0;
5605
  int64_t expected_affected_rows2 = 0;
5606
  int64_t affected_rows1 = 0;
5607
  int64_t affected_rows2 = 0;
5608
  if (OB_FAIL(ObDbmsStatsPreferences::gen_init_global_prefs_sql(prefs_sql,
5609
                                                                false,
5610
                                                                &expected_affected_rows1))) {
5611
    LOG_WARN("failed gen init global prefs sql", K(ret), K(prefs_sql));
5612
  } else if (OB_FAIL(ObDbmsStatsMaintenanceWindow::get_stats_maintenance_window_jobs_sql(
5613
                                                                        sys_variable,
5614
                                                                        tenant_id,
5615
                                                                        jobs_sql,
5616
                                                                        expected_affected_rows2))) {
5617
    LOG_WARN("failed tto get stats maintenance window jobs sql", K(ret), K(jobs_sql));
5618
  } else if (OB_UNLIKELY(prefs_sql.empty() || jobs_sql.empty())) {
5619
    ret = OB_ERR_UNEXPECTED;
5620
    RS_LOG(WARN, "get unexpected empty", K(ret), K(prefs_sql), K(jobs_sql));
5621
  } else if (OB_FAIL(trans.write(exec_tenant_id, prefs_sql.ptr(), affected_rows1)) ||
5622
             OB_FAIL(trans.write(exec_tenant_id, jobs_sql.ptr(), affected_rows2))) {
5623
    RS_LOG(WARN, "execute sql failed", K(ret), K(prefs_sql), K(jobs_sql));
5624
  } else if (OB_UNLIKELY(affected_rows1 != expected_affected_rows1 ||
5625
                         affected_rows2 != expected_affected_rows2)) {
5626
    ret = OB_ERR_UNEXPECTED;
5627
    RS_LOG(WARN, "get unexpected affected_rows", K(ret), K(affected_rows1), K(affected_rows2),
5628
                                           K(expected_affected_rows1), K(expected_affected_rows2));
5629
  } else {/*do nothing*/}
5630
  return ret;
5631
}
5632

5633
int ObDDLOperator::init_tenant_spm_configure(uint64_t tenant_id,
5634
                                             ObMySQLTransaction &trans)
5635
{
5636
  int ret = OB_SUCCESS;
5637
  const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
5638
  const uint64_t extract_tenant_id = ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id);
5639
  int64_t affected_rows = 0;
5640
  ObSqlString sql;
5641
  if (OB_FAIL(sql.assign_fmt("INSERT INTO %s (tenant_id, name, value) VALUES ",
5642
                             OB_ALL_SPM_CONFIG_TNAME))) {
5643
    RS_LOG(WARN, "sql assign failed", K(ret));
5644
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", NULL),", extract_tenant_id, "AUTO_CAPTURE_ACTION"))) {
5645
    RS_LOG(WARN, "sql append failed", K(ret));
5646
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", NULL),", extract_tenant_id, "AUTO_CAPTURE_MODULE"))) {
5647
    RS_LOG(WARN, "sql append failed", K(ret));
5648
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", NULL),", extract_tenant_id, "AUTO_CAPTURE_PARSING_SCHEMA_NAME"))) {
5649
    RS_LOG(WARN, "sql append failed", K(ret));
5650
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", NULL),", extract_tenant_id, "AUTO_CAPTURE_SQL_TEXT"))) {
5651
    RS_LOG(WARN, "sql append failed", K(ret));
5652
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", \"%s\"),", extract_tenant_id, "AUTO_SPM_EVOLVE_TASK", "OFF"))) {
5653
    RS_LOG(WARN, "sql append failed", K(ret));
5654
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", \"%s\"),", extract_tenant_id, "AUTO_SPM_EVOLVE_TASK_INTERVAL", "3600"))) {
5655
    RS_LOG(WARN, "sql append failed", K(ret));
5656
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", \"%s\"),", extract_tenant_id, "AUTO_SPM_EVOLVE_TASK_MAX_RUNTIME", "1800"))) {
5657
    RS_LOG(WARN, "sql append failed", K(ret));
5658
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", \"%s\"),", extract_tenant_id, "SPACE_BUDGET_PERCENT", "10"))) {
5659
    RS_LOG(WARN, "sql append failed", K(ret));
5660
  } else if (OB_FAIL(sql.append_fmt("(%lu, \"%s\", \"%s\");", extract_tenant_id, "PLAN_RETENTION_WEEKS", "53"))) {
5661
    RS_LOG(WARN, "sql append failed", K(ret));
5662
  } else if (OB_FAIL(trans.write(exec_tenant_id, sql.ptr(), affected_rows))) {
5663
    RS_LOG(WARN, "execute sql failed", K(ret), K(sql));
5664
  } else {/*do nothing*/}
5665
  return ret;
5666
}
5667

5668
/*
5669
 * The following system permissions are not granted to dba and need to be extracted from the complete set of permissions
5670
-----------------------------------------
5671
ADMINISTER KEY MANAGEMENT
5672
ALTER DATABASE LINK
5673
ALTER PUBLIC DATABASE LINK
5674
EXEMPT ACCESS POLICY
5675
EXEMPT IDENTITY POLICY
5676
EXEMPT REDACTION POLICY
5677
INHERIT ANY PRIVILEGES
5678
INHERIT ANY REMOTE PRIVILEGES
5679
KEEP DATE TIME
5680
KEEP SYSGUID
5681
PURGE DBA_RECYCLEBIN
5682
SYSBACKUP
5683
SYSDBA
5684
SYSDG
5685
SYSKM
5686
SYSOPER
5687
SYSRAC
5688
TRANSLATE ANY SQL
5689
UNLIMITED TABLESPACE
5690
------------------------------------------
5691
resource role, pre define sys priv;
5692
RESOURCE CREATE TABLE                             NO  YES YES
5693
RESOURCE CREATE OPERATOR                          NO  YES YES
5694
RESOURCE CREATE TYPE                              NO  YES YES
5695
RESOURCE CREATE CLUSTER                           NO  YES YES
5696
RESOURCE CREATE TRIGGER                           NO  YES YES
5697
RESOURCE CREATE INDEXTYPE                         NO  YES YES
5698
RESOURCE CREATE PROCEDURE                         NO  YES YES
5699
RESOURCE CREATE SEQUENCE                          NO  YES YES*/
5700
int ObDDLOperator::build_raw_priv_info_inner_user(
5701
    uint64_t grantee_id,
5702
    ObRawPrivArray &raw_priv_array,
5703
    uint64_t &option)
5704
{
5705
  int ret = OB_SUCCESS;
5706
  if (is_ora_dba_role(grantee_id) || is_ora_sys_user(grantee_id)) {
5707
    option = ADMIN_OPTION;
5708
    for (int i = PRIV_ID_NONE + 1; i < PRIV_ID_MAX && OB_SUCC(ret); i++) {
5709
      if (i != PRIV_ID_EXEMPT_RED_PLY
5710
          && i != PRIV_ID_SYSDBA
5711
          && i != PRIV_ID_SYSOPER
5712
          && i != PRIV_ID_SYSBACKUP
5713
          && i != PRIV_ID_EXEMPT_ACCESS_POLICY) {
5714
        OZ (raw_priv_array.push_back(i));
5715
      }
5716
    }
5717
  } else if (is_ora_resource_role(grantee_id)) {
5718
    option = NO_OPTION;
5719
    OZ (raw_priv_array.push_back(PRIV_ID_CREATE_TABLE));
5720
    OZ (raw_priv_array.push_back(PRIV_ID_CREATE_TYPE));
5721
    OZ (raw_priv_array.push_back(PRIV_ID_CREATE_TRIG));
5722
    OZ (raw_priv_array.push_back(PRIV_ID_CREATE_PROC));
5723
    OZ (raw_priv_array.push_back(PRIV_ID_CREATE_SEQ));
5724
  } else if (is_ora_connect_role(grantee_id)) {
5725
    option = NO_OPTION;
5726
    OZ (raw_priv_array.push_back(PRIV_ID_CREATE_SESSION));
5727
  } else if (is_ora_public_role(grantee_id)) {
5728
  } else {
5729
    ret = OB_INVALID_ARGUMENT;
5730
    LOG_WARN("grantee_id error", K(ret), K(grantee_id));
5731
  }
5732
  return ret;
5733
}
5734

5735
int ObDDLOperator::init_inner_user_privs(
5736
    const uint64_t tenant_id,
5737
    ObUserInfo &user,
5738
    ObMySQLTransaction &trans,
5739
    const bool is_oracle_mode)
5740
{
5741
  int ret = OB_SUCCESS;
5742
  int64_t new_schema_version = OB_INVALID_VERSION;
5743
  uint64_t grantee_id = user.get_user_id();
5744
  uint64_t option = NO_OPTION;
5745
  ObRawPrivArray raw_priv_array;
5746
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5747

5748
  if (OB_ISNULL(schema_service)) {
5749
    ret = OB_ERR_SYS;
5750
    LOG_ERROR("schema_service must not null", K(ret));
5751
  }
5752
  if (OB_SUCC(ret) && is_oracle_mode) {
5753
    ObString empty_str;
5754
    OZ (build_raw_priv_info_inner_user(grantee_id, raw_priv_array, option), grantee_id);
5755
    OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version), tenant_id);
5756
    OZ (schema_service->get_priv_sql_service().grant_sys_priv_to_ur(tenant_id,
5757
                                                                    grantee_id,
5758
                                                                    option,
5759
                                                                    raw_priv_array,
5760
                                                                    new_schema_version,
5761
                                                                    &empty_str,
5762
                                                                    trans,
5763
                                                                    true /*is_grant*/,
5764
                                                                    false),
5765
        tenant_id, grantee_id, ADMIN_OPTION, raw_priv_array);
5766
  }
5767
  return ret;
5768
}
5769

5770
int ObDDLOperator::init_tenant_user(const uint64_t tenant_id,
5771
                                    const ObString &user_name,
5772
                                    const ObString &pwd_raw,
5773
                                    const uint64_t pure_user_id,
5774
                                    const ObString &user_comment,
5775
                                    ObMySQLTransaction &trans,
5776
                                    const bool set_locked,
5777
                                    const bool is_user,
5778
                                    const bool is_oracle_mode)
5779
{
5780
  int ret = OB_SUCCESS;
5781
  ObString pwd_enc;
5782
  char enc_buf[ENC_BUF_LEN] = {0};
5783
  int64_t new_schema_version = OB_INVALID_VERSION;
5784
  ObSchemaService *schema_service = schema_service_.get_schema_service();
5785
  ObUserInfo user;
5786
  user.set_tenant_id(tenant_id);
5787
  pwd_enc.assign_ptr(enc_buf, ENC_BUF_LEN);
5788
  if (OB_ISNULL(schema_service)) {
5789
    ret = OB_ERR_SYS;
5790
    LOG_ERROR("schema_service must not null");
5791
  } else if (pwd_raw.length() > 0
5792
             && OB_FAIL(ObEncryptedHelper::encrypt_passwd_to_stage2(pwd_raw, pwd_enc))) {
5793
    LOG_WARN("Encrypt password failed", K(ret), K(pwd_raw));
5794
  } else if (OB_FAIL(user.set_user_name(user_name))) {
5795
    LOG_WARN("set user name failed", K(ret));
5796
  } else if (OB_FAIL(user.set_host(OB_SYS_HOST_NAME))) {
5797
    LOG_WARN("set host name failed", K(ret));
5798
  } else if (OB_FAIL(user.set_passwd(pwd_enc))) {
5799
    LOG_WARN("set user password failed", K(ret));
5800
  } else if (OB_FAIL(user.set_info(user_comment))) {
5801
    LOG_WARN("set user info failed", K(ret));
5802
  } else {
5803
    user.set_is_locked(set_locked);
5804
    user.set_user_id(pure_user_id);
5805
    if ((!is_oracle_mode || is_user) &&
5806
        pure_user_id != OB_ORA_LBACSYS_USER_ID &&
5807
        pure_user_id != OB_ORA_AUDITOR_USER_ID) {
5808
      user.set_priv_set(OB_PRIV_ALL | OB_PRIV_GRANT);
5809
    }
5810
    user.set_schema_version(OB_CORE_SCHEMA_VERSION);
5811
    user.set_profile_id(OB_INVALID_ID);
5812
    user.set_type((is_user) ? OB_USER : OB_ROLE);
5813
  }
5814
  if (OB_SUCC(ret)) {
5815
    ObSqlString ddl_stmt_str;
5816
    ObString ddl_sql;
5817
    if (OB_FAIL(ObDDLSqlGenerator::gen_create_user_sql(ObAccountArg(user.get_user_name_str(),
5818
                                                       user.get_host_name_str(),
5819
                                                       user.is_role()),
5820
                                                       user.get_passwd_str(),
5821
                                                       ddl_stmt_str))) {
5822
      LOG_WARN("gen create user sql failed", K(user), K(ret));
5823
    } else if (FALSE_IT(ddl_sql = ddl_stmt_str.string())) {
5824
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
5825
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
5826
    } else if (OB_FAIL(schema_service->get_user_sql_service().create_user(
5827
                       user, new_schema_version, &ddl_sql, trans))) {
5828
      LOG_WARN("insert user failed", K(user), K(ret));
5829
    } else if ((!is_user || is_ora_sys_user(user.get_user_id()))
5830
               && OB_FAIL(init_inner_user_privs(tenant_id, user, trans, is_oracle_mode))) {
5831
      LOG_WARN("init user privs failed", K(user), K(ret));
5832
    }
5833
  }
5834
  return ret;
5835
}
5836

5837
int ObDDLOperator::init_tenant_users(const ObTenantSchema &tenant_schema,
5838
                                     const ObSysVariableSchema &sys_variable,
5839
                                     ObMySQLTransaction &trans)
5840
{
5841
  int ret = OB_SUCCESS;
5842
  const uint64_t tenant_id = tenant_schema.get_tenant_id();
5843
  ObString sys_user_name(OB_SYS_USER_NAME);
5844
  ObString ora_sys_user_name(OB_ORA_SYS_USER_NAME);
5845
  ObString ora_lbacsys_user_name(OB_ORA_LBACSYS_NAME);
5846
  ObString ora_auditor_user_name(OB_ORA_AUDITOR_NAME);
5847
  ObString ora_connect_role_name(OB_ORA_CONNECT_ROLE_NAME);
5848
  ObString ora_resource_role_name(OB_ORA_RESOURCE_ROLE_NAME);
5849
  ObString ora_dba_role_name(OB_ORA_DBA_ROLE_NAME);
5850
  ObString ora_public_role_name(OB_ORA_PUBLIC_ROLE_NAME);
5851
  ObString sys_standby_name(OB_STANDBY_USER_NAME);
5852
  char ora_lbacsys_password[ENCRYPT_KEY_LENGTH];
5853
  char ora_auditor_password[ENCRYPT_KEY_LENGTH];
5854
  bool is_oracle_mode = false;
5855
  if (OB_FAIL(sys_variable.get_oracle_mode(is_oracle_mode))) {
5856
    RS_LOG(WARN, "failed to get oracle mode", K(ret), K(tenant_id));
5857
  } else if (is_oracle_mode) {
5858
    // Only retain the three users that is SYS/LBACSYS/ORAAUDITOR in Oracle mode.
5859
    if (OB_FAIL(share::ObKeyGenerator::generate_encrypt_key(ora_lbacsys_password, ENCRYPT_KEY_LENGTH))) {
5860
      RS_LOG(WARN, "failed to generate lbacsys's password", K(ret), K(tenant_id));
5861
    } else if (OB_FAIL(share::ObKeyGenerator::generate_encrypt_key(ora_auditor_password, ENCRYPT_KEY_LENGTH))) {
5862
      RS_LOG(WARN, "failed to generate auditor's password", K(ret), K(tenant_id));
5863
    } else if (OB_FAIL(init_tenant_user(tenant_id, ora_sys_user_name, ObString(""),
5864
        OB_ORA_SYS_USER_ID, "oracle system administrator", trans, false, true, true))) {
5865
      RS_LOG(WARN, "failed to init oracle sys user", K(ret), K(tenant_id));
5866
    } else if (OB_FAIL(init_tenant_user(tenant_id, ora_lbacsys_user_name,
5867
        ObString(ENCRYPT_KEY_LENGTH, ora_lbacsys_password),
5868
        OB_ORA_LBACSYS_USER_ID, "oracle system administrator", trans, true, true, true))) {
5869
      RS_LOG(WARN, "failed to init oracle sys user", K(ret), K(tenant_id));
5870
    } else if (OB_FAIL(init_tenant_user(tenant_id, ora_auditor_user_name,
5871
        ObString(ENCRYPT_KEY_LENGTH, ora_auditor_password),
5872
        OB_ORA_AUDITOR_USER_ID, "oracle system administrator", trans, true, true, true))) {
5873
      RS_LOG(WARN, "failed to init oracle sys user", K(ret), K(tenant_id));
5874
    } else if (OB_FAIL(init_tenant_user(tenant_id, ora_connect_role_name, ObString(""),
5875
         OB_ORA_CONNECT_ROLE_ID, "oracle connect role", trans, false, false, true))) {
5876
      RS_LOG(WARN, "fail to init oracle connect role", K(ret), K(tenant_id));
5877
    } else if (OB_FAIL(init_tenant_user(tenant_id, ora_resource_role_name, ObString(""),
5878
         OB_ORA_RESOURCE_ROLE_ID, "oracle resource role", trans, false, false, true))) {
5879
      RS_LOG(WARN, "fail to init oracle resource role", K(ret), K(tenant_id));
5880
    } else if (OB_FAIL(init_tenant_user(tenant_id, ora_dba_role_name, ObString(""),
5881
         OB_ORA_DBA_ROLE_ID, "oracle dba role", trans, false, false, true))) {
5882
      RS_LOG(WARN, "fail to init oracle dba role", K(ret), K(tenant_id));
5883
    } else if (OB_FAIL(init_tenant_user(tenant_id, ora_public_role_name, ObString(""),
5884
         OB_ORA_PUBLIC_ROLE_ID, "oracle public role", trans, false, false, true))) {
5885
      RS_LOG(WARN, "fail to init oracle public role", K(ret), K(tenant_id));
5886
    }
5887
  } else {
5888
    if (OB_FAIL(init_tenant_user(tenant_id, sys_user_name, ObString(""), OB_SYS_USER_ID,
5889
        "system administrator", trans))) {
5890
      RS_LOG(WARN, "failed to init sys user", K(ret), K(tenant_id));
5891
    }
5892
#ifdef OB_BUILD_TDE_SECURITY
5893
    if (OB_SUCC(ret)) {
5894
      if (OB_FAIL(share::ObKeyGenerator::generate_encrypt_key(ora_auditor_password,
5895
                                                              ENCRYPT_KEY_LENGTH))) {
5896
        RS_LOG(WARN, "failed to generate auditor's password", K(ret), K(tenant_id));
5897
      } else if (OB_FAIL(init_tenant_user(tenant_id, ora_auditor_user_name,
5898
                                    ObString(ENCRYPT_KEY_LENGTH, ora_auditor_password),
5899
                                    OB_ORA_AUDITOR_USER_ID, "system administrator", trans, true))) {
5900
        RS_LOG(WARN, "failed to init mysql audit user", K(ret), K(tenant_id));
5901
      }
5902
    }
5903
#endif
5904
  }
5905

5906
  //TODO in standby cluster, temp logical, will be deleted after inner sql ready
5907
//  if (OB_SUCC(ret) && is_sys_tenant(tenant_id)) {
5908
//    const uint64_t user_id = 100;
5909
//    if (OB_FAIL(init_tenant_user(tenant_id, sys_standby_name, "", user_id,
5910
//            "system administrator", trans))) {
5911
//      RS_LOG(WARN, "failed to init sys user", K(ret), K(tenant_id));
5912
//    }
5913
//  }
5914
  return ret;
5915
}
5916

5917
int ObDDLOperator::init_tenant_config(
5918
    const uint64_t tenant_id,
5919
    const common::ObIArray<common::ObConfigPairs> &init_configs,
5920
    ObMySQLTransaction &trans)
5921
{
5922
  int ret = OB_SUCCESS;
5923
  int64_t tenant_idx = !is_user_tenant(tenant_id) ? 0 : 1;
5924
  if (is_user_tenant(tenant_id) && init_configs.count() == 1) {
5925
    ret = OB_SUCCESS;
5926
    LOG_WARN("no user config", KR(ret), K(tenant_idx), K(tenant_id), K(init_configs));
5927
  } else if (OB_UNLIKELY(
5928
      init_configs.count() < tenant_idx + 1
5929
      || tenant_id != init_configs.at(tenant_idx).get_tenant_id())) {
5930
    ret = OB_INVALID_ARGUMENT;
5931
    LOG_WARN("invalid init_configs", KR(ret), K(tenant_idx), K(tenant_id), K(init_configs));
5932
  } else if (OB_FAIL(init_tenant_config_(tenant_id, init_configs.at(tenant_idx), trans))) {
5933
    LOG_WARN("fail to init tenant config", KR(ret), K(tenant_id));
5934
  } else if (OB_FAIL(init_tenant_config_from_seed_(tenant_id, trans))) {
5935
    LOG_WARN("fail to init tenant config from seed", KR(ret), K(tenant_id));
5936
  }
5937
  return ret;
5938
}
5939

5940
int ObDDLOperator::init_tenant_config_(
5941
    const uint64_t tenant_id,
5942
    const common::ObConfigPairs &tenant_config,
5943
    ObMySQLTransaction &trans)
5944
{
5945
  int ret = OB_SUCCESS;
5946
  omt::ObTenantConfigGuard hard_code_config(TENANT_CONF(OB_SYS_TENANT_ID));
5947
  int64_t config_cnt = tenant_config.get_configs().count();
5948
  if (OB_UNLIKELY(tenant_id != tenant_config.get_tenant_id() || config_cnt <= 0)) {
5949
    ret = OB_INVALID_ARGUMENT;
5950
    LOG_WARN("invalid tenant config", KR(ret), K(tenant_id), K(tenant_config));
5951
  } else if (!hard_code_config.is_valid()) {
5952
    ret = OB_ERR_UNEXPECTED;
5953
    LOG_WARN("failed to get hard code config", KR(ret), K(tenant_id));
5954
  } else {
5955
    ObDMLSqlSplicer dml;
5956
    ObConfigItem *item = NULL;
5957
    char svr_ip[OB_MAX_SERVER_ADDR_SIZE] = "ANY";
5958
    int64_t svr_port = 0;
5959
    int64_t config_version = omt::ObTenantConfig::INITIAL_TENANT_CONF_VERSION + 1;
5960
    FOREACH_X(config, tenant_config.get_configs(), OB_SUCC(ret)) {
5961
      const ObConfigStringKey key(config->key_.ptr());
5962
      if (OB_ISNULL(hard_code_config->get_container().get(key))
5963
          || OB_ISNULL(item = *(hard_code_config->get_container().get(key)))) {
5964
        ret = OB_ENTRY_NOT_EXIST;
5965
        LOG_WARN("config not exist", KR(ret), KPC(config));
5966
      } else if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id))
5967
                 || OB_FAIL(dml.add_pk_column("zone", ""))
5968
                 || OB_FAIL(dml.add_pk_column("svr_type", print_server_role(OB_SERVER)))
5969
                 || OB_FAIL(dml.add_pk_column(K(svr_ip)))
5970
                 || OB_FAIL(dml.add_pk_column(K(svr_port)))
5971
                 || OB_FAIL(dml.add_pk_column("name", config->key_.ptr()))
5972
                 || OB_FAIL(dml.add_column("data_type", item->data_type()))
5973
                 || OB_FAIL(dml.add_column("value", config->value_.ptr()))
5974
                 || OB_FAIL(dml.add_column("info", ""))
5975
                 || OB_FAIL(dml.add_column("config_version", config_version))
5976
                 || OB_FAIL(dml.add_column("section", item->section()))
5977
                 || OB_FAIL(dml.add_column("scope", item->scope()))
5978
                 || OB_FAIL(dml.add_column("source", item->source()))
5979
                 || OB_FAIL(dml.add_column("edit_level", item->edit_level()))) {
5980
        LOG_WARN("fail to add column", KR(ret), K(tenant_id), KPC(config));
5981
      } else if (OB_FAIL(dml.finish_row())) {
5982
        LOG_WARN("fail to finish row", KR(ret), K(tenant_id), KPC(config));
5983
      }
5984
    } // end foreach
5985
    ObSqlString sql;
5986
    int64_t affected_rows = 0;
5987
    const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
5988
    if (FAILEDx(dml.splice_batch_insert_sql(OB_TENANT_PARAMETER_TNAME, sql))) {
5989
      LOG_WARN("fail to generate sql", KR(ret), K(tenant_id));
5990
    } else if (OB_FAIL(trans.write(exec_tenant_id, sql.ptr(), affected_rows))) {
5991
      LOG_WARN("fail to execute sql", KR(ret), K(tenant_id), K(exec_tenant_id), K(sql));
5992
    } else if (config_cnt != affected_rows) {
5993
      ret = OB_ERR_UNEXPECTED;
5994
      LOG_WARN("affected_rows not match", KR(ret), K(tenant_id), K(config_cnt), K(affected_rows));
5995
    }
5996
  }
5997
  return ret;
5998
}
5999

6000
int ObDDLOperator::init_tenant_config_from_seed_(
6001
    const uint64_t tenant_id,
6002
    ObMySQLTransaction &trans)
6003
{
6004
  int ret = OB_SUCCESS;
6005
  int64_t start = ObTimeUtility::current_time();
6006
  ObSqlString sql;
6007
  const static char *from_seed = "select config_version, zone, svr_type, svr_ip, svr_port, name, "
6008
                "data_type, value, info, section, scope, source, edit_level "
6009
                "from __all_seed_parameter";
6010
  ObSQLClientRetryWeak sql_client_retry_weak(&sql_proxy_);
6011
  SMART_VAR(ObMySQLProxy::MySQLResult, result) {
6012
    int64_t expected_rows = 0;
6013
    int64_t config_version = omt::ObTenantConfig::INITIAL_TENANT_CONF_VERSION + 1;
6014
    bool is_first = true;
6015
    if (OB_FAIL(sql_client_retry_weak.read(result, OB_SYS_TENANT_ID, from_seed))) {
6016
      LOG_WARN("read config from __all_seed_parameter failed", K(from_seed), K(ret));
6017
    } else {
6018
      sql.reset();
6019
      if (OB_FAIL(sql.assign_fmt("INSERT IGNORE INTO %s "
6020
          "(TENANT_ID, ZONE, SVR_TYPE, SVR_IP, SVR_PORT, NAME, DATA_TYPE, VALUE, INFO, "
6021
          "SECTION, SCOPE, SOURCE, EDIT_LEVEL, CONFIG_VERSION) VALUES",
6022
          OB_TENANT_PARAMETER_TNAME))) {
6023
        LOG_WARN("sql assign failed", K(ret));
6024
      }
6025

6026
      while (OB_SUCC(ret) && OB_SUCC(result.get_result()->next())) {
6027
        common::sqlclient::ObMySQLResult *rs = result.get_result();
6028
        if (OB_ISNULL(rs)) {
6029
          ret = OB_ERR_UNEXPECTED;
6030
          LOG_WARN("system config result is null", K(ret));
6031
        } else {
6032
          ObString var_zone, var_svr_type, var_svr_ip, var_name, var_data_type;
6033
          ObString var_value, var_info, var_section, var_scope, var_source, var_edit_level;
6034
          int64_t var_svr_port = 0;
6035
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "zone", var_zone);
6036
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "svr_type", var_svr_type);
6037
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "svr_ip", var_svr_ip);
6038
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "name", var_name);
6039
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "data_type", var_data_type);
6040
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "value", var_value);
6041
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "info", var_info);
6042
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "section", var_section);
6043
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "scope", var_scope);
6044
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "source", var_source);
6045
          EXTRACT_VARCHAR_FIELD_MYSQL(*rs, "edit_level", var_edit_level);
6046
          EXTRACT_INT_FIELD_MYSQL(*rs, "svr_port", var_svr_port, int64_t);
6047
          if (FAILEDx(sql.append_fmt("%s('%lu', '%.*s', '%.*s', '%.*s', %ld, '%.*s', '%.*s', '%.*s',"
6048
              "'%.*s', '%.*s', '%.*s', '%.*s', '%.*s', %ld)",
6049
              is_first ? " " : ", ",
6050
              tenant_id,
6051
              var_zone.length(), var_zone.ptr(),
6052
              var_svr_type.length(), var_svr_type.ptr(),
6053
              var_svr_ip.length(), var_svr_ip.ptr(), var_svr_port,
6054
              var_name.length(), var_name.ptr(),
6055
              var_data_type.length(), var_data_type.ptr(),
6056
              var_value.length(), var_value.ptr(),
6057
              var_info.length(), var_info.ptr(),
6058
              var_section.length(), var_section.ptr(),
6059
              var_scope.length(), var_scope.ptr(),
6060
              var_source.length(), var_source.ptr(),
6061
              var_edit_level.length(), var_edit_level.ptr(), config_version))) {
6062
            LOG_WARN("sql append failed", K(ret));
6063
          }
6064
        }
6065
        expected_rows++;
6066
        is_first = false;
6067
      } // while
6068

6069
      if (OB_ITER_END == ret) {
6070
        ret = OB_SUCCESS;
6071
        uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
6072
        if (expected_rows > 0) {
6073
          int64_t affected_rows = 0;
6074
          if (OB_FAIL(trans.write(exec_tenant_id, sql.ptr(), affected_rows))) {
6075
            LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(exec_tenant_id), K(sql));
6076
          } else if (OB_UNLIKELY(affected_rows < 0
6077
                     || expected_rows < affected_rows)) {
6078
            ret = OB_ERR_UNEXPECTED;
6079
            LOG_WARN("unexpected affected_rows", KR(ret),  K(expected_rows), K(affected_rows));
6080
          }
6081
        }
6082
      } else {
6083
        LOG_WARN("failed to get result from result set", K(ret));
6084
      }
6085
    } // else
6086
    LOG_INFO("init tenant config", K(ret), K(tenant_id),
6087
               "cost", ObTimeUtility::current_time() - start);
6088
  }
6089
  return ret;
6090

6091
}
6092

6093
int ObDDLOperator::init_freeze_info(const uint64_t tenant_id,
6094
                                    ObMySQLTransaction &trans)
6095
{
6096
  int ret = OB_SUCCESS;
6097
  int64_t start = ObTimeUtility::current_time();
6098
  ObFreezeInfoProxy freeze_info_proxy(tenant_id);
6099
  ObFreezeInfo frozen_status;
6100
  frozen_status.set_initial_value(DATA_CURRENT_VERSION);
6101
  // init freeze_info in __all_freeze_info
6102
  if (OB_FAIL(freeze_info_proxy.set_freeze_info(trans, frozen_status))) {
6103
    LOG_WARN("fail to set freeze info", KR(ret), K(frozen_status), K(tenant_id));
6104
  }
6105

6106
  LOG_INFO("init freeze info", K(ret), K(tenant_id),
6107
           "cost", ObTimeUtility::current_time() - start);
6108
  return ret;
6109
}
6110

6111
int ObDDLOperator::init_tenant_srs(const uint64_t tenant_id,
6112
                                   ObMySQLTransaction &trans)
6113
{
6114
  // todo : import srs_id 0 in srs mgr init
6115
  int ret = OB_SUCCESS;
6116
  ObSqlString sql;
6117
  int64_t start = ObTimeUtility::current_time();
6118
  int64_t expected_rows = 1;
6119
  uint64_t tenant_data_version = 0;
6120
  if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, tenant_data_version))) {
6121
    LOG_WARN("get tenant data version failed", K(ret));
6122
  } else if (tenant_data_version < DATA_VERSION_4_1_0_0) {
6123
    ret = OB_NOT_SUPPORTED;
6124
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "tenant version is less than 4.1, spatial reference system");
6125
  } else {
6126
    if (OB_FAIL(sql.assign_fmt("INSERT INTO %s "
6127
        "(SRS_VERSION, SRS_ID, SRS_NAME, ORGANIZATION, ORGANIZATION_COORDSYS_ID, DEFINITION, minX, maxX, minY, maxY, proj4text, DESCRIPTION) VALUES"
6128
        R"((1, 0, '', NULL, NULL, '', -2147483648,2147483647,-2147483648,2147483647,'', NULL))",
6129
        OB_ALL_SPATIAL_REFERENCE_SYSTEMS_TNAME))) {
6130
      LOG_WARN("sql assign failed", K(ret));
6131
    }
6132

6133
    if (OB_SUCC(ret)) {
6134
      int64_t affected_rows = 0;
6135
      if (OB_FAIL(trans.write(tenant_id, sql.ptr(), affected_rows))) {
6136
        LOG_WARN("execute sql failed", K(ret), K(sql));
6137
      } else if (expected_rows != affected_rows) {
6138
        ret = OB_ERR_UNEXPECTED;
6139
        LOG_WARN("unexpected affected_rows", K(expected_rows), K(affected_rows));
6140
      }
6141
    }
6142
  }
6143

6144
  LOG_INFO("init tenant srs", K(ret), K(tenant_id),
6145
           "cost", ObTimeUtility::current_time() - start);
6146
  return ret;
6147
}
6148

6149
int ObDDLOperator::init_tenant_sys_stats(const uint64_t tenant_id,
6150
                                         ObMySQLTransaction &trans)
6151
{
6152
  int ret = OB_SUCCESS;
6153
  int64_t start = ObTimeUtility::current_time();
6154
  ObSysStat sys_stat;
6155
  if (OB_FAIL(sys_stat.set_initial_values(tenant_id))) {
6156
    LOG_WARN("set initial values failed", K(ret));
6157
  } else if (sys_stat.item_list_.is_empty()) {
6158
    ret = OB_INVALID_ARGUMENT;
6159
    LOG_WARN("not system stat item", KR(ret), K(tenant_id));
6160
  } else if (OB_FAIL(replace_sys_stat(tenant_id, sys_stat, trans))) {
6161
    LOG_WARN("replace system stat failed", K(ret));
6162
  }
6163
  LOG_INFO("init sys stat", K(ret), K(tenant_id),
6164
           "cost", ObTimeUtility::current_time() - start);
6165
  return ret;
6166
}
6167

6168
int ObDDLOperator::replace_sys_stat(const uint64_t tenant_id,
6169
                                    ObSysStat &sys_stat,
6170
                                    ObISQLClient &trans)
6171
{
6172
  int ret = OB_SUCCESS;
6173
  ObSqlString sql;
6174
  const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
6175
  if (sys_stat.item_list_.is_empty()) {
6176
    // skip
6177
  } else if (OB_FAIL(sql.assign_fmt("INSERT INTO %s "
6178
      "(TENANT_ID, ZONE, NAME, DATA_TYPE, VALUE, INFO, gmt_modified) VALUES ",
6179
      OB_ALL_SYS_STAT_TNAME))) {
6180
    LOG_WARN("sql append failed", K(ret));
6181
  } else {
6182
    DLIST_FOREACH_X(it, sys_stat.item_list_, OB_SUCC(ret)) {
6183
      if (OB_ISNULL(it)) {
6184
        ret = OB_ERR_UNEXPECTED;
6185
        LOG_WARN("it is null", K(ret));
6186
      } else {
6187
        char buf[2L<<10] = "";
6188
        int64_t pos = 0;
6189
        if (OB_FAIL(it->value_.print_sql_literal(
6190
                      buf, sizeof(buf), pos))) {
6191
          LOG_WARN("print obj failed", K(ret), "obj", it->value_);
6192
        } else {
6193
          ObString value(pos, buf);
6194
          uint64_t schema_id = OB_INVALID_ID;
6195
          if (OB_FAIL(ObMaxIdFetcher::str_to_uint(value, schema_id))) {
6196
            LOG_WARN("fail to convert str to uint", K(ret), K(value));
6197
          } else if (FALSE_IT(schema_id = ObSchemaUtils::get_extract_schema_id(exec_tenant_id, schema_id))) {
6198
          } else if (OB_FAIL(sql.append_fmt("%s(%lu, '', '%s', %d, '%ld', '%s', now())",
6199
              (it == sys_stat.item_list_.get_first()) ? "" : ", ",
6200
              ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id),
6201
              it->name_, it->value_.get_type(),
6202
              static_cast<int64_t>(schema_id),
6203
              it->info_))) {
6204
            LOG_WARN("sql append failed", K(ret));
6205
          }
6206
        }
6207
      }
6208
    }
6209
    if (OB_SUCC(ret)) {
6210
      LOG_INFO("create system stat sql", K(sql));
6211
      int64_t affected_rows = 0;
6212
      if (OB_FAIL(trans.write(exec_tenant_id, sql.ptr(), affected_rows))) {
6213
        LOG_WARN("execute sql failed", K(ret), K(sql));
6214
      } else if (sys_stat.item_list_.get_size() != affected_rows
6215
          && sys_stat.item_list_.get_size() != affected_rows / 2) {
6216
        ret = OB_ERR_UNEXPECTED;
6217
        LOG_WARN("unexpected affected_rows", K(affected_rows),
6218
            "expected", sys_stat.item_list_.get_size());
6219
      }
6220
    }
6221
  }
6222
  return ret;
6223
}
6224

6225
int ObDDLOperator::init_sys_tenant_charset(ObMySQLTransaction &trans)
6226
{
6227
  int ret = OB_SUCCESS;
6228
  const ObCharsetWrapper *charset_wrap_arr = NULL;
6229
  int64_t charset_wrap_arr_len = 0;
6230
  ObSqlString sql;
6231
  if (OB_FAIL(sql.assign_fmt("insert into %s "
6232
      "(charset, description, default_collation, max_length) values ",
6233
      OB_ALL_CHARSET_TNAME))) {
6234
    LOG_WARN("sql append failed", K(ret));
6235
  } else {
6236
    ObCharset::get_charset_wrap_arr(charset_wrap_arr, charset_wrap_arr_len);
6237
    if (OB_ISNULL(charset_wrap_arr) ||
6238
        OB_UNLIKELY(ObCharset::VALID_CHARSET_TYPES != charset_wrap_arr_len)) {
6239
      ret = OB_ERR_UNEXPECTED;
6240
      LOG_ERROR("charset wrap array is NULL or charset_wrap_arr_len is not CHARSET_WRAPPER_COUNT",
6241
                K(ret), K(charset_wrap_arr), K(charset_wrap_arr_len));
6242
    } else {
6243
      for (int64_t i = 0; OB_SUCC(ret) && i < charset_wrap_arr_len; ++i) {
6244
        ObCharsetWrapper charset_wrap = charset_wrap_arr[i];
6245
        if (OB_FAIL(sql.append_fmt("%s('%s', '%s', '%s', %ld)",
6246
           (0 == i) ? "" : ", ", ObCharset::charset_name(charset_wrap.charset_),
6247
           charset_wrap.description_,
6248
           ObCharset::collation_name(ObCharset::get_default_collation(charset_wrap.charset_)),
6249
                                     charset_wrap.maxlen_))) {
6250
          LOG_WARN("sql append failed", K(ret));
6251
        }
6252
      }
6253
    }
6254
  }
6255

6256
  if (OB_SUCC(ret)) {
6257
    LOG_INFO("create charset sql", K(sql));
6258
    int64_t affected_rows = 0;
6259
    if (OB_FAIL(trans.write(sql.ptr(), affected_rows))) {
6260
      LOG_WARN("execute sql failed", K(ret), K(sql));
6261
    } else if (charset_wrap_arr_len != affected_rows) {
6262
      ret = OB_ERR_UNEXPECTED;
6263
      LOG_ERROR("unexpected affected_rows", K(affected_rows),
6264
          "expected", (charset_wrap_arr_len));
6265
    }
6266
  }
6267
  return ret;
6268
}
6269

6270
int ObDDLOperator::init_sys_tenant_collation(ObMySQLTransaction &trans)
6271
{
6272
  int ret = OB_SUCCESS;
6273
  const ObCollationWrapper *collation_wrap_arr = NULL;
6274
  int64_t collation_wrap_arr_len = 0;
6275
  ObSqlString sql;
6276
  int64_t total_valid_collations = 0;
6277
  if (OB_FAIL(sql.assign_fmt("insert into %s "
6278
      "(collation, charset, id, `is_default`, is_compiled, sortlen) values ",
6279
      OB_ALL_COLLATION_TNAME))) {
6280
    LOG_WARN("sql append failed", K(ret));
6281
  } else {
6282
    ObCharset::get_collation_wrap_arr(collation_wrap_arr, collation_wrap_arr_len);
6283
    if (OB_ISNULL(collation_wrap_arr) ||
6284
        OB_UNLIKELY(ObCharset::VALID_COLLATION_TYPES != collation_wrap_arr_len)) {
6285
      ret = OB_ERR_UNEXPECTED;
6286
      LOG_ERROR("collation wrap array is NULL or collation_wrap_arr_len is not COLLATION_WRAPPER_COUNT",
6287
                K(ret), K(collation_wrap_arr), K(collation_wrap_arr_len));
6288
    } else {
6289
      for (int64_t i = 0; OB_SUCC(ret) && i < collation_wrap_arr_len; ++i) {
6290
        ObCollationWrapper collation_wrap = collation_wrap_arr[i];
6291
        if (CS_TYPE_INVALID != collation_wrap.collation_) {
6292
          if (OB_FAIL(sql.append_fmt("%s('%s', '%s', %ld, '%s', '%s', %ld)",
6293
              (0 == total_valid_collations) ? "" : ", ",
6294
              ObCharset::collation_name(collation_wrap.collation_),
6295
              ObCharset::charset_name(collation_wrap.charset_),
6296
              collation_wrap.id_,
6297
              (true == collation_wrap.default_) ? "Yes" : "",
6298
              (true == collation_wrap.compiled_) ? "Yes" : "",
6299
              collation_wrap.sortlen_))) {
6300
            LOG_WARN("sql append failed", K(ret));
6301
          }
6302
          total_valid_collations++;
6303
        }
6304
      }
6305
    }
6306
  }
6307

6308
  if (OB_SUCC(ret)) {
6309
    LOG_INFO("create collation sql", K(sql));
6310
    int64_t affected_rows = 0;
6311
    if (OB_FAIL(trans.write(sql.ptr(), affected_rows))) {
6312
      LOG_WARN("execute sql failed", K(ret), K(sql));
6313
    } else if (total_valid_collations != affected_rows) {
6314
      ret = OB_ERR_UNEXPECTED;
6315
      LOG_ERROR("unexpected affected_rows", K(affected_rows),
6316
          "expected", (collation_wrap_arr_len));
6317
    }
6318
  }
6319
  return ret;
6320
}
6321

6322
int ObDDLOperator::init_sys_tenant_privilege(ObMySQLTransaction &trans)
6323
{
6324
  int ret = OB_SUCCESS;
6325

6326
  ObSqlString sql;
6327
  int64_t row_count = 0;
6328
  if (OB_FAIL(sql.assign_fmt("INSERT /*+ use_plan_cache(none) */ INTO %s "
6329
      "(Privilege, Context, Comment) values ",
6330
        OB_ALL_PRIVILEGE_TNAME))) {
6331
    LOG_WARN("sql append failed", K(ret));
6332
  } else {
6333
    const PrivilegeRow *current_row = all_privileges;
6334
    if (OB_ISNULL(current_row)) {
6335
      ret = OB_ERR_UNEXPECTED;
6336
      LOG_WARN("current_row is null", K(ret));
6337
    } else {
6338
      bool is_first_row = true;
6339
      for (; OB_SUCC(ret) && NULL != current_row && NULL != current_row->privilege_;
6340
           ++current_row) {
6341
        if (OB_FAIL(sql.append_fmt("%s('%s', '%s', '%s')",
6342
            is_first_row ? "" : ", ",
6343
            current_row->privilege_,
6344
            current_row->context_,
6345
            current_row->comment_))) {
6346
          LOG_WARN("sql append failed", K(ret));
6347
        } else {
6348
          ++row_count;
6349
          is_first_row = false;
6350
        }
6351
      }
6352
    }
6353
  }
6354

6355
  if (OB_SUCC(ret)) {
6356
    LOG_INFO("create privileges sql", K(sql));
6357
    int64_t affected_rows = 0;
6358
    if (OB_FAIL(trans.write(sql.ptr(), affected_rows))) {
6359
      LOG_WARN("execute sql failed", K(ret), K(sql));
6360
    } else if (row_count != affected_rows) {
6361
      ret = OB_ERR_UNEXPECTED;
6362
      LOG_ERROR("unexpected affected_rows", K(affected_rows));
6363
    }
6364
  }
6365

6366
  return ret;
6367
}
6368

6369
//----Functions for managing privileges----
6370
int ObDDLOperator::create_user(
6371
    const share::schema::ObUserInfo &user_info,
6372
    const ObString *ddl_stmt_str,
6373
    common::ObMySQLTransaction &trans)
6374
{
6375
  int ret = OB_SUCCESS;
6376
  const uint64_t tenant_id = user_info.get_tenant_id();
6377
  int64_t new_schema_version = OB_INVALID_VERSION;
6378
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6379
  if (OB_ISNULL(schema_sql_service)) {
6380
    ret = OB_ERR_SYS;
6381
    LOG_ERROR("schema_sql_service must not be null", K(ret));
6382
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6383
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6384
  } else if (OB_FAIL(schema_sql_service->get_user_sql_service().create_user(
6385
                     user_info, new_schema_version, ddl_stmt_str, trans))) {
6386
    LOG_WARN("Failed to create user", K(user_info), K(ret));
6387
  }
6388
  return ret;
6389
}
6390

6391
int ObDDLOperator::drop_user(
6392
    const uint64_t tenant_id,
6393
    const uint64_t user_id,
6394
    const common::ObString *ddl_stmt_str,
6395
    common::ObMySQLTransaction &trans)
6396
{
6397
  int ret = OB_SUCCESS;
6398
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6399
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6400
    ret = OB_INVALID_ARGUMENT;
6401
    LOG_WARN("Tenant_id and user_id must not be null", K(tenant_id), K(user_id), K(ret));
6402
  } else if (OB_ISNULL(schema_sql_service)) {
6403
    ret = OB_ERR_SYS;
6404
    LOG_ERROR("schama sql service and schema manager must not be null",
6405
              K(schema_sql_service), K(ret));
6406
  }
6407
  //delete user
6408
  if (OB_SUCC(ret)) {
6409
    int64_t new_schema_version = OB_INVALID_VERSION;
6410
    ObSchemaGetterGuard schema_guard;
6411
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6412
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6413
    } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6414
      LOG_WARN("failed to get schema guard", K(ret));
6415
    } else if (OB_FAIL(schema_sql_service->get_user_sql_service().drop_user(tenant_id,
6416
        user_id, new_schema_version, ddl_stmt_str, trans, schema_guard))) {
6417
      LOG_WARN("Drop user from all user table error", K(tenant_id), K(user_id), K(ret));
6418
    }
6419
  }
6420
  //delete db and table privileges of this user
6421
  if (OB_SUCC(ret)) {
6422
    if (OB_FAIL(drop_db_table_privs(tenant_id, user_id, trans))) {
6423
      LOG_WARN("Drop db, table privileges of user error", K(tenant_id), K(user_id), K(ret));
6424
    }
6425
  }
6426

6427
  // oracle mode, if the user has a label security policy, the label granted to the user will be deleted synchronously.
6428
  if (OB_SUCC(ret)) {
6429
    ObSchemaGetterGuard schema_guard;
6430
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6431
      LOG_WARN("failed to get schema guard", K(ret));
6432
    } else if (OB_FAIL(drop_all_label_se_user_components(tenant_id, user_id,
6433
                                                         OB_INVALID_ID, trans,
6434
                                                         ObString(), schema_guard))) {
6435
      LOG_WARN("fail to drop user label components cascaded", K(ret));
6436
    }
6437
  }
6438

6439

6440
  // delete audit in user
6441
  if (OB_SUCC(ret)) {
6442
    ObArray<const ObSAuditSchema *> audits;
6443
    ObSchemaGetterGuard schema_guard;
6444
    int64_t new_schema_version = OB_INVALID_VERSION;
6445
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6446
      LOG_WARN("failed to get schema guard", K(ret));
6447
    } else if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
6448
                                                              AUDIT_STMT,
6449
                                                              user_id,
6450
                                                              audits))) {
6451
      LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
6452
    } else if (!audits.empty()) {
6453
      common::ObSqlString public_sql_string;
6454
      for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
6455
        const ObSAuditSchema *audit_schema = audits.at(i);
6456
        if (OB_ISNULL(audit_schema)) {
6457
          ret = OB_ERR_UNEXPECTED;
6458
          LOG_WARN("audit_schema is NULL", K(ret));
6459
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6460
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6461
        } else if (OB_FAIL(schema_sql_service->get_audit_sql_service().handle_audit_metainfo(
6462
            *audit_schema,
6463
            AUDIT_MT_DEL,
6464
            false,
6465
            new_schema_version,
6466
            NULL,
6467
            trans,
6468
            public_sql_string))) {
6469
          LOG_WARN("drop audit_schema failed",  KPC(audit_schema), K(ret));
6470
        } else {
6471
          LOG_INFO("succ to delete audit_schema from drop user", KPC(audit_schema));
6472
        }
6473
      }
6474
    } else {
6475
      LOG_DEBUG("no need to delete audit_schema from drop user", K(user_id));
6476
    }
6477
  }
6478

6479
  return ret;
6480
}
6481

6482
int ObDDLOperator::drop_db_table_privs(
6483
    const uint64_t tenant_id,
6484
    const uint64_t user_id,
6485
    common::ObMySQLTransaction &trans)
6486
{
6487
  int ret = OB_SUCCESS;
6488
  ObSchemaGetterGuard schema_guard;
6489
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6490
  int64_t ddl_count = 0;
6491
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6492
    ret = OB_INVALID_ARGUMENT;
6493
    LOG_WARN("Tenant_id and user_id must not be null", K(tenant_id), K(user_id), K(ret));
6494
  } else if (OB_ISNULL(schema_sql_service)) {
6495
    ret = OB_ERR_SYS;
6496
    LOG_ERROR("schama sql service and schema manager must not be null",
6497
              K(schema_sql_service), K(ret));
6498
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6499
    LOG_WARN("failed to get schema guard", K(ret));
6500
  }
6501
  // delete database privileges of this user
6502
  if (OB_SUCC(ret)) {
6503
    ObArray<const ObDBPriv *> db_privs;
6504
    if (OB_FAIL(schema_guard.get_db_priv_with_user_id(
6505
        tenant_id, user_id, db_privs))) {
6506
      LOG_WARN("Get database privileges of user to be deleted error",
6507
                K(tenant_id), K(user_id), K(ret));
6508
    } else {
6509
      for (int64_t i = 0; OB_SUCC(ret) && i < db_privs.count(); ++i) {
6510
        const ObDBPriv *db_priv = db_privs.at(i);
6511
        int64_t new_schema_version = OB_INVALID_VERSION;
6512
        if (OB_ISNULL(db_priv)) {
6513
          LOG_WARN("db priv is NULL", K(ret), K(db_priv));
6514
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6515
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6516
        } else if (OB_FAIL(schema_sql_service->get_priv_sql_service().delete_db_priv(
6517
            db_priv->get_original_key(), new_schema_version, trans))) {
6518
          LOG_WARN("Delete database privilege failed", "DB Priv", *db_priv, K(ret));
6519
        }
6520
      }
6521
      ddl_count -= db_privs.count();
6522
    }
6523
  }
6524
  // delete table privileges of this user MYSQL
6525
  if (OB_SUCC(ret)) {
6526
    ObArray<const ObTablePriv *> table_privs;
6527
    if (OB_FAIL(schema_guard.get_table_priv_with_user_id(
6528
                                 tenant_id, user_id, table_privs))) {
6529
      LOG_WARN("Get table privileges of user to be deleted error",
6530
                K(tenant_id), K(user_id), K(ret));
6531
    } else {
6532
      for (int64_t i = 0; OB_SUCC(ret) && i < table_privs.count(); ++i) {
6533
        const ObTablePriv *table_priv = table_privs.at(i);
6534
        int64_t new_schema_version = OB_INVALID_VERSION;
6535
        if (OB_ISNULL(table_priv)) {
6536
          LOG_WARN("table priv is NULL", K(ret), K(table_priv));
6537
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6538
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6539
        } else if (OB_FAIL(schema_sql_service->get_priv_sql_service().delete_table_priv(
6540
            table_priv->get_sort_key(), new_schema_version, trans))) {
6541
          LOG_WARN("Delete table privilege failed", "Table Priv", *table_priv, K(ret));
6542
        }
6543
      }
6544
    }
6545
  }
6546

6547
  // delete oracle table privileges of this user ORACLE
6548
  if (OB_SUCC(ret)) {
6549
    ObArray<const ObObjPriv *> obj_privs;
6550

6551
    OZ (schema_guard.get_obj_priv_with_grantee_id(
6552
                tenant_id, user_id, obj_privs));
6553
    OZ (schema_guard.get_obj_priv_with_grantor_id(
6554
                tenant_id, user_id, obj_privs, false));
6555
    for (int64_t i = 0; OB_SUCC(ret) && i < obj_privs.count(); ++i) {
6556
      const ObObjPriv *obj_priv = obj_privs.at(i);
6557
      int64_t new_schema_version = OB_INVALID_VERSION;
6558
      if (OB_ISNULL(obj_priv)) {
6559
        LOG_WARN("obj_priv priv is NULL", K(ret), K(obj_priv));
6560
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6561
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6562
      } else if (OB_FAIL(schema_sql_service->get_priv_sql_service().delete_obj_priv(
6563
                 *obj_priv, new_schema_version, trans))) {
6564
        LOG_WARN("Delete obj_priv privilege failed", "obj Priv", *obj_priv, K(ret));
6565
      }
6566
    }
6567
  }
6568

6569
  return ret;
6570
}
6571

6572
int ObDDLOperator::rename_user(
6573
    const uint64_t tenant_id,
6574
    const uint64_t user_id,
6575
    const ObAccountArg &new_account,
6576
    const common::ObString *ddl_stmt_str,
6577
    common::ObMySQLTransaction &trans)
6578
{
6579
  int ret = OB_SUCCESS;
6580
  ObSchemaGetterGuard schema_guard;
6581
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6582
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6583
    ret = OB_INVALID_ARGUMENT;
6584
    LOG_WARN("tenant_id and user_id must not be null", K(tenant_id), K(user_id), K(ret));
6585
  } else if (OB_ISNULL(schema_sql_service)) {
6586
    ret = OB_ERR_SYS;
6587
    LOG_ERROR("schama service_impl must not null",
6588
        "schema_service_impl", schema_sql_service, K(ret));
6589
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6590
    LOG_WARN("failed to get schema guard", K(ret));
6591
  } else {
6592
    const ObUserInfo *user_info = NULL;
6593
    int64_t new_schema_version = OB_INVALID_VERSION;
6594
    if (OB_FAIL(schema_guard.get_user_info(tenant_id, user_id, user_info))) {
6595
      LOG_WARN("failed to get user info", K(ret), K(tenant_id), K(user_id));
6596
    } else if (OB_ISNULL(user_info)) {
6597
      ret = OB_ERR_USER_NOT_EXIST;
6598
      LOG_WARN("User not exist", K(ret));
6599
    } else {
6600
      ObUserInfo new_user_info = *user_info;
6601
      new_user_info.set_user_name(new_account.user_name_);
6602
      new_user_info.set_host(new_account.host_name_);
6603
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6604
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6605
      } else if (OB_FAIL(schema_sql_service->get_user_sql_service().rename_user(
6606
                  new_user_info, new_schema_version, ddl_stmt_str, trans))) {
6607
        LOG_WARN("Failed to rename user", K(tenant_id), K(user_id), K(new_account), K(ret));
6608
      }
6609
    }
6610
  }
6611
  return ret;
6612
}
6613

6614
int ObDDLOperator::set_passwd(
6615
    const uint64_t tenant_id,
6616
    const uint64_t user_id,
6617
    const common::ObString &passwd,
6618
    const ObString *ddl_stmt_str,
6619
    common::ObMySQLTransaction &trans)
6620
{
6621
  int ret = OB_SUCCESS;
6622
  ObSchemaGetterGuard schema_guard;
6623
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6624
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6625
    ret = OB_INVALID_ARGUMENT;
6626
    LOG_WARN("tenant_id and user_id must not be null", K(tenant_id), K(user_id), K(ret));
6627
  } else if (OB_ISNULL(schema_sql_service)) {
6628
    ret = OB_ERR_SYS;
6629
    LOG_ERROR("schama service_impl and schema manage must not null",
6630
        "schema_service_impl", schema_sql_service, K(ret));
6631
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6632
    LOG_WARN("failed to get schema guard", K(ret));
6633
  } else {
6634
    const ObUserInfo *user_info = NULL;
6635
    if (OB_FAIL(schema_guard.get_user_info(tenant_id, user_id, user_info))) {
6636
      LOG_WARN("failed to get user info", K(ret));
6637
    } else if (OB_ISNULL(user_info)) {
6638
      ret = OB_ERR_USER_NOT_EXIST;
6639
      LOG_WARN("User not exist", K(ret));
6640
    } else {
6641
      int64_t new_schema_version = OB_INVALID_VERSION;
6642
      ObUserInfo new_user_info = *user_info;
6643
      new_user_info.set_passwd(passwd);
6644
      new_user_info.set_password_last_changed(ObTimeUtility::current_time());
6645
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6646
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6647
      } else if (OB_FAIL(schema_sql_service->get_user_sql_service().set_passwd(
6648
                        new_user_info, new_schema_version, ddl_stmt_str, trans))) {
6649
        LOG_WARN("Failed to set passwd", K(tenant_id), K(user_id), K(ret));
6650
      }
6651
    }
6652
  }
6653

6654
  return ret;
6655
}
6656

6657
int ObDDLOperator::set_max_connections(
6658
    const uint64_t tenant_id,
6659
    const uint64_t user_id,
6660
    const uint64_t max_connections_per_hour,
6661
    const uint64_t max_user_connections,
6662
    const ObString *ddl_stmt_str,
6663
    common::ObMySQLTransaction &trans)
6664
{
6665
  int ret = OB_SUCCESS;
6666
  ObSchemaGetterGuard schema_guard;
6667
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6668
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6669
    ret = OB_INVALID_ARGUMENT;
6670
    LOG_WARN("tenant_id and user_id must not be null", K(tenant_id), K(user_id), K(ret));
6671
  } else if (OB_ISNULL(schema_sql_service)) {
6672
    ret = OB_ERR_SYS;
6673
    LOG_ERROR("schama service_impl and schema manage must not null",
6674
        "schema_service_impl", schema_sql_service, K(ret));
6675
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6676
    LOG_WARN("failed to get schema guard", K(ret));
6677
  } else {
6678
    const ObUserInfo *user_info = NULL;
6679
    if (OB_FAIL(schema_guard.get_user_info(tenant_id, user_id, user_info))) {
6680
      LOG_WARN("failed to get user info", K(ret));
6681
    } else if (OB_ISNULL(user_info)) {
6682
      ret = OB_ERR_USER_NOT_EXIST;
6683
      LOG_WARN("User not exist", K(ret));
6684
    } else {
6685
      int64_t new_schema_version = OB_INVALID_VERSION;
6686
      ObUserInfo new_user_info = *user_info;
6687
      if (OB_INVALID_ID != max_connections_per_hour) {
6688
        new_user_info.set_max_connections(max_connections_per_hour);
6689
      }
6690
      if (OB_INVALID_ID != max_user_connections) {
6691
        new_user_info.set_max_user_connections(max_user_connections);
6692
      }
6693
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6694
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6695
      } else if (OB_FAIL(schema_sql_service->get_user_sql_service().set_max_connections(
6696
                        new_user_info, new_schema_version, ddl_stmt_str, trans))) {
6697
        LOG_WARN("Failed to set passwd", K(tenant_id), K(user_id), K(ret));
6698
      }
6699
    }
6700
  }
6701

6702
  return ret;
6703
}
6704

6705
int ObDDLOperator::alter_role(
6706
    const uint64_t tenant_id,
6707
    const uint64_t role_id,
6708
    const common::ObString &passwd,
6709
    const ObString *ddl_stmt_str,
6710
    common::ObMySQLTransaction &trans)
6711
{
6712
  int ret = OB_SUCCESS;
6713
  ObSchemaGetterGuard schema_guard;
6714
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6715
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == role_id) {
6716
    ret = OB_INVALID_ARGUMENT;
6717
    LOG_WARN("tenant_id and role_id must not be null", K(tenant_id), K(role_id), K(ret));
6718
  } else if (OB_ISNULL(schema_sql_service)) {
6719
    ret = OB_ERR_SYS;
6720
    LOG_ERROR("schama service_impl and schema manage must not null",
6721
        "schema_service_impl", schema_sql_service, K(ret));
6722
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6723
    LOG_WARN("failed to get schema guard", K(ret));
6724
  } else {
6725
    const ObUserInfo *role_info = NULL;
6726
    if (OB_FAIL(schema_guard.get_user_info(tenant_id, role_id, role_info))) {
6727
      LOG_WARN("failed to get role info", K(ret), K(role_id));
6728
    } else if (OB_ISNULL(role_info)) {
6729
      ret = OB_ROLE_NOT_EXIST;
6730
      LOG_WARN("Role not exist", K(ret));
6731
    } else {
6732
      int64_t new_schema_version = OB_INVALID_VERSION;
6733
      ObUserInfo new_role_info = *role_info;
6734
      new_role_info.set_passwd(passwd);
6735
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6736
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6737
      } else if (OB_FAIL(schema_sql_service->get_user_sql_service().alter_role(
6738
                         new_role_info, new_schema_version, ddl_stmt_str, trans))) {
6739
        LOG_WARN("Failed to alter_role", K(tenant_id), K(role_id), K(ret));
6740
      }
6741
    }
6742
  }
6743

6744
  return ret;
6745
}
6746

6747
int ObDDLOperator::alter_user_default_role(const ObString &ddl_str,
6748
                                           const ObUserInfo &schema,
6749
                                           ObIArray<uint64_t> &role_id_array,
6750
                                           ObIArray<uint64_t> &disable_flag_array,
6751
                                           ObMySQLTransaction &trans)
6752
{
6753
  int ret = OB_SUCCESS;
6754
  ObSchemaService *schema_sql_service = NULL;
6755
  int64_t new_schema_version = OB_INVALID_VERSION;
6756

6757
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
6758
    ret = OB_ERR_SYS;
6759
    LOG_ERROR("schema_sql_service must not null", K(ret));
6760
  } else if (!schema.is_valid()) {
6761
    ret = OB_INVALID_ARGUMENT;
6762
    LOG_WARN("invalid argument", K(ret), K(schema));
6763
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(schema.get_tenant_id(),
6764
                                                            new_schema_version))) {
6765
    LOG_WARN("fail to gen new schema_version", K(ret));
6766
  } else {
6767
    if (OB_FAIL(schema_sql_service->get_priv_sql_service().alter_user_default_role(
6768
                                                          schema,
6769
                                                          new_schema_version,
6770
                                                          &ddl_str,
6771
                                                          role_id_array,
6772
                                                          disable_flag_array,
6773
                                                          trans))) {
6774
      LOG_WARN("alter user default role failed", K(ret));
6775
    }
6776
  }
6777

6778
  LOG_DEBUG("alter_user_default_role", K(schema));
6779
  return ret;
6780
}
6781

6782
int ObDDLOperator::alter_user_profile(const ObString &ddl_str,
6783
                                      ObUserInfo &schema,
6784
                                      ObMySQLTransaction &trans)
6785
{
6786
  int ret = OB_SUCCESS;
6787
  ObSchemaService *schema_sql_service = NULL;
6788
  int64_t new_schema_version = OB_INVALID_VERSION;
6789

6790
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
6791
    ret = OB_ERR_SYS;
6792
    LOG_ERROR("schema_sql_service must not null", K(ret));
6793
  } else if (!schema.is_valid()) {
6794
    ret = OB_INVALID_ARGUMENT;
6795
    LOG_WARN("invalid argument", K(ret), K(schema));
6796
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(schema.get_tenant_id(), new_schema_version))) {
6797
    LOG_WARN("fail to gen new schema_version", K(ret));
6798
  } else {
6799
    schema.set_schema_version(new_schema_version);
6800
    if (OB_FAIL(schema_sql_service->get_user_sql_service().alter_user_profile(schema, &ddl_str, trans))) {
6801
      LOG_WARN("alter user profile failed", K(ret));
6802
    }
6803
  }
6804

6805
  LOG_DEBUG("alter_user_profile", K(schema));
6806
  return ret;
6807
}
6808

6809
int ObDDLOperator::alter_user_require(const uint64_t tenant_id,
6810
    const uint64_t user_id,
6811
    const obrpc::ObSetPasswdArg &arg,
6812
    const common::ObString *ddl_stmt_str,
6813
    common::ObMySQLTransaction &trans)
6814
{
6815
  int ret = OB_SUCCESS;
6816
  ObSchemaGetterGuard schema_guard;
6817
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6818
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6819
    ret = OB_INVALID_ARGUMENT;
6820
    LOG_WARN("tenant_id and user_id must not be null", K(tenant_id), K(user_id), K(ret));
6821
  } else if (OB_ISNULL(schema_sql_service)) {
6822
    ret = OB_ERR_SYS;
6823
    LOG_ERROR("schama service_impl and schema manage must not null",
6824
        "schema_service_impl", schema_sql_service, K(ret));
6825
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6826
    LOG_WARN("failed to get schema guard", K(ret));
6827
  } else {
6828
    const ObUserInfo *user_info = NULL;
6829
    if (OB_FAIL(schema_guard.get_user_info(tenant_id, user_id, user_info))) {
6830
      LOG_WARN("failed to get user info", K(ret));
6831
    } else if (OB_ISNULL(user_info)) {
6832
      ret = OB_ERR_USER_NOT_EXIST;
6833
      LOG_WARN("User not exist", K(ret));
6834
    } else {
6835
      int64_t new_schema_version = OB_INVALID_VERSION;
6836
      ObUserInfo new_user_info = *user_info;
6837
      new_user_info.set_ssl_type(arg.ssl_type_);
6838
      new_user_info.set_ssl_cipher(arg.ssl_cipher_);
6839
      new_user_info.set_x509_issuer(arg.x509_issuer_);
6840
      new_user_info.set_x509_subject(arg.x509_subject_);
6841
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6842
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6843
      } else if (OB_FAIL(schema_sql_service->get_user_sql_service().alter_user_require(
6844
                         new_user_info, new_schema_version, ddl_stmt_str, trans))) {
6845
        LOG_WARN("Failed to alter_user_require", K(tenant_id), K(user_id), K(ret));
6846
      }
6847
    }
6848
  }
6849

6850
  return ret;
6851
}
6852

6853
int ObDDLOperator::grant_revoke_user(
6854
    const uint64_t tenant_id,
6855
    const uint64_t user_id,
6856
    const ObPrivSet priv_set,
6857
    const bool grant,
6858
    const bool is_from_inner_sql,
6859
    const ObString *ddl_stmt_str,
6860
    common::ObMySQLTransaction &trans)
6861
{
6862
  int ret = OB_SUCCESS;
6863
  ObSchemaGetterGuard schema_guard;
6864
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6865
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6866
    ret = OB_INVALID_ARGUMENT;
6867
    LOG_WARN("tenant_id and user_id must not be null", K(tenant_id), K(user_id), K(ret));
6868
  } else if (OB_ISNULL(schema_sql_service)) {
6869
    ret = OB_ERR_SYS;
6870
    LOG_ERROR("schama service_impl and schema manage must not null",
6871
        "schema_service_impl", schema_sql_service, K(ret));
6872
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6873
    LOG_WARN("failed to get schema guard", K(ret));
6874
  } else {
6875
    ObPrivSet new_priv = priv_set;
6876

6877
    const ObUserInfo *user_info = NULL;
6878
    if (OB_FAIL(schema_guard.get_user_info(tenant_id, user_id, user_info)) ||
6879
        NULL == user_info) {
6880
      ret = OB_ERR_USER_NOT_EXIST;
6881
      LOG_WARN("User not exist", K(ret));
6882
    } else {
6883
      if (grant) {
6884
        new_priv = priv_set | user_info->get_priv_set();
6885
      } else {
6886
        new_priv = (~priv_set) & user_info->get_priv_set();
6887
      }
6888
      //no matter privilege change or not, write a sql
6889
      int64_t new_schema_version = OB_INVALID_VERSION;
6890
      ObUserInfo new_user_info = *user_info;
6891
      new_user_info.set_priv_set(new_priv);
6892
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6893
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6894
      } else if (OB_FAIL(schema_sql_service->get_user_sql_service().grant_revoke_user(
6895
                         new_user_info, new_schema_version, ddl_stmt_str, trans, is_from_inner_sql))) {
6896
        LOG_WARN("Failed to grant or revoke user", K(tenant_id), K(user_id), K(grant), K(ret));
6897
      }
6898
    }
6899
  }
6900

6901
  return ret;
6902
}
6903

6904
int ObDDLOperator::lock_user(
6905
    const uint64_t tenant_id,
6906
    const uint64_t user_id,
6907
    const bool locked,
6908
    const ObString *ddl_stmt_str,
6909
    common::ObMySQLTransaction &trans)
6910
{
6911
  int ret = OB_SUCCESS;
6912
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6913
  ObSchemaGetterGuard schema_guard;
6914
  if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == user_id) {
6915
    ret = OB_INVALID_ARGUMENT;
6916
    LOG_WARN("tenant_id and user_id is invalid", K(tenant_id), K(user_id), K(ret));
6917
  } else if (OB_ISNULL(schema_sql_service)) {
6918
    ret = OB_ERR_SYS;
6919
    LOG_ERROR("schama service_impl and schema manage must not null",
6920
        "schema_service_impl", schema_sql_service, K(ret));
6921
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6922
    LOG_WARN("failed to get schema guard", K(ret));
6923
  } else {
6924
    const ObUserInfo *user_info = NULL;
6925
    if (OB_FAIL(schema_guard.get_user_info(tenant_id, user_id, user_info)) ||
6926
          NULL == user_info) {
6927
      ret = OB_ERR_USER_NOT_EXIST;
6928
      LOG_WARN("User not exist", K(ret));
6929
    } else if (locked != user_info->get_is_locked()) {
6930
      int64_t new_schema_version = OB_INVALID_VERSION;
6931
      ObUserInfo new_user_info = *user_info;
6932
      new_user_info.set_is_locked(locked);
6933
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6934
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6935
      } else if (OB_FAIL(schema_sql_service->get_user_sql_service().lock_user(
6936
                         new_user_info, new_schema_version, ddl_stmt_str, trans))) {
6937
        LOG_WARN("Failed to lock user", K(tenant_id), K(user_id), K(locked), K(ret));
6938
      }
6939
    }
6940
  }
6941
  return ret;
6942
}
6943

6944
int ObDDLOperator::grant_database(
6945
    const ObOriginalDBKey &db_priv_key,
6946
    const ObPrivSet priv_set,
6947
    const ObString *ddl_stmt_str,
6948
    common::ObMySQLTransaction &trans)
6949
{
6950
  int ret = OB_SUCCESS;
6951
  const uint64_t tenant_id = db_priv_key.tenant_id_;
6952
  ObSchemaGetterGuard schema_guard;
6953
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
6954
  if (OB_ISNULL(schema_sql_service)) {
6955
    ret = OB_ERR_SYS;
6956
    LOG_ERROR("schama service_impl and schema manage must not null",
6957
        "schema_service_impl", schema_sql_service, K(ret));
6958
  } else if (!db_priv_key.is_valid()) {
6959
    ret = OB_INVALID_ARGUMENT;
6960
    LOG_WARN("db_priv_key is invalid", K(db_priv_key), K(ret));
6961
  } else if (0 == priv_set) {
6962
    //do nothing
6963
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
6964
    LOG_WARN("failed to get schema guard", K(ret));
6965
  } else {
6966
    ObPrivSet new_priv = priv_set;
6967
    bool need_flush = true;
6968
    ObPrivSet db_priv_set = OB_PRIV_SET_EMPTY;
6969
    if (OB_FAIL(schema_guard.get_db_priv_set(db_priv_key, db_priv_set, true))) {
6970
      LOG_WARN("get db priv set failed", K(ret));
6971
    } else {
6972
      new_priv |= db_priv_set;
6973
      need_flush = (new_priv != db_priv_set);
6974
      if (need_flush) {
6975
        int64_t new_schema_version = OB_INVALID_VERSION;
6976
        if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
6977
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
6978
        } else if (OB_FAIL(schema_sql_service->get_priv_sql_service().grant_database(db_priv_key,
6979
                                                                              new_priv,
6980
                                                                              new_schema_version,
6981
                                                                              ddl_stmt_str,
6982
                                                                              trans))) {
6983
          LOG_WARN("Failed to grant database", K(db_priv_key), K(ret));
6984
        }
6985
      }
6986
    }
6987
  }
6988
  return ret;
6989
}
6990

6991
int ObDDLOperator::revoke_database(
6992
    const ObOriginalDBKey &db_priv_key,
6993
    const ObPrivSet priv_set,
6994
    common::ObMySQLTransaction &trans)
6995
{
6996
  int ret = OB_SUCCESS;
6997
  const uint64_t tenant_id = db_priv_key.tenant_id_;
6998
  ObSchemaGetterGuard schema_guard;
6999
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
7000
  if (OB_ISNULL(schema_sql_service)) {
7001
    ret = OB_ERR_SYS;
7002
    LOG_ERROR("schama service_impl and schema manage must not null",
7003
        "schema_service_impl", schema_sql_service, K(ret));
7004
  } else if (!db_priv_key.is_valid()) {
7005
    ret = OB_INVALID_ARGUMENT;
7006
    LOG_WARN("db_priv_key is invalid", K(db_priv_key), K(ret));
7007
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
7008
    LOG_WARN("failed to get schema guard", K(ret));
7009
  } else {
7010
    ObPrivSet db_priv_set = OB_PRIV_SET_EMPTY;
7011
    if (OB_FAIL(schema_guard.get_db_priv_set(db_priv_key, db_priv_set, true))) {
7012
      LOG_WARN("get db priv set failed", K(ret));
7013
    } else if (OB_PRIV_SET_EMPTY == db_priv_set) {
7014
      ret = OB_ERR_NO_GRANT;
7015
      LOG_WARN("No such grant to revoke", K(db_priv_key), K(ret));
7016
    } else if (0 == priv_set) {
7017
      //do nothing
7018
    } else {
7019
      ObPrivSet new_priv = db_priv_set & (~priv_set);
7020
      if (db_priv_set & priv_set) {
7021
        ObSqlString ddl_stmt_str;
7022
        ObString ddl_sql;
7023
        const ObUserInfo *user_info = NULL;
7024
        ObNeedPriv need_priv;
7025
        need_priv.db_ = db_priv_key.db_;
7026
        need_priv.priv_level_ = OB_PRIV_DB_LEVEL;
7027
        need_priv.priv_set_ = db_priv_set & priv_set; //priv to revoke
7028
        int64_t new_schema_version = OB_INVALID_VERSION;
7029
        if (OB_FAIL(schema_guard.get_user_info(tenant_id, db_priv_key.user_id_, user_info))) {
7030
          LOG_WARN("get user info failed", K(tenant_id), K(db_priv_key), K(ret));
7031
        } else if (OB_ISNULL(user_info)) {
7032
          ret = OB_ERR_UNEXPECTED;
7033
          LOG_WARN("user not exist", K(db_priv_key), K(ret));
7034
        } else if (OB_FAIL(ObDDLSqlGenerator::gen_db_priv_sql(ObAccountArg(user_info->get_user_name_str(), user_info->get_host_name_str()),
7035
                                                              need_priv,
7036
                                                              false, /*is_grant*/
7037
                                                              ddl_stmt_str))) {
7038
          LOG_WARN("gen_db_priv_sql failed", K(ret), K(need_priv));
7039
        } else if (FALSE_IT(ddl_sql = ddl_stmt_str.string())) {
7040
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
7041
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
7042
        } else if (OB_FAIL(schema_sql_service->get_priv_sql_service().revoke_database(
7043
            db_priv_key, new_priv, new_schema_version, &ddl_sql, trans))) {
7044
          LOG_WARN("Failed to revoke database", K(db_priv_key), K(ret));
7045
        }
7046
      }
7047
    }
7048
  }
7049
  return ret;
7050
}
7051

7052
/* According to the current obj priv, check if the user has all the permissions listed in obj_priv_array */
7053
int ObDDLOperator::check_obj_privs_exists(
7054
    ObSchemaGetterGuard &schema_guard,
7055
    const share::schema::ObObjPrivSortKey &obj_priv_key, /* in: obj priv key */
7056
    const ObRawObjPrivArray &obj_priv_array,      /* in: privs to be deleted */
7057
    ObRawObjPrivArray &option_priv_array,         /* out: privs to be deleted cascade */
7058
    bool &is_all)                                 /* out: obj priv array is all privs existed */
7059
{
7060
  int ret = OB_SUCCESS;
7061
  ObPackedObjPriv obj_privs = 0;
7062
  ObRawObjPriv raw_obj_priv = 0;
7063
  bool exists = false;
7064
  uint64_t option_out = false;
7065
  is_all = false;
7066
  int org_n = 0;
7067
  OZ (schema_guard.get_obj_privs(obj_priv_key, obj_privs));
7068
  for (int i = 0; i < obj_priv_array.count() && OB_SUCC(ret); i++) {
7069
    raw_obj_priv = obj_priv_array.at(i);
7070
    OZ (ObOraPrivCheck::raw_obj_priv_exists_with_info(raw_obj_priv,
7071
                                                      obj_privs,
7072
                                                      exists,
7073
                                                      option_out),
7074
        raw_obj_priv, obj_privs, ret);
7075
    if (OB_SUCC(ret)) {
7076
      if (!exists) {
7077
      ret = OB_ERR_CANNOT_REVOKE_PRIVILEGES_YOU_DID_NOT_GRANT;
7078
      } else if (option_out == GRANT_OPTION) {
7079
        OZ (option_priv_array.push_back(raw_obj_priv));
7080
      }
7081
    }
7082
  }
7083
  OZ (ObPrivPacker::get_total_obj_privs(obj_privs, org_n));
7084
  OX (is_all = org_n == obj_priv_array.count());
7085
  return ret;
7086
}
7087

7088
/** According to the current obj priv, check if the user has all the permissions listed in obj_priv_array, including the column permissions on the table.
7089
 * check_obj_privs_exists_including_col_privs
7090
 * is used to check the existence of object permissions
7091
 * @param  {ObSchemaGetterGuard &} schema_guard                 : schema_guard
7092
 * @param  {const schema::ObObjPrivSortKey &} obj_priv_key      : object for checking, accurate to the table
7093
 * @param  {const ObRawObjPrivArray &} obj_priv_array           : permission for revoking
7094
 * @param  {ObIArray<schema::ObObjPrivSortKey> &} new_key_array : There may be multiple columns on the obj_priv_key
7095
 *         table object with independent column permissions, so we regenerate all the keys,
7096
 *         which are accurate to the column
7097
 * @param  {ObIArray<ObPackedObjPriv> &} new_packed_privs_array : Corresponds to new_key_array,
7098
 *         permission to revoke
7099
 * @param  {ObIArray<bool> &} is_all                            : Corresponds to new_key_array,
7100
 *         indicating whether the permission to revoke is all the permissions owned by the key
7101
 * @return {int}                                                : ret
7102
 */
7103
int ObDDLOperator::check_obj_privs_exists_including_col_privs(
7104
    ObSchemaGetterGuard &schema_guard,
7105
    const share::schema::ObObjPrivSortKey &obj_priv_key,
7106
    const ObRawObjPrivArray &obj_priv_array,
7107
    ObIArray<share::schema::ObObjPrivSortKey> &new_key_array,
7108
    ObIArray<ObPackedObjPriv> &new_packed_privs_array,
7109
    ObIArray<bool> &is_all)
7110
{
7111
  int ret = OB_SUCCESS;
7112
  ObRawObjPriv raw_obj_priv_to_be_revoked = 0;
7113
  ObPackedObjPriv packed_table_privs = 0;
7114
  ObPackedObjPriv packed_table_privs_to_be_revoked = 0;
7115
  ObSEArray<uint64_t, 4> col_id_array;
7116
  ObSEArray<ObPackedObjPriv, 4> packed_col_privs_array;
7117
  ObPackedObjPriv packed_total_matched_privs = 0;
7118
  ObObjPrivSortKey new_col_key = obj_priv_key;
7119
  ObPackedObjPriv packed_col_privs = 0;
7120
  ObPackedObjPriv packed_col_privs_to_be_revoked = 0;
7121
  bool exists = false;
7122
  int org_n = 0;
7123
  int own_priv_count = 0;
7124
  int revoked_priv_count = 0;
7125
  uint64_t option_out = false;
7126
  bool is_all_single = false;
7127
  new_key_array.reset();
7128
  new_packed_privs_array.reset();
7129
  is_all.reset();
7130
  // 1. Find all object permissions based on grantee_id, grantor_id, obj_type, obj_id.
7131
  OZ (build_table_and_col_priv_array_for_revoke_all(schema_guard,
7132
                                                    obj_priv_key,
7133
                                                    packed_table_privs,
7134
                                                    col_id_array,
7135
                                                    packed_col_privs_array));
7136
  CK (col_id_array.count() == packed_col_privs_array.count());
7137
  // 2. check permissions of table level.
7138
  for (int i = 0; OB_SUCC(ret) && i < obj_priv_array.count(); ++i) {
7139
    raw_obj_priv_to_be_revoked = obj_priv_array.at(i);
7140
    // Check whether the table-level permission exists on the table
7141
    OZ (ObOraPrivCheck::raw_obj_priv_exists_with_info(raw_obj_priv_to_be_revoked,
7142
                                                      packed_table_privs,
7143
                                                      exists,
7144
                                                      option_out),
7145
        raw_obj_priv_to_be_revoked, packed_table_privs, ret);
7146
    if (OB_SUCC(ret)) {
7147
      // If it exists, add the permission together with option to packed_table_privs_to_be_revoked,
7148
      // and added in packed_total_matched_privs means that the permission was found
7149
      // The permission may not exist as a table-level permission on the table
7150
      if (exists) {
7151
        OZ (ObPrivPacker::append_raw_obj_priv(option_out,
7152
                                              raw_obj_priv_to_be_revoked,
7153
                                              packed_table_privs_to_be_revoked));
7154
        OZ (ObPrivPacker::append_raw_obj_priv(option_out,
7155
                                              raw_obj_priv_to_be_revoked,
7156
                                              packed_total_matched_privs));
7157
      }
7158
    }
7159
  }
7160
  // Record the table key and its permission to be revoke in the return value
7161
  if (packed_table_privs_to_be_revoked) {
7162
    OZ (new_key_array.push_back(obj_priv_key));
7163
    OZ (new_packed_privs_array.push_back(packed_table_privs_to_be_revoked));
7164
    OZ (ObPrivPacker::get_total_obj_privs(packed_table_privs, own_priv_count));
7165
    OZ (ObPrivPacker::get_total_obj_privs(packed_table_privs_to_be_revoked, revoked_priv_count));
7166
    OX (is_all_single = own_priv_count == revoked_priv_count);
7167
    OZ (is_all.push_back(is_all_single));
7168
  }
7169
  // 3. Check column permissions
7170
  for (int i = 0; OB_SUCC(ret) && i < col_id_array.count(); ++i) {
7171
    // each column
7172
    new_col_key.col_id_ = col_id_array.at(i);
7173
    packed_col_privs = packed_col_privs_array.at(i);
7174
    packed_col_privs_to_be_revoked = 0;
7175
    for (int i = 0; OB_SUCC(ret) && i < obj_priv_array.count(); ++i) {
7176
      raw_obj_priv_to_be_revoked = obj_priv_array.at(i);
7177
      // Check only if the permission may be a column permission
7178
      if (ObOraPrivCheck::raw_priv_can_be_granted_to_column(raw_obj_priv_to_be_revoked)) {
7179
        // Check if the permission exists on the column
7180
        OZ (ObOraPrivCheck::raw_obj_priv_exists_with_info(raw_obj_priv_to_be_revoked,
7181
                                                          packed_col_privs,
7182
                                                          exists,
7183
                                                          option_out),
7184
            raw_obj_priv_to_be_revoked, packed_col_privs, ret);
7185
        if (OB_SUCC(ret)) {
7186
          if (exists) {
7187
            OZ (ObPrivPacker::append_raw_obj_priv(option_out,
7188
                                                  raw_obj_priv_to_be_revoked,
7189
                                                  packed_col_privs_to_be_revoked));
7190
            OZ (ObPrivPacker::append_raw_obj_priv(option_out,
7191
                                                  raw_obj_priv_to_be_revoked,
7192
                                                  packed_total_matched_privs));
7193
          }
7194
        }
7195
      }
7196
    }
7197
    // According to whether there are permissions in packed_col_privs_to_be_revoked, decide whether to keep the key
7198
    if (OB_SUCC(ret)) {
7199
      if (packed_col_privs_to_be_revoked) {
7200
        OZ (new_key_array.push_back(new_col_key));
7201
        OZ (new_packed_privs_array.push_back(packed_col_privs_to_be_revoked));
7202
        OZ (ObPrivPacker::get_total_obj_privs(packed_col_privs, own_priv_count));
7203
        OZ (ObPrivPacker::get_total_obj_privs(packed_col_privs_to_be_revoked, revoked_priv_count));
7204
        OX (is_all_single = own_priv_count == revoked_priv_count);
7205
        OZ (is_all.push_back(is_all_single));
7206
      }
7207
    }
7208
  }
7209
  // The three arrays should be the same size after processing.
7210
  CK (new_key_array.count() == new_packed_privs_array.count());
7211
  CK (new_key_array.count() == is_all.count());
7212
  // According to the number of packed_total_matched_privs, determine whether to try to revoke a permission that does not exist
7213
  OZ (ObPrivPacker::get_total_obj_privs(packed_total_matched_privs, org_n));
7214
  if (OB_SUCC(ret)) {
7215
    if (org_n < obj_priv_array.count()) {
7216
      ret = OB_ERR_CANNOT_REVOKE_PRIVILEGES_YOU_DID_NOT_GRANT;
7217
      LOG_WARN("try to revoke non exists privs", K(ret), K(org_n), K(obj_priv_array.count()));
7218
    }
7219
  }
7220
  return ret;
7221
}
7222

7223
/* According to the current obj priv, determine which ones need to be newly added priv array */
7224
int ObDDLOperator::set_need_flush_ora(
7225
    ObSchemaGetterGuard &schema_guard,
7226
    const share::schema::ObObjPrivSortKey &obj_priv_key,   /* in: obj priv key*/
7227
    const uint64_t option,                          /* in: new option */
7228
    const ObRawObjPrivArray &obj_priv_array,        /* in: new privs used want to add */
7229
    ObRawObjPrivArray &new_obj_priv_array)          /* out: new privs actually to be added */
7230
{
7231
  int ret = OB_SUCCESS;
7232
  ObPackedObjPriv obj_privs = 0;
7233
  ObRawObjPriv raw_obj_priv = 0;
7234
  bool exists = false;
7235
  OZ (schema_guard.get_obj_privs(obj_priv_key, obj_privs));
7236
  for (int i = 0; i < obj_priv_array.count() && OB_SUCC(ret); i++) {
7237
    raw_obj_priv = obj_priv_array.at(i);
7238
    OZ (ObOraPrivCheck::raw_obj_priv_exists(raw_obj_priv,
7239
                                            option,
7240
                                            obj_privs,
7241
                                            exists),
7242
        raw_obj_priv, option, obj_privs, ret);
7243
    if (OB_SUCC(ret) && !exists) {
7244
      OZ (new_obj_priv_array.push_back(raw_obj_priv));
7245
    }
7246
  }
7247
  return ret;
7248
}
7249

7250
/* Only handle authorization for one object, for example, one table, one column */
7251
int ObDDLOperator::grant_table(
7252
    const ObTablePrivSortKey &table_priv_key,
7253
    const ObPrivSet priv_set,
7254
    const ObString *ddl_stmt_str,
7255
    common::ObMySQLTransaction &trans,
7256
    const share::ObRawObjPrivArray &obj_priv_array,
7257
    const uint64_t option,
7258
    const share::schema::ObObjPrivSortKey &obj_priv_key)
7259
{
7260
  int ret = OB_SUCCESS;
7261
  ObRawObjPrivArray new_obj_priv_array;
7262
  const uint64_t tenant_id = table_priv_key.tenant_id_;
7263
  ObSchemaGetterGuard schema_guard;
7264
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
7265
  if (OB_ISNULL(schema_sql_service)) {
7266
    ret = OB_ERR_SYS;
7267
    LOG_ERROR("schama service_impl and schema manage must not null",
7268
        "schema_service_impl", schema_sql_service, K(ret));
7269
  } else if (!table_priv_key.is_valid()) {
7270
    ret = OB_INVALID_ARGUMENT;
7271
    LOG_WARN("table_priv_key is invalid", K(table_priv_key), K(ret));
7272
  } else if (0 == priv_set && obj_priv_array.count() == 0) {
7273
    //do nothing
7274
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
7275
    LOG_WARN("failed to get schema guard", K(ret));
7276
  } else {
7277
    ObPrivSet new_priv = priv_set;
7278
    ObPrivSet table_priv_set = OB_PRIV_SET_EMPTY;
7279
    if (OB_FAIL(schema_guard.get_table_priv_set(table_priv_key, table_priv_set))) {
7280
      LOG_WARN("get table priv set failed", K(ret));
7281
    } else {
7282
      bool need_flush = true;
7283
      new_priv |= table_priv_set;
7284
      need_flush = (new_priv != table_priv_set);
7285
      bool is_directory = false;
7286
      if (obj_priv_array.count() > 0
7287
          && static_cast<uint64_t>(ObObjectType::DIRECTORY) == obj_priv_key.obj_type_) {
7288
        is_directory = true;
7289
      }
7290

7291
      if (need_flush && !is_directory) {
7292
        int64_t new_schema_version = OB_INVALID_VERSION;
7293
        int64_t new_schema_version_ora = OB_INVALID_VERSION;
7294
        if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
7295
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
7296
        } else if (obj_priv_array.count() > 0) {
7297
          OZ (set_need_flush_ora(schema_guard, obj_priv_key, option, obj_priv_array,
7298
            new_obj_priv_array));
7299
          if (new_obj_priv_array.count() > 0) {
7300
            OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version_ora));
7301
          }
7302
        }
7303
        OZ (schema_sql_service->get_priv_sql_service().grant_table(
7304
            table_priv_key, new_priv, new_schema_version, ddl_stmt_str, trans,
7305
            new_obj_priv_array, option, obj_priv_key, new_schema_version_ora, true, false),
7306
            table_priv_key, ret, false);
7307
      } else if (obj_priv_array.count() > 0) {
7308
        OZ (set_need_flush_ora(schema_guard, obj_priv_key, option, obj_priv_array,
7309
          new_obj_priv_array));
7310
        if (new_obj_priv_array.count() > 0) {
7311
          int64_t new_schema_version_ora = OB_INVALID_VERSION;
7312
          OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version_ora));
7313
          OZ (schema_sql_service->get_priv_sql_service().grant_table_ora_only(
7314
            ddl_stmt_str, trans, new_obj_priv_array, option, obj_priv_key,
7315
            new_schema_version_ora, false, false),table_priv_key, ret);
7316
        }
7317
      }
7318
    }
7319
  }
7320

7321
  return ret;
7322
}
7323

7324
/* in: grantor, grantee, obj_type, obj_id
7325
   out: table_packed_privs
7326
        array of col_id which has col privs
7327
        array of col_packed_privs */
7328
int ObDDLOperator::build_table_and_col_priv_array_for_revoke_all(
7329
    ObSchemaGetterGuard &schema_guard,
7330
    const ObObjPrivSortKey &obj_priv_key,
7331
    ObPackedObjPriv &packed_table_priv,
7332
    ObSEArray<uint64_t, 4> &col_id_array,
7333
    ObSEArray<ObPackedObjPriv, 4> &packed_privs_array)
7334
{
7335
  int ret = OB_SUCCESS;
7336
  ObSEArray<const ObObjPriv *, 4> obj_priv_array;
7337
  uint64_t col_id = 0;
7338
  CK (obj_priv_key.is_valid());
7339
  OZ (schema_guard.get_obj_privs_in_grantor_ur_obj_id(obj_priv_key.tenant_id_,
7340
                                                      obj_priv_key,
7341
                                                      obj_priv_array));
7342
  for (int i = 0; i < obj_priv_array.count() && OB_SUCC(ret); i++) {
7343
    const ObObjPriv *obj_priv = obj_priv_array.at(i);
7344
    if (obj_priv != NULL) {
7345
      col_id = obj_priv->get_col_id();
7346
      if (col_id == OBJ_LEVEL_FOR_TAB_PRIV) {
7347
        packed_table_priv = obj_priv->get_obj_privs();
7348
      } else {
7349
        OZ (col_id_array.push_back(col_id));
7350
        OZ (packed_privs_array.push_back(obj_priv->get_obj_privs()));
7351
      }
7352
    }
7353
  }
7354

7355
  return ret;
7356
}
7357

7358
int ObDDLOperator::revoke_table_all(
7359
    ObSchemaGetterGuard &schema_guard,
7360
    const uint64_t tenant_id,
7361
    const ObObjPrivSortKey &obj_priv_key,
7362
    ObString &ddl_sql,
7363
    common::ObMySQLTransaction &trans)
7364
{
7365
  int ret = OB_SUCCESS;
7366
  int64_t new_schema_version = OB_INVALID_VERSION;
7367
  share::ObPackedObjPriv packed_table_privs = 0;
7368
  ObRawObjPrivArray raw_priv_array;
7369
  ObRawObjPrivArray option_raw_array;
7370
  ObSEArray<uint64_t, 4> col_id_array;
7371
  ObSEArray<ObPackedObjPriv, 4> packed_privs_array;
7372
  ObObjPrivSortKey new_key = obj_priv_key;
7373
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
7374
  if (OB_ISNULL(schema_sql_service)) {
7375
    ret = OB_ERR_SYS;
7376
    LOG_ERROR("schama service_impl and schema manage must not null",
7377
        "schema_service_impl", schema_sql_service,
7378
        K(ret));
7379
  }
7380
  OZ (build_table_and_col_priv_array_for_revoke_all(schema_guard,
7381
                                                    obj_priv_key,
7382
                                                    packed_table_privs,
7383
                                                    col_id_array,
7384
                                                    packed_privs_array));
7385
  if (OB_SUCC(ret)) {
7386
    // 1. table-level permissions
7387
    if (packed_table_privs > 0) {
7388
      OZ (ObPrivPacker::raw_obj_priv_from_pack(packed_table_privs, raw_priv_array));
7389
      OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
7390
      OZ (schema_sql_service->get_priv_sql_service().revoke_table_ora(
7391
        new_key, raw_priv_array, new_schema_version, &ddl_sql, trans, true));
7392
      OZ (ObPrivPacker::raw_option_obj_priv_from_pack(packed_table_privs, option_raw_array));
7393
      OZ (revoke_obj_cascade(schema_guard, new_key.grantee_id_,
7394
          trans, new_key, option_raw_array));
7395
    }
7396
    // 2. column-level permissions
7397
    for (int i = 0; i < col_id_array.count() && OB_SUCC(ret); i++) {
7398
      new_key.col_id_ = col_id_array.at(i);
7399
      OZ (ObPrivPacker::raw_obj_priv_from_pack(packed_privs_array.at(i), raw_priv_array));
7400
      OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
7401
      OZ (schema_sql_service->get_priv_sql_service().revoke_table_ora(
7402
        new_key, raw_priv_array, new_schema_version, &ddl_sql, trans, true));
7403
      OZ (ObPrivPacker::raw_option_obj_priv_from_pack(packed_privs_array.at(i),
7404
          option_raw_array));
7405
      OZ (revoke_obj_cascade(schema_guard, new_key.grantee_id_,
7406
          trans, new_key, option_raw_array));
7407
    }
7408
  }
7409
  return ret;
7410
}
7411

7412
int ObDDLOperator::build_next_level_revoke_obj(
7413
    ObSchemaGetterGuard &schema_guard,
7414
    const ObObjPrivSortKey &old_key,
7415
    ObObjPrivSortKey &new_key,
7416
    ObIArray<const ObObjPriv *> &obj_privs)
7417
{
7418
  int ret = OB_SUCCESS;
7419
  new_key = old_key;
7420
  new_key.grantor_id_ = new_key.grantee_id_;
7421
  OZ (schema_guard.get_obj_privs_in_grantor_obj_id(new_key.tenant_id_,
7422
                                                   new_key,
7423
                                                   obj_privs));
7424
  return ret;
7425
}
7426

7427
/* After processing the top-level revoke obj, then call this function to process revoke recursively.
7428
   1. According to the obj key of the upper layer, change grantee to grantor and find new permissions that need to be reclaimed
7429
   2. If there are permissions that need to be reclaimed, call revoke obj ora, if not, end.
7430
   3. calling self. If a new grantee is found back to the original grantee, the end */
7431
int ObDDLOperator::revoke_obj_cascade(
7432
    ObSchemaGetterGuard &schema_guard,
7433
    const uint64_t start_grantee_id,     /* in: check circle */
7434
    common::ObMySQLTransaction &trans,
7435
    const ObObjPrivSortKey &old_key,     /* in: old key */
7436
    ObRawObjPrivArray &old_array)        /* in: privs that have grantable option */
7437
{
7438
  int ret = OB_SUCCESS;
7439
  uint64_t tenant_id = old_key.tenant_id_;
7440
  int64_t new_schema_version = OB_INVALID_VERSION;
7441
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
7442
  ObObjPrivSortKey new_key;
7443
  ObRawObjPrivArray grantable_array;
7444
  ObRawObjPrivArray new_array;
7445
  ObSEArray<const ObObjPriv *, 4> obj_privs;
7446
  bool is_all = false;
7447
  if (old_array.count() > 0) {
7448
    OZ (build_next_level_revoke_obj(schema_guard, old_key, new_key, obj_privs));
7449
    /* If there are multiple, it means that this user has delegated to multiple other users */
7450
    if (obj_privs.count() > 0) {
7451
      ObPackedObjPriv old_p_list;
7452
      ObPackedObjPriv old_opt_p_list;
7453
      ObPackedObjPriv privs_revoke_this_level;
7454
      ObPackedObjPriv privs_revoke_next_level;
7455

7456
      OZ (ObPrivPacker::pack_raw_obj_priv_list(NO_OPTION, old_array, old_p_list));
7457
      OZ (ObPrivPacker::pack_raw_obj_priv_list(GRANT_OPTION, old_array, old_opt_p_list));
7458

7459
      for (int i = 0; OB_SUCC(ret) && i < obj_privs.count(); i++) {
7460
        const ObObjPriv* obj_priv = obj_privs.at(i);
7461
        if (obj_priv != NULL) {
7462
          /* 1. cross join grantee privs and grantor privs without option */
7463
          privs_revoke_this_level = old_p_list & obj_priv->get_obj_privs();
7464

7465
          if (privs_revoke_this_level > 0) {
7466
            /* 2. build new_Key */
7467
            new_key.grantee_id_ = obj_priv->get_grantee_id();
7468
            /* 2. build new array */
7469
            OZ (ObPrivPacker::raw_obj_priv_from_pack(privs_revoke_this_level, new_array));
7470
            OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
7471
            OX (is_all = (new_array.count() == old_array.count()));
7472
            OZ (schema_sql_service->get_priv_sql_service().revoke_table_ora(
7473
                  new_key, new_array, new_schema_version, NULL, trans, is_all));
7474
            /* 3. new grantee is equ org grantee. end */
7475
            if (OB_SUCC(ret)) {
7476
              if (new_key.grantee_id_ == start_grantee_id) {
7477
              } else {
7478
                /* 3. decide privs to be revoked recursively */
7479
                privs_revoke_next_level = old_opt_p_list & obj_priv->get_obj_privs();
7480
                if (privs_revoke_next_level > 0) {
7481
                  OZ (ObPrivPacker::raw_obj_priv_from_pack(privs_revoke_next_level, new_array));
7482
                  OZ (revoke_obj_cascade(schema_guard, start_grantee_id, trans,
7483
                      new_key, new_array));
7484
                }
7485
              }
7486
            }
7487
          }
7488
        }
7489
      }
7490
    }
7491
  }
7492
  return ret;
7493
}
7494

7495
/* Get all foreign keys of a user referencing the specified parent table */
7496
int ObDDLOperator::build_fk_array_by_parent_table(
7497
  uint64_t tenant_id,
7498
  ObSchemaGetterGuard &schema_guard,
7499
  const ObString &grantee_name,
7500
  const ObString &db_name,
7501
  const ObString &tab_name,
7502
  ObIArray<ObDropForeignKeyArg> &drop_fk_array,
7503
  ObIArray<uint64_t> &ref_tab_id_array)
7504
{
7505
  int ret = OB_SUCCESS;
7506
  const ObTableSchema *table_schema = NULL;
7507

7508
  OZ (schema_guard.get_table_schema(tenant_id, db_name, tab_name, false, table_schema));
7509
  if (OB_SUCC(ret)) {
7510
    if (NULL == table_schema) {
7511
      ret = OB_TABLE_NOT_EXIST;
7512
    } else {
7513
      uint64_t db_id = OB_INVALID_ID;
7514
      OZ (schema_guard.get_database_id(tenant_id, grantee_name, db_id));
7515
      /* Traverse all child tables referencing the parent table, if the owner of the child table is grantee, add drop fk array */
7516
      const ObIArray<ObForeignKeyInfo> &fk_array = table_schema->get_foreign_key_infos();
7517
      for (int i = 0; OB_SUCC(ret) && i < fk_array.count(); i++) {
7518
        const ObForeignKeyInfo &fk_info = fk_array.at(i);
7519
        const ObSimpleTableSchemaV2 *ref_table = NULL;
7520
        OZ (schema_guard.get_simple_table_schema(tenant_id, fk_info.child_table_id_, ref_table));
7521
        if (OB_SUCC(ret)) {
7522
          if (ref_table == NULL) {
7523
            ret = OB_TABLE_NOT_EXIST;
7524
          } else if (ref_table->get_database_id() ==  db_id) {
7525
            ObDropForeignKeyArg fk_arg;
7526
            fk_arg.foreign_key_name_ = fk_info.foreign_key_name_;
7527
            OZ (drop_fk_array.push_back(fk_arg));
7528
            OZ (ref_tab_id_array.push_back(ref_table->get_table_id()));
7529
          }
7530
        }
7531
      }
7532
    }
7533
  }
7534

7535
  return ret;
7536
}
7537

7538
int ObDDLOperator::drop_fk_cascade(
7539
    uint64_t tenant_id,
7540
    ObSchemaGetterGuard &schema_guard,
7541
    bool has_ref_priv,
7542
    bool has_no_cascade,
7543
    const ObString &grantee_name,
7544
    const ObString &parent_db_name,
7545
    const ObString &parent_tab_name,
7546
    ObMySQLTransaction &trans)
7547
{
7548
  int ret = OB_SUCCESS;
7549
  if (has_ref_priv) {
7550
    ObSEArray<ObDropForeignKeyArg, 4> drop_fk_array;
7551
    ObSEArray<uint64_t, 4> ref_tab_id_array;
7552
    OZ (build_fk_array_by_parent_table(tenant_id,
7553
                                       schema_guard,
7554
                                       grantee_name,
7555
                                       parent_db_name,
7556
                                       parent_tab_name,
7557
                                       drop_fk_array,
7558
                                       ref_tab_id_array));
7559
    if (OB_SUCC(ret)) {
7560
      if (drop_fk_array.count() > 0) {
7561
        if (has_no_cascade) {
7562
          ret = OB_ERR_CASCADE_CONSTRAINTS_MUST_BE_SPECIFIED_TO_PERFORM_THIS_REVOKE;
7563
        } else {
7564
          for (int i = 0; OB_SUCC(ret) && i < drop_fk_array.count(); i++) {
7565
            const ObTableSchema *ref_tab = NULL;
7566
            const ObDropForeignKeyArg &drop_fk = drop_fk_array.at(i);
7567

7568
            OZ (schema_guard.get_table_schema(tenant_id,
7569
                ref_tab_id_array.at(i), ref_tab));
7570
            if (OB_SUCC(ret)) {
7571
              if (ref_tab == NULL) {
7572
                ret = OB_TABLE_NOT_EXIST;
7573
              } else {
7574
                const ObForeignKeyInfo *parent_table_mock_foreign_key_info = NULL;
7575
                OZ (alter_table_drop_foreign_key(*ref_tab, drop_fk, trans, parent_table_mock_foreign_key_info, ref_tab->get_in_offline_ddl_white_list()));
7576
                if (OB_SUCC(ret) && NULL != parent_table_mock_foreign_key_info) {
7577
                  ret = OB_ERR_UNEXPECTED;
7578
                  LOG_WARN("parent_table_mock_foreign_key_info in oracle mode is unexpected", K(ret));
7579
                }
7580
              }
7581
            }
7582
          }
7583
        }
7584
      }
7585
    }
7586
  }
7587

7588
  return ret;
7589
}
7590

7591
int ObDDLOperator::revoke_table(
7592
    const ObTablePrivSortKey &table_priv_key,
7593
    const ObPrivSet priv_set,
7594
    common::ObMySQLTransaction &trans,
7595
    const ObObjPrivSortKey &obj_priv_key,
7596
    const share::ObRawObjPrivArray &obj_priv_array,
7597
    const bool revoke_all_ora)
7598
{
7599
  int ret = OB_SUCCESS;
7600
  const uint64_t tenant_id = table_priv_key.tenant_id_;
7601
  ObSchemaGetterGuard schema_guard;
7602
  ObSchemaService *schema_sql_service = schema_service_.get_schema_service();
7603
  if (OB_ISNULL(schema_sql_service)) {
7604
    ret = OB_ERR_SYS;
7605
    LOG_ERROR("schama service_impl and schema manage must not null",
7606
        "schema_service_impl", schema_sql_service,
7607
        K(ret));
7608
  } else if (!table_priv_key.is_valid()) {
7609
    ret = OB_INVALID_ARGUMENT;
7610
    LOG_WARN("db_priv_key is invalid", K(table_priv_key), K(ret));
7611
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
7612
    LOG_WARN("failed to get schema guard", K(ret));
7613
  } else {
7614
    ObPrivSet table_priv_set = OB_PRIV_SET_EMPTY;
7615
    if (OB_FAIL(schema_guard.get_table_priv_set(table_priv_key, table_priv_set))) {
7616
      LOG_WARN("get table priv set failed", K(ret));
7617
    } else if (OB_PRIV_SET_EMPTY == table_priv_set
7618
               && !revoke_all_ora
7619
               && obj_priv_array.count() == 0) {
7620
      ret = OB_ERR_CANNOT_REVOKE_PRIVILEGES_YOU_DID_NOT_GRANT;
7621
      LOG_WARN("No such grant to revoke", K(table_priv_key), K(ret));
7622
    } else if (0 == priv_set && obj_priv_array.count() == 0) {
7623
      // do-nothing
7624
    } else {
7625
      ObPrivSet new_priv = table_priv_set & (~priv_set);
7626
      /* If there is an intersection between the existing permissions and the permissions that require revoke */
7627
      if (table_priv_set & priv_set) {
7628
        ObSqlString ddl_stmt_str;
7629
        ObString ddl_sql;
7630
        const ObUserInfo *user_info = NULL;
7631
        ObNeedPriv need_priv;
7632
        share::ObRawObjPrivArray option_priv_array;
7633

7634
        need_priv.db_ = table_priv_key.db_;
7635
        need_priv.table_ = table_priv_key.table_;
7636
        need_priv.priv_level_ = OB_PRIV_TABLE_LEVEL;
7637
        need_priv.priv_set_ = table_priv_set & priv_set; //priv to revoke
7638
        int64_t new_schema_version = OB_INVALID_VERSION;
7639
        int64_t new_schema_version_ora = OB_INVALID_VERSION;
7640
        bool is_all = false;
7641
        bool has_ref_priv = false;
7642
        if (OB_FAIL(check_obj_privs_exists(schema_guard, obj_priv_key,
7643
            obj_priv_array, option_priv_array, is_all))) {
7644
          LOG_WARN("priv not exits", K(obj_priv_array), K(ret));
7645
        } else if (OB_FAIL(schema_guard.get_user_info(tenant_id, table_priv_key.user_id_, user_info))) {
7646
          LOG_WARN("get user info failed", K(table_priv_key), K(ret));
7647
        } else if (OB_ISNULL(user_info)) {
7648
          ret = OB_ERR_UNEXPECTED;
7649
          LOG_WARN("user not exist", K(table_priv_key), K(ret));
7650
        } else if (OB_FAIL(drop_fk_cascade(tenant_id,
7651
                                           schema_guard,
7652
                                           has_ref_priv,
7653
                                           true, /* has no cascade */
7654
                                           user_info->get_user_name_str(), /* grantee name */
7655
                                           table_priv_key.db_,
7656
                                           table_priv_key.table_,
7657
                                           trans))) {
7658
          LOG_WARN("drop fk cascase failed", K(table_priv_key), K(ret));
7659
        } else if (OB_FAIL(ObDDLSqlGenerator::gen_table_priv_sql(
7660
            ObAccountArg(user_info->get_user_name_str(), user_info->get_host_name_str()),
7661
            need_priv,
7662
            false, /*is_grant*/
7663
            ddl_stmt_str))) {
7664
          LOG_WARN("gen_table_priv_sql failed", K(ret), K(need_priv));
7665
        } else if (FALSE_IT(ddl_sql = ddl_stmt_str.string())) {
7666
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id,
7667
                           new_schema_version))) {
7668
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
7669
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id,
7670
                           new_schema_version_ora))) {
7671
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
7672
        } else if (OB_FAIL(schema_sql_service->get_priv_sql_service().revoke_table(
7673
            table_priv_key, new_priv, new_schema_version, &ddl_sql, trans,
7674
            new_schema_version_ora, obj_priv_key, obj_priv_array, is_all))) {
7675
          LOG_WARN("Failed to revoke table", K(table_priv_key), K(ret));
7676
        } else {
7677
          OZ (revoke_obj_cascade(schema_guard, obj_priv_key.grantee_id_,
7678
              trans, obj_priv_key, option_priv_array));
7679
        }
7680
        // In revoke all statement, if you have permission, it will come here, and the content of mysql will be processed first.
7681
        if (OB_SUCC(ret) && revoke_all_ora) {
7682
          OZ (revoke_table_all(schema_guard, tenant_id, obj_priv_key, ddl_sql, trans));
7683
        }
7684
      } else {
7685
        ObSqlString ddl_stmt_str;
7686
        ObString ddl_sql;
7687
        const ObUserInfo *user_info = NULL;
7688
        int64_t new_schema_version = OB_INVALID_VERSION;
7689
        share::ObRawObjPrivArray option_priv_array;
7690
        ObRawObjPrivArray raw_priv_array;
7691
        ObArray<bool> is_all;
7692
        ObArray<ObObjPrivSortKey> priv_key_array;
7693
        ObArray<ObPackedObjPriv> packed_privs_array;
7694
        ObRawObjPrivArray option_raw_array;
7695
        // In oracle mode, need to check revoke permission exists, only need to reclaim oracle permission
7696
        // Due to the existence of column permissions, one obj_priv_key is expanded into multiple,
7697
        // and each key represents a column
7698
        OZ (check_obj_privs_exists_including_col_privs(schema_guard, obj_priv_key,
7699
            obj_priv_array, priv_key_array, packed_privs_array, is_all));
7700
        OZ (schema_guard.get_user_info(tenant_id, table_priv_key.user_id_, user_info));
7701
        if (OB_SUCC(ret) && user_info == NULL) {
7702
          ret = OB_ERR_UNEXPECTED;
7703
          LOG_WARN("user not exist", K(table_priv_key), K(ret));
7704
        }
7705

7706
        OZ (ObDDLSqlGenerator::gen_table_priv_sql_ora(
7707
            ObAccountArg(user_info->get_user_name_str(), user_info->get_host_name_str()),
7708
            table_priv_key,
7709
            revoke_all_ora,
7710
            obj_priv_array,
7711
            false,
7712
            ddl_stmt_str));
7713
        OX (ddl_sql = ddl_stmt_str.string());
7714
        if (OB_SUCC(ret)) {
7715
          if (revoke_all_ora) {
7716
            OZ (revoke_table_all(schema_guard, tenant_id, obj_priv_key, ddl_sql, trans));
7717
          } else if (obj_priv_array.count() > 0) {
7718
            // Revoke table permissions and column permissions one by one
7719
            for (int i = 0; OB_SUCC(ret) && i < priv_key_array.count(); ++i) {
7720
              const ObObjPrivSortKey &priv_key = priv_key_array.at(i);
7721
              OZ (ObPrivPacker::raw_obj_priv_from_pack(packed_privs_array.at(i), raw_priv_array));
7722
              OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
7723
              OZ (schema_sql_service->get_priv_sql_service().revoke_table_ora(
7724
                priv_key, raw_priv_array, new_schema_version,
7725
                &ddl_sql, trans, is_all.at(i)));
7726
              OZ (ObPrivPacker::raw_option_obj_priv_from_pack(packed_privs_array.at(i),
7727
                  option_raw_array));
7728
              OZ (revoke_obj_cascade(schema_guard, priv_key.grantee_id_,
7729
                  trans, priv_key, option_raw_array));
7730
            }
7731
          }
7732
        }
7733
      }
7734
    }
7735
  }
7736
  return ret;
7737
}
7738

7739
int ObDDLOperator::get_flush_role_array(
7740
  const uint64_t option,
7741
  const common::ObIArray<uint64_t> &org_role_ids,
7742
  bool &need_flush,
7743
  bool is_grant,
7744
  const ObUserInfo &user_info,
7745
  common::ObIArray<uint64_t> &role_ids)
7746
{
7747
  int ret = OB_SUCCESS;
7748
  need_flush = false;
7749
  if (org_role_ids.count() > 0) {
7750
    if (is_grant) {
7751
      for (int64_t i = 0; OB_SUCC(ret) && i < org_role_ids.count(); ++i) {
7752
        const uint64_t role_id = org_role_ids.at(i);
7753
        if (!user_info.role_exists(role_id, option)) {
7754
          need_flush = true;
7755
          OZ (role_ids.push_back(role_id));
7756
        }
7757
      }
7758
    } else {
7759
      need_flush = true;
7760
      OZ (role_ids.assign(org_role_ids));
7761
    }
7762
  }
7763
  return ret;
7764
}
7765

7766
int ObDDLOperator::grant_revoke_role(
7767
    const uint64_t tenant_id,
7768
    const ObUserInfo &user_info,
7769
    const common::ObIArray<uint64_t> &org_role_ids,
7770
    // When specified_role_info is not empty, use it as role_info instead of reading it in the schema.
7771
    const ObUserInfo *specified_role_info,
7772
    common::ObMySQLTransaction &trans,
7773
    const bool log_operation,
7774
    const bool is_grant,
7775
    const uint64_t option)
7776
{
7777
  int ret = OB_SUCCESS;
7778
  ObSchemaService *schema_service = schema_service_.get_schema_service();
7779
  ObSchemaGetterGuard schema_guard;
7780
  int64_t new_schema_version = OB_INVALID_VERSION;
7781
  ObString ddl_sql;
7782

7783
  if (OB_ISNULL(schema_service)) {
7784
    ret = OB_ERR_SYS;
7785
    LOG_ERROR("schema_service must not null", K(ret));
7786
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
7787
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
7788
  } else if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
7789
    LOG_WARN("failed to get schema guard", K(ret));
7790
  } else {
7791
    common::ObSEArray<uint64_t, 8> role_ids;
7792
    bool need_flush = false;
7793
    OZ (get_flush_role_array(option,
7794
                             org_role_ids,
7795
                             need_flush,
7796
                             is_grant,
7797
                             user_info,
7798
                             role_ids));
7799
    if (OB_SUCC(ret) && need_flush) {
7800
      common::ObSqlString sql_string;
7801
      if (OB_FAIL(sql_string.append_fmt(is_grant ? "GRANT ": "REVOKE "))) {
7802
        LOG_WARN("append sql failed", K(ret));
7803
      } else if (OB_NOT_NULL(specified_role_info)) {
7804
        // Use single specified role info
7805
        if (OB_FAIL(sql_string.append_fmt("%s", specified_role_info->get_user_name()))) {
7806
          LOG_WARN("append sql failed", K(ret));
7807
        }
7808
      } else {
7809
        // Use role info obtained from schema
7810
        for (int64_t i = 0; OB_SUCC(ret) && i < role_ids.count(); ++i) {
7811
          const uint64_t role_id = role_ids.at(i);
7812
          const ObUserInfo *role_info = NULL;
7813
          if (0 != i) {
7814
            if (OB_FAIL(sql_string.append_fmt(","))) {
7815
              LOG_WARN("append sql failed", K(ret));
7816
            }
7817
          }
7818
          if (FAILEDx(schema_guard.get_user_info(tenant_id, role_id, role_info))) {
7819
            LOG_WARN("Failed to get role info", K(ret), K(tenant_id), K(role_id));
7820
          } else if (NULL == role_info) {
7821
            ret = OB_ERR_UNEXPECTED;
7822
            LOG_WARN("role doesn't exist", K(ret), K(role_id));
7823
          } else if (OB_FAIL(sql_string.append_fmt("%s", role_info->get_user_name()))) {
7824
            LOG_WARN("append sql failed", K(ret));
7825
          }
7826
        }
7827
      }
7828
      if (OB_SUCC(ret)) {
7829
        if (OB_FAIL(sql_string.append_fmt(is_grant ? " TO %s": " FROM %s", user_info.get_user_name()))) {
7830
          LOG_WARN("append sql failed", K(ret));
7831
        } else if (is_grant && option != NO_OPTION && OB_FAIL(sql_string.append_fmt(
7832
                                                                          " WITH ADMIN OPTION"))) {
7833
          LOG_WARN("append sql failed", K(ret));
7834
        } else {
7835
          ddl_sql = sql_string.string();
7836
          LOG_WARN("wang sql ", K(ddl_sql), K(sql_string));
7837
        }
7838
      }
7839
      if (OB_SUCC(ret)) {
7840
        if (OB_FAIL(schema_service->get_priv_sql_service().grant_revoke_role(tenant_id,
7841
            user_info,
7842
            role_ids,
7843
            specified_role_info,
7844
            new_schema_version,
7845
            log_operation ? &ddl_sql : NULL,
7846
            trans,
7847
            is_grant,
7848
            schema_guard,
7849
            option))) {
7850
          LOG_WARN("Failed to revoke role", K(user_info), K(ret));
7851
        }
7852
      }
7853
    }
7854
  }
7855

7856
  return ret;
7857
}
7858

7859
int ObDDLOperator::get_flush_priv_array(
7860
    const uint64_t option,
7861
    const share::ObRawPrivArray &priv_array,
7862
    const ObSysPriv *sys_priv,
7863
    share::ObRawPrivArray &new_priv_array,
7864
    bool &need_flush,
7865
    const bool is_grant,
7866
    const ObUserInfo &user_info)
7867
{
7868
  int ret = OB_SUCCESS;
7869
  int64_t raw_priv = 0;
7870
  bool exists = false;
7871

7872
  need_flush = FALSE;
7873
  if (is_grant) {
7874
    if (sys_priv == NULL) {
7875
      need_flush = true;
7876
      OZ (new_priv_array.assign(priv_array));
7877
    } else {
7878
      ARRAY_FOREACH(priv_array, idx) {
7879
        raw_priv = priv_array.at(idx);
7880
        OZ (ObOraPrivCheck::raw_sys_priv_exists(option,
7881
                                                raw_priv,
7882
                                                sys_priv->get_priv_array(),
7883
                                                exists));
7884
        if (OB_SUCC(ret) && !exists) {
7885
          need_flush = true;
7886
          OZ (new_priv_array.push_back(raw_priv));
7887
        }
7888
      }
7889
    }
7890
  }
7891
  else {
7892
    need_flush = true;
7893
    if (sys_priv == NULL) {
7894
      ret = OB_ERR_SYSTEM_PRIVILEGES_NOT_GRANTED_TO;
7895
      LOG_USER_ERROR(OB_ERR_SYSTEM_PRIVILEGES_NOT_GRANTED_TO,
7896
                     user_info.get_user_name_str().length(),
7897
                     user_info.get_user_name_str().ptr());
7898
      LOG_WARN("revoke sys priv fail, sys priv not exists", K(priv_array), K(ret));
7899
    } else {
7900
      ARRAY_FOREACH(priv_array, idx) {
7901
        raw_priv = priv_array.at(idx);
7902
        OZ (ObOraPrivCheck::raw_sys_priv_exists(option,
7903
                                                raw_priv,
7904
                                                sys_priv->get_priv_array(),
7905
                                                exists));
7906
        if (OB_SUCC(ret) && !exists) {
7907
          ret = OB_ERR_SYSTEM_PRIVILEGES_NOT_GRANTED_TO;
7908
          LOG_USER_ERROR(OB_ERR_SYSTEM_PRIVILEGES_NOT_GRANTED_TO,
7909
                     user_info.get_user_name_str().length(),
7910
                     user_info.get_user_name_str().ptr());
7911
          LOG_WARN("revoke sys priv fail, sys priv not exists", K(priv_array), K(ret));
7912
        }
7913
        OZ (new_priv_array.push_back(raw_priv));
7914
      }
7915
    }
7916
  }
7917
  return ret;
7918
}
7919

7920
int ObDDLOperator::grant_sys_priv_to_ur(
7921
    const uint64_t tenant_id,
7922
    const uint64_t grantee_id,
7923
    const ObSysPriv* sys_priv,
7924
    const uint64_t option,
7925
    const ObRawPrivArray priv_array,
7926
    common::ObMySQLTransaction &trans,
7927
    const bool is_grant,
7928
    const common::ObString *ddl_stmt_str,
7929
    ObSchemaGetterGuard &schema_guard)
7930
{
7931
  int ret = OB_SUCCESS;
7932
  ObSchemaService *schema_service = schema_service_.get_schema_service();
7933
  int64_t new_schema_version = OB_INVALID_VERSION;
7934
  ObRawPrivArray new_priv_array;
7935
  bool need_flush;
7936
  const ObUserInfo *user_info = NULL;
7937
  if (OB_ISNULL(schema_service)) {
7938
    ret = OB_ERR_SYS;
7939
    LOG_ERROR("schema_service must not null", K(ret));
7940
  }
7941
  OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version), tenant_id);
7942
  OZ (schema_guard.get_user_info(tenant_id, grantee_id, user_info));
7943
  OZ (get_flush_priv_array(option,
7944
                           priv_array,
7945
                           sys_priv,
7946
                           new_priv_array,
7947
                           need_flush,
7948
                           is_grant,
7949
                           *user_info));
7950
  if (OB_SUCC(ret) && need_flush) {
7951
    if (is_grant) {
7952
      CK (new_priv_array.count() > 0);
7953
      OZ (schema_service->get_priv_sql_service().grant_sys_priv_to_ur(tenant_id,
7954
                                                                      grantee_id,
7955
                                                                      option,
7956
                                                                      new_priv_array,
7957
                                                                      new_schema_version,
7958
                                                                      ddl_stmt_str,
7959
                                                                      trans,
7960
                                                                      is_grant,
7961
                                                                      false));
7962
    } else {
7963
      int n_cnt = 0;
7964
      bool revoke_all_flag = false;
7965
      /* revoke */
7966
      CK(sys_priv != NULL);
7967
      OZ (ObPrivPacker::get_total_privs(sys_priv->get_priv_array(), n_cnt));
7968
      revoke_all_flag = (n_cnt == new_priv_array.count());
7969
        /* revoke all */
7970
      OZ (schema_service->get_priv_sql_service().grant_sys_priv_to_ur(tenant_id,
7971
                                                                      grantee_id,
7972
                                                                      option,
7973
                                                                      new_priv_array,
7974
                                                                      new_schema_version,
7975
                                                                      ddl_stmt_str,
7976
                                                                      trans,
7977
                                                                      is_grant,
7978
                                                                      revoke_all_flag),
7979
           tenant_id, grantee_id, new_priv_array, is_grant, revoke_all_flag);
7980
    }
7981
  }
7982
  return ret;
7983
}
7984

7985
//----End of functions for managing privileges----
7986

7987
//----Functions for managing outlines----
7988
int ObDDLOperator::create_outline(ObOutlineInfo &outline_info,
7989
                                  ObMySQLTransaction &trans,
7990
                                  const ObString *ddl_stmt_str/*=NULL*/)
7991
{
7992
  int ret = OB_SUCCESS;
7993
  uint64_t new_outline_id = OB_INVALID_ID;
7994
  const uint64_t tenant_id = outline_info.get_tenant_id();
7995
  int64_t new_schema_version = OB_INVALID_VERSION;
7996
  ObSchemaService *schema_service = schema_service_.get_schema_service();
7997

7998
  if (OB_ISNULL(schema_service)) {
7999
    ret = OB_ERR_SYS;
8000
    LOG_ERROR("schema_service must not null", K(ret));
8001
  } // else if (!outline_info.is_valid()) {
8002
  //   ret = OB_INVALID_ARGUMENT;
8003
  //   LOG_ERROR("outline is invalid", K(outline_info), K(ret));
8004
  // }
8005
  else if (OB_FAIL(schema_service->fetch_new_outline_id(tenant_id, new_outline_id))) {
8006
    LOG_WARN("failed to fetch new_outline_id", K(tenant_id), K(ret));
8007
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8008
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8009
  } else {
8010
    outline_info.set_outline_id(new_outline_id);
8011
    outline_info.set_schema_version(new_schema_version);
8012
    if (OB_FAIL(schema_service->get_outline_sql_service().insert_outline(
8013
        outline_info, trans, ddl_stmt_str))) {
8014
      LOG_WARN("insert outline info failed", K(outline_info), K(ret));
8015
    }
8016
  }
8017
  return ret;
8018
}
8019

8020
int ObDDLOperator::replace_outline(ObOutlineInfo &outline_info,
8021
                                   ObMySQLTransaction &trans,
8022
                                   const ObString *ddl_stmt_str/*=NULL*/)
8023
{
8024
  int ret = OB_SUCCESS;
8025
  const uint64_t tenant_id = outline_info.get_tenant_id();
8026
  int64_t new_schema_version = OB_INVALID_VERSION;
8027
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8028
  if (OB_ISNULL(schema_service)) {
8029
    ret = OB_ERR_SYS;
8030
    LOG_ERROR("schema_service is NULL", K(ret));
8031
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8032
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8033
  } else {
8034
    outline_info.set_schema_version(new_schema_version);
8035
    if (OB_FAIL(schema_service->get_outline_sql_service().replace_outline(
8036
        outline_info, trans, ddl_stmt_str))) {
8037
      LOG_WARN("replace outline info failed", K(outline_info), K(ret));
8038
    } else {/*do nothing*/}
8039
  }
8040
  return ret;
8041
}
8042

8043
int ObDDLOperator::alter_outline(ObOutlineInfo &outline_info,
8044
                                 ObMySQLTransaction &trans,
8045
                                 const ObString *ddl_stmt_str/*=NULL*/)
8046
{
8047
  int ret = OB_SUCCESS;
8048
  const uint64_t tenant_id = outline_info.get_tenant_id();
8049
  int64_t new_schema_version = OB_INVALID_VERSION;
8050
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8051
  if (OB_ISNULL(schema_service)) {
8052
    ret = OB_ERR_SYS;
8053
    LOG_ERROR("schema_service is NULL", K(ret));
8054
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8055
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8056
  } else {
8057
    outline_info.set_schema_version(new_schema_version);
8058
    if (OB_FAIL(schema_service->get_outline_sql_service().alter_outline(
8059
        outline_info, trans, ddl_stmt_str))) {
8060
      LOG_WARN("alter outline failed", K(outline_info), K(ret));
8061
    } else {/*do nothing*/}
8062
  }
8063
  return ret;
8064
}
8065

8066
int ObDDLOperator::drop_outline(const uint64_t tenant_id,
8067
                                const uint64_t database_id,
8068
                                const uint64_t outline_id,
8069
                                ObMySQLTransaction &trans,
8070
                                const ObString *ddl_stmt_str/*=NULL*/)
8071
{
8072
  int ret = OB_SUCCESS;
8073
  int64_t new_schema_version = OB_INVALID_VERSION;
8074
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8075
  if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || OB_INVALID_ID == database_id
8076
                  || OB_INVALID_ID == outline_id)) {
8077
    ret = OB_INVALID_ARGUMENT;
8078
    LOG_WARN("invalid arguments", K(tenant_id), K(database_id), K(outline_id), K(ret));
8079
  } else if (OB_ISNULL(schema_service)) {
8080
    ret = OB_ERR_SYS;
8081
    LOG_ERROR("schema_service must not null", K(ret));
8082
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8083
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8084
  } else if (OB_FAIL(schema_service->get_outline_sql_service().delete_outline(
8085
      tenant_id,
8086
      database_id,
8087
      outline_id,
8088
      new_schema_version,
8089
      trans,
8090
      ddl_stmt_str))) {
8091
    LOG_WARN("drop outline failed", K(tenant_id), K(outline_id), KT(outline_id), K(ret));
8092
  } else {/*do nothing*/}
8093
  return ret;
8094
}
8095

8096
//----Functions for managing dblinks----
8097
int ObDDLOperator::create_dblink(ObDbLinkBaseInfo &dblink_info,
8098
                                 ObMySQLTransaction &trans,
8099
                                 const ObString *ddl_stmt_str/*=NULL*/)
8100
{
8101
  int ret = OB_SUCCESS;
8102
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8103
  uint64_t tenant_id = dblink_info.get_tenant_id();
8104
  uint64_t new_dblink_id = OB_INVALID_ID;
8105
  int64_t schema_version = -1;
8106
  int64_t is_deleted = 0;
8107
  if (OB_ISNULL(schema_service)) {
8108
    ret = OB_ERR_SYS;
8109
    LOG_ERROR("schema_service must not null", K(ret));
8110
  } else if (OB_FAIL(schema_service->fetch_new_dblink_id(tenant_id, new_dblink_id))) {
8111
    LOG_WARN("failed to fetch new_dblink_id", K(tenant_id), K(ret));
8112
  } else if (FALSE_IT(dblink_info.set_dblink_id(new_dblink_id))) {
8113
    // nothing.
8114
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, schema_version))) {
8115
    LOG_WARN("failed to gen new_schema_version", K(tenant_id), K(ret));
8116
  } else if (FALSE_IT(dblink_info.set_schema_version(schema_version))) {
8117
    // nothing.
8118
  } else if (OB_FAIL(schema_service->get_dblink_sql_service().insert_dblink(
8119
                     dblink_info, is_deleted, trans, ddl_stmt_str))) {
8120
    LOG_WARN("failed to insert dblink", K(dblink_info.get_dblink_name()), K(ret));
8121
  }
8122
  return ret;
8123
}
8124

8125
int ObDDLOperator::drop_dblink(ObDbLinkBaseInfo &dblink_info,
8126
                               ObMySQLTransaction &trans,
8127
                               const common::ObString *ddl_stmt_str/*=NULL*/)
8128
{
8129
  int ret = OB_SUCCESS;
8130
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8131
  uint64_t tenant_id = dblink_info.get_tenant_id();
8132
  uint64_t dblink_id = dblink_info.get_dblink_id();
8133
  int64_t schema_version = -1;
8134
  int64_t is_deleted = 1;
8135
  if (OB_ISNULL(schema_service)) {
8136
    ret = OB_ERR_SYS;
8137
    LOG_ERROR("schema_service must not null", K(ret));
8138
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, schema_version))) {
8139
    LOG_WARN("failed to gen new_schema_version", K(tenant_id), K(ret));
8140
  } else if (FALSE_IT(dblink_info.set_schema_version(schema_version))) {
8141
    // nothing.
8142
  } else if (OB_FAIL(schema_service->get_dblink_sql_service().insert_dblink(
8143
                     dblink_info, is_deleted, trans, ddl_stmt_str))) {
8144
    LOG_WARN("failed to insert dblink", K(dblink_info.get_dblink_name()), K(ret));
8145
  } else if (OB_FAIL(schema_service->get_dblink_sql_service().delete_dblink(
8146
                     tenant_id, dblink_id, trans))) {
8147
    LOG_WARN("failed to delete dblink", K(dblink_info.get_dblink_name()), K(ret));
8148
  }
8149
  return ret;
8150
}
8151
//----End of functions for managing dblinks----
8152

8153
//----Functions for managing synonym----
8154
int ObDDLOperator::create_synonym(ObSynonymInfo &synonym_info,
8155
                                  ObMySQLTransaction &trans,
8156
                                  const ObString *ddl_stmt_str/*=NULL*/)
8157
{
8158
  int ret = OB_SUCCESS;
8159
  uint64_t new_synonym_id = OB_INVALID_ID;
8160
  const uint64_t tenant_id = synonym_info.get_tenant_id();
8161
  int64_t new_schema_version = OB_INVALID_VERSION;
8162
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8163
  if (OB_ISNULL(schema_service)) {
8164
    ret = OB_ERR_SYS;
8165
    LOG_ERROR("schema_service must not null", K(ret));
8166
  } else if (OB_FAIL(schema_service->fetch_new_synonym_id(tenant_id, new_synonym_id))) {
8167
    LOG_WARN("failed to fetch new_synonym_id", K(tenant_id), K(ret));
8168
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8169
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8170
  } else {
8171
    synonym_info.set_synonym_id(new_synonym_id);
8172
    synonym_info.set_schema_version(new_schema_version);
8173
    if (OB_FAIL(schema_service->get_synonym_sql_service().insert_synonym(
8174
        synonym_info, &trans, ddl_stmt_str))) {
8175
      LOG_WARN("insert synonym info failed", K(synonym_info.get_synonym_name_str()), K(ret));
8176
    }
8177
  }
8178
  return ret;
8179
}
8180

8181
int ObDDLOperator::replace_synonym(ObSynonymInfo &synonym_info,
8182
                                   ObMySQLTransaction &trans,
8183
                                   const ObString *ddl_stmt_str/*=NULL*/)
8184
{
8185
  int ret = OB_SUCCESS;
8186
  const uint64_t tenant_id = synonym_info.get_tenant_id();
8187
  int64_t new_schema_version = OB_INVALID_VERSION;
8188
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8189
  if (OB_ISNULL(schema_service)) {
8190
    ret = OB_ERR_SYS;
8191
    LOG_ERROR("schema_service is NULL", K(ret));
8192
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8193
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8194
  } else {
8195
    synonym_info.set_schema_version(new_schema_version);
8196
    if (OB_FAIL(schema_service->get_synonym_sql_service().replace_synonym(
8197
        synonym_info, &trans, ddl_stmt_str))) {
8198
      LOG_WARN("replace synonym info failed", K(synonym_info.get_synonym_name_str()), K(ret));
8199
    } else {/*do nothing*/}
8200
  }
8201
  return ret;
8202
}
8203

8204
int ObDDLOperator::drop_synonym(const uint64_t tenant_id,
8205
                                const uint64_t database_id,
8206
                                const uint64_t synonym_id,
8207
                                ObMySQLTransaction &trans,
8208
                                const ObString *ddl_stmt_str/*=NULL*/)
8209
{
8210
  int ret = OB_SUCCESS;
8211
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8212
  int64_t new_schema_version = OB_INVALID_VERSION;
8213
  if (OB_UNLIKELY(OB_INVALID_ID == tenant_id
8214
                  || OB_INVALID_ID == synonym_id)) {
8215
    ret = OB_INVALID_ARGUMENT;
8216
    LOG_WARN("invalid arguments", K(tenant_id), K(database_id), K(synonym_id), K(ret));
8217
  } else if (OB_ISNULL(schema_service)) {
8218
    ret = OB_ERR_SYS;
8219
    LOG_ERROR("schema_service must not null", K(ret));
8220
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8221
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8222
  } else if (OB_FAIL(schema_service->get_synonym_sql_service().delete_synonym(
8223
      tenant_id,
8224
      database_id,
8225
      synonym_id,
8226
      new_schema_version,
8227
      &trans,
8228
      ddl_stmt_str))) {
8229
    LOG_WARN("drop synonym failed", K(tenant_id), K(synonym_id), KT(synonym_id), K(ret));
8230
  } else {/*do nothing*/}
8231
  return ret;
8232
}
8233

8234

8235
//----End of functions for managing outlines----
8236

8237
int ObDDLOperator::create_routine(ObRoutineInfo &routine_info,
8238
                                  ObMySQLTransaction &trans,
8239
                                  ObErrorInfo &error_info,
8240
                                  ObIArray<ObDependencyInfo> &dep_infos,
8241
                                  const ObString *ddl_stmt_str)
8242
{
8243
  int ret = OB_SUCCESS;
8244
  uint64_t new_routine_id = OB_INVALID_ID;
8245
  const uint64_t tenant_id = routine_info.get_tenant_id();
8246
  int64_t new_schema_version = OB_INVALID_VERSION;
8247
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8248

8249
  if (OB_ISNULL(schema_service)) {
8250
    ret = OB_ERR_SYS;
8251
    LOG_ERROR("schema_service must not null", K(ret));
8252
  } else if (OB_SYS_TENANT_ID == tenant_id
8253
          && OB_FAIL(schema_service->fetch_new_sys_pl_object_id(tenant_id, new_routine_id))) {
8254
    LOG_WARN("failed to fetch new_routine_id", K(tenant_id), K(ret));
8255
  } else if (OB_SYS_TENANT_ID != tenant_id
8256
          && OB_FAIL(schema_service->fetch_new_routine_id(tenant_id, new_routine_id))) {
8257
    LOG_WARN("failed to fetch new_routine_id", K(tenant_id), K(ret));
8258
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8259
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8260
  } else {
8261
    routine_info.set_routine_id(new_routine_id);
8262
    routine_info.set_schema_version(new_schema_version);
8263
    if (OB_FAIL(schema_service->get_routine_sql_service().create_routine(routine_info,
8264
                                                                         &trans,
8265
                                                                         ddl_stmt_str))) {
8266
      LOG_WARN("insert routine info failed", K(routine_info), K(ret));
8267
    }
8268
  }
8269
  OZ (insert_dependency_infos(trans, dep_infos, tenant_id, routine_info.get_routine_id(),
8270
                                routine_info.get_schema_version(),
8271
                                routine_info.get_owner_id()));
8272

8273
  // add audit in routine if necessary
8274
  if (OB_SUCC(ret)) {
8275
    int64_t new_schema_version = OB_INVALID_VERSION;
8276
    ObArray<const ObSAuditSchema *> audits;
8277
    ObSchemaGetterGuard schema_guard;
8278
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
8279
      LOG_WARN("failed to get schema guard", K(ret));
8280
    } else if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
8281
                                                       AUDIT_OBJ_DEFAULT,
8282
                                                       OB_AUDIT_MOCK_USER_ID,
8283
                                                       audits))) {
8284
      LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
8285
    } else if (!audits.empty()) {
8286
      ObSchemaService *schema_service = schema_service_.get_schema_service();
8287
      common::ObSqlString public_sql_string;
8288
      ObSAuditSchema new_audit_schema;
8289
      for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
8290
        uint64_t new_audit_id = common::OB_INVALID_ID;
8291
        const ObSAuditSchema *audit_schema = audits.at(i);
8292
        if (OB_ISNULL(audit_schema)) {
8293
          ret = OB_ERR_UNEXPECTED;
8294
          LOG_WARN("audit_schema is NULL", K(ret));
8295
        } else if (!audit_schema->is_access_operation_for_procedure()) {
8296
          continue;
8297
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))){
8298
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8299
        } else if (OB_FAIL(schema_service->fetch_new_audit_id(tenant_id, new_audit_id))) {
8300
          LOG_WARN("Failed to fetch new_audit_id", K(ret));
8301
        } else if (OB_FAIL(new_audit_schema.assign(*audit_schema))) {
8302
          LOG_WARN("fail to assign audit schema", KR(ret));
8303
        } else {
8304
          new_audit_schema.set_schema_version(new_schema_version);
8305
          new_audit_schema.set_audit_id(new_audit_id);
8306
          new_audit_schema.set_audit_type(AUDIT_PROCEDURE);
8307
          new_audit_schema.set_owner_id(routine_info.get_routine_id());
8308
          if (OB_FAIL(schema_service->get_audit_sql_service().handle_audit_metainfo(
8309
              new_audit_schema,
8310
              AUDIT_MT_ADD,
8311
              false,
8312
              new_schema_version,
8313
              NULL,
8314
              trans,
8315
              public_sql_string))) {
8316
            LOG_WARN("add audit_schema failed",  K(new_audit_schema), K(ret));
8317
          } else {
8318
            LOG_INFO("succ to add audit_schema from routine", K(new_audit_schema));
8319
          }
8320
        }
8321
      }
8322
    }
8323
  }
8324
  if (OB_SUCC(ret)) {
8325
    if (OB_FAIL(error_info.handle_error_info(trans, &routine_info))) {
8326
      LOG_WARN("insert create routine error info failed.", K(ret), K(error_info));
8327
    }
8328
  }
8329
  return ret;
8330
}
8331

8332
int ObDDLOperator::replace_routine(ObRoutineInfo &routine_info,
8333
                                   const ObRoutineInfo *old_routine_info,
8334
                                   ObMySQLTransaction &trans,
8335
                                   ObErrorInfo &error_info,
8336
                                   ObIArray<ObDependencyInfo> &dep_infos,
8337
                                   const ObString *ddl_stmt_str)
8338
{
8339
  int ret = OB_SUCCESS;
8340
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8341
  CK(OB_NOT_NULL(schema_service));
8342
  CK(OB_NOT_NULL(old_routine_info));
8343
  const uint64_t tenant_id = routine_info.get_tenant_id();
8344
  int64_t del_param_schema_version = OB_INVALID_VERSION;
8345
  int64_t new_schema_version = OB_INVALID_VERSION;
8346
  if (old_routine_info->get_routine_params().count() > 0) {
8347
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, del_param_schema_version))) {
8348
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8349
    }
8350
  }
8351

8352
  if (OB_FAIL(ret)) {
8353
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8354
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8355
  } else {
8356
    routine_info.set_routine_id(old_routine_info->get_routine_id());
8357
    routine_info.set_schema_version(new_schema_version);
8358
  }
8359
  OZ (ObDependencyInfo::delete_schema_object_dependency(trans, old_routine_info->get_tenant_id(),
8360
                                     old_routine_info->get_routine_id(),
8361
                                     new_schema_version,
8362
                                     old_routine_info->get_object_type()));
8363
  if (OB_SUCC(ret)
8364
      && OB_FAIL(schema_service->get_routine_sql_service().replace_routine(routine_info,
8365
                                                                           old_routine_info,
8366
                                                                           del_param_schema_version,
8367
                                                                           &trans,
8368
                                                                           ddl_stmt_str))) {
8369
    LOG_WARN("replace routine info failed", K(routine_info), K(ret));
8370
  }
8371

8372
  OZ (insert_dependency_infos(trans, dep_infos, tenant_id, routine_info.get_routine_id(),
8373
                                routine_info.get_schema_version(),
8374
                                routine_info.get_owner_id()));
8375
  if (OB_SUCC(ret)) {
8376
    if (OB_FAIL(error_info.handle_error_info(trans, &routine_info))) {
8377
      LOG_WARN("replace routine error info failed.", K(ret), K(error_info));
8378
    }
8379
  }
8380
  return ret;
8381
}
8382

8383
int ObDDLOperator::alter_routine(const ObRoutineInfo &routine_info,
8384
                                 ObMySQLTransaction &trans,
8385
                                 ObErrorInfo &error_info,
8386
                                 const ObString *ddl_stmt_str)
8387
{
8388
  int ret = OB_SUCCESS;
8389
  UNUSEDx(ddl_stmt_str);
8390
  if (OB_FAIL(error_info.handle_error_info(trans, &routine_info))) {
8391
    LOG_WARN("drop routine error info failed.", K(ret), K(error_info));
8392
  }
8393
  return ret;
8394
}
8395

8396
int ObDDLOperator::drop_routine(const ObRoutineInfo &routine_info,
8397
                                ObMySQLTransaction &trans,
8398
                                ObErrorInfo &error_info,
8399
                                const ObString *ddl_stmt_str)
8400
{
8401
  int ret = OB_SUCCESS;
8402
  const uint64_t tenant_id = routine_info.get_tenant_id();
8403
  int64_t new_schema_version = OB_INVALID_VERSION;
8404
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8405

8406
  if (OB_ISNULL(schema_service)) {
8407
    ret = OB_ERR_SYS;
8408
    LOG_ERROR("schema_service must not null", K(ret));
8409
  } else if (OB_FAIL(drop_obj_privs(tenant_id, routine_info.get_routine_id(),
8410
                                    static_cast<uint64_t>(routine_info.get_routine_type()),
8411
                                    trans))) {
8412
    LOG_WARN("fail to drop_obj_privs", K(ret), K(tenant_id));
8413
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8414
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8415
  } else if (OB_FAIL(schema_service->get_routine_sql_service().drop_routine(
8416
                     routine_info, new_schema_version, trans, ddl_stmt_str))) {
8417
    LOG_WARN("drop routine info failed", K(routine_info), K(ret));
8418
  }
8419
  OZ (ObDependencyInfo::delete_schema_object_dependency(trans, routine_info.get_tenant_id(),
8420
                                     routine_info.get_routine_id(),
8421
                                     new_schema_version,
8422
                                     routine_info.get_object_type()));
8423
  if (OB_SUCC(ret)) {
8424
    if (OB_FAIL(error_info.handle_error_info(trans, &routine_info))) {
8425
      LOG_WARN("drop routine error info failed.", K(ret), K(error_info));
8426
    }
8427
  }
8428

8429
  // delete audit in procedure
8430
  if (OB_SUCC(ret)) {
8431
    ObArray<const ObSAuditSchema *> audits;
8432
    ObSchemaGetterGuard schema_guard;
8433
    ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
8434
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
8435
      LOG_WARN("failed to get schema guard", K(ret));
8436
    } else if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
8437
                                                              AUDIT_PROCEDURE,
8438
                                                              routine_info.get_routine_id(),
8439
                                                              audits))) {
8440
      LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
8441
    } else if (!audits.empty()) {
8442
      common::ObSqlString public_sql_string;
8443
      for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
8444
        const ObSAuditSchema *audit_schema = audits.at(i);
8445
        if (OB_ISNULL(audit_schema)) {
8446
          ret = OB_ERR_UNEXPECTED;
8447
          LOG_WARN("audit_schema is NULL", K(ret));
8448
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8449
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8450
        } else if (OB_FAIL(schema_service_impl->get_audit_sql_service().handle_audit_metainfo(
8451
            *audit_schema,
8452
            AUDIT_MT_DEL,
8453
            false,
8454
            new_schema_version,
8455
            NULL,
8456
            trans,
8457
            public_sql_string))) {
8458
          LOG_WARN("drop audit_schema failed",  KPC(audit_schema), K(ret));
8459
        } else {
8460
          LOG_INFO("succ to delete audit_schema from drop procedure", KPC(audit_schema));
8461
        }
8462
      }
8463
    } else {
8464
      LOG_DEBUG("no need to delete audit_schema from drop procedure", K(audits), K(routine_info));
8465
    }
8466
  }
8467
  return ret;
8468
}
8469

8470
int ObDDLOperator::update_routine_info(ObRoutineInfo &routine_info,
8471
                                      int64_t tenant_id,
8472
                                      int64_t parent_id,
8473
                                      int64_t owner_id,
8474
                                      int64_t database_id,
8475
                                      int64_t routine_id = OB_INVALID_ID)
8476
{
8477
  int ret = OB_SUCCESS;
8478
  uint64_t new_routine_id = routine_id;
8479
  int64_t new_schema_version = OB_INVALID_VERSION;
8480
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8481
  lib::Worker::CompatMode compat_mode = lib::Worker::CompatMode::INVALID;
8482
  if (OB_ISNULL(schema_service)) {
8483
    ret = OB_ERR_SYS;
8484
    LOG_ERROR("schema_service must not null", K(ret));
8485
  } else if (OB_INVALID_ID == new_routine_id
8486
        && OB_SYS_TENANT_ID == tenant_id
8487
        && OB_FAIL(schema_service->fetch_new_sys_pl_object_id(tenant_id, new_routine_id))) {
8488
    LOG_WARN("failed to fetch new_routine_id", K(tenant_id), K(ret));
8489
  } else if (OB_INVALID_ID == new_routine_id
8490
        && OB_SYS_TENANT_ID != tenant_id
8491
        && OB_FAIL(schema_service->fetch_new_routine_id(tenant_id, new_routine_id))) {
8492
    LOG_WARN("failed to fetch new_routine_id", K(tenant_id), K(ret));
8493
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8494
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8495
  } else if (OB_FAIL(ObCompatModeGetter::get_tenant_mode(tenant_id, compat_mode))) {
8496
    LOG_WARN("fail to get tenant mode", K(ret));
8497
  } else {
8498
    routine_info.set_database_id(database_id);
8499
    if (lib::Worker::CompatMode::ORACLE == compat_mode) {
8500
      routine_info.set_owner_id(owner_id);
8501
    }
8502
    routine_info.set_package_id(parent_id);
8503
    routine_info.set_routine_id(new_routine_id);
8504
    routine_info.set_schema_version(new_schema_version);
8505
  }
8506
  return ret;
8507
}
8508

8509
int ObDDLOperator::create_package(const ObPackageInfo *old_package_info,
8510
                                  ObPackageInfo &new_package_info,
8511
                                  ObMySQLTransaction &trans,
8512
                                  ObSchemaGetterGuard &schema_guard,
8513
                                  ObIArray<ObRoutineInfo> &public_routine_infos,
8514
                                  ObErrorInfo &error_info,
8515
                                  ObIArray<ObDependencyInfo> &dep_infos,
8516
                                  const ObString *ddl_stmt_str)
8517
{
8518
  int ret = OB_SUCCESS;
8519
  uint64_t new_package_id = OB_INVALID_ID;
8520
  const uint64_t tenant_id = new_package_info.get_tenant_id();
8521
  int64_t new_schema_version = OB_INVALID_VERSION;
8522
  bool is_replace = false;
8523
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8524
  if (OB_ISNULL(schema_service)) {
8525
    ret = OB_ERR_SYS;
8526
    LOG_ERROR("schema_service must not null", K(ret));
8527
  } else {
8528
    if (OB_NOT_NULL(old_package_info)) {
8529
      is_replace = true;
8530
      new_package_id = old_package_info->get_package_id();
8531
      if (old_package_info->is_package() && OB_FAIL(del_routines_in_package(*old_package_info, trans, schema_guard))) {
8532
        LOG_WARN("del routines in package failed", K(ret), K(old_package_info));
8533
      } else {}
8534
    } else {
8535
      if (OB_SYS_TENANT_ID == tenant_id) {
8536
        if (OB_FAIL(schema_service->fetch_new_sys_pl_object_id(tenant_id, new_package_id))) {
8537
          LOG_WARN("failed to fetch new_package_id", K(tenant_id), K(ret));
8538
        }
8539
      } else {
8540
        if (OB_FAIL(schema_service->fetch_new_package_id(tenant_id, new_package_id))) {
8541
          LOG_WARN("failed to fetch new_package_id", K(tenant_id), K(ret));
8542
        }
8543
      }
8544
    }
8545
    if (OB_SUCC(ret)) {
8546
      new_package_info.set_package_id(new_package_id);
8547
      if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8548
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8549
      } else if (FALSE_IT(new_package_info.set_schema_version(new_schema_version))) {
8550
      } else if (OB_FAIL(schema_service->get_routine_sql_service().create_package(new_package_info,
8551
          &trans, is_replace, ddl_stmt_str))) {
8552
        LOG_WARN("insert package info failed", K(new_package_info), K(ret));
8553
      } else {
8554
        ARRAY_FOREACH(public_routine_infos, routine_idx) {
8555
          ObRoutineInfo &routine_info = public_routine_infos.at(routine_idx);
8556
          if (new_package_info.is_package()) {
8557
            if (OB_FAIL(update_routine_info(routine_info,
8558
                                            tenant_id,
8559
                                            new_package_info.get_package_id(),
8560
                                            new_package_info.get_owner_id(),
8561
                                            new_package_info.get_database_id(),
8562
                                            routine_info.get_routine_id()))) {
8563
              LOG_WARN("failed to update routine info", K(ret));
8564
            } else if (OB_FAIL(schema_service->get_routine_sql_service().create_routine(routine_info,
8565
                                                                         &trans, NULL))) {
8566
              LOG_WARN("insert routine info failed", K(routine_info), K(ret));
8567
            }
8568
          } else if (OB_INVALID_ID == routine_info.get_routine_id()) {
8569
            OZ (update_routine_info(routine_info,
8570
                                    tenant_id,
8571
                                    routine_info.get_package_id(),
8572
                                    routine_info.get_owner_id(),
8573
                                    routine_info.get_database_id()));
8574
            OZ (schema_service->get_routine_sql_service().create_routine(routine_info, &trans, NULL));
8575
          } else {
8576
            // update routine route sql
8577
            int64_t new_schema_version = OB_INVALID_VERSION;
8578
            OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
8579
            OX (routine_info.set_schema_version(new_schema_version));
8580
            OZ (schema_service->get_routine_sql_service().update_routine(routine_info, &trans));
8581
          }
8582
        }
8583
      }
8584
    }
8585

8586
    // add audit in package if necessary
8587
    if (OB_SUCC(ret) && new_package_info.is_package()) {
8588
      int64_t new_schema_version = OB_INVALID_VERSION;
8589
      ObArray<const ObSAuditSchema *> audits;
8590
      if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
8591
                                                         AUDIT_OBJ_DEFAULT,
8592
                                                         OB_AUDIT_MOCK_USER_ID,
8593
                                                         audits))) {
8594
        LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
8595
      } else if (!audits.empty()) {
8596
        ObSchemaService *schema_service = schema_service_.get_schema_service();
8597
        common::ObSqlString public_sql_string;
8598
        ObSAuditSchema new_audit_schema;
8599
        for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
8600
          uint64_t new_audit_id = common::OB_INVALID_ID;
8601
          const ObSAuditSchema *audit_schema = audits.at(i);
8602
          if (OB_ISNULL(audit_schema)) {
8603
            ret = OB_ERR_UNEXPECTED;
8604
            LOG_WARN("audit_schema is NULL", K(ret));
8605
          } else if (!audit_schema->is_access_operation_for_package()) {
8606
            continue;
8607
          } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))){
8608
            LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8609
          } else if (OB_FAIL(schema_service->fetch_new_audit_id(tenant_id, new_audit_id))) {
8610
            LOG_WARN("Failed to fetch new_audit_id", K(ret));
8611
          } else if (OB_FAIL(new_audit_schema.assign(*audit_schema))) {
8612
            LOG_WARN("fail to assign audit schema", KR(ret));
8613
          } else {
8614
            new_audit_schema.set_schema_version(new_schema_version);
8615
            new_audit_schema.set_audit_id(new_audit_id);
8616
            new_audit_schema.set_audit_type(AUDIT_PACKAGE);
8617
            new_audit_schema.set_owner_id(new_package_info.get_package_id());
8618
            if (OB_FAIL(schema_service->get_audit_sql_service().handle_audit_metainfo(
8619
                new_audit_schema,
8620
                AUDIT_MT_ADD,
8621
                false,
8622
                new_schema_version,
8623
                NULL,
8624
                trans,
8625
                public_sql_string))) {
8626
              LOG_WARN("add audit_schema failed",  K(new_audit_schema), K(ret));
8627
            } else {
8628
              LOG_INFO("succ to add audit_schema from package", K(new_audit_schema));
8629
            }
8630
          }
8631
        }
8632
      }
8633
    }
8634
    if (is_replace) {
8635
      OZ (ObDependencyInfo::delete_schema_object_dependency(trans, tenant_id,
8636
                                     old_package_info->get_package_id(),
8637
                                     new_schema_version,
8638
                                     old_package_info->get_object_type()));
8639
    }
8640
    OZ (insert_dependency_infos(trans, dep_infos, tenant_id, new_package_info.get_package_id(),
8641
                                new_package_info.get_schema_version(),
8642
                                new_package_info.get_owner_id()));
8643
    if (OB_SUCC(ret)) {
8644
      if (OB_FAIL(error_info.handle_error_info(trans, &new_package_info))) {
8645
        LOG_WARN("insert create package error info failed.", K(ret), K(error_info));
8646
      }
8647
    }
8648
  }
8649
  return ret;
8650
}
8651

8652
int ObDDLOperator::alter_package(const ObPackageInfo &package_info,
8653
                                 ObSchemaGetterGuard &schema_guard,
8654
                                 ObMySQLTransaction &trans,
8655
                                 ObIArray<ObRoutineInfo> &public_routine_infos,
8656
                                 ObErrorInfo &error_info,
8657
                                 const ObString *ddl_stmt_str)
8658
{
8659
  int ret = OB_SUCCESS;
8660
  UNUSEDx(ddl_stmt_str);
8661
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
8662
  const uint64_t tenant_id = package_info.get_tenant_id();
8663
  int64_t new_schema_version = OB_INVALID_VERSION;
8664
  uint64_t package_id = package_info.get_package_id();
8665
  ObPackageInfo new_package_info;
8666
  OV (OB_NOT_NULL(schema_service_impl), OB_ERR_SYS);
8667
  OV (OB_INVALID_ID != tenant_id && OB_INVALID_ID != package_id, OB_INVALID_ARGUMENT);
8668
  if (OB_SUCC(ret)) {
8669
    if (public_routine_infos.count() > 0) {
8670
      bool need_create = false;
8671
      ObArray<const ObRoutineInfo *> routine_infos;
8672
      OZ (schema_guard.get_routine_infos_in_package(tenant_id,
8673
                                                    public_routine_infos.at(0).get_package_id(),
8674
                                                    routine_infos));
8675
      OX (need_create = (0 == routine_infos.count()));
8676
      // update routine route sql
8677
      ARRAY_FOREACH(public_routine_infos, routine_idx) {
8678
        ObRoutineInfo &routine_info = public_routine_infos.at(routine_idx);
8679
        if (need_create) {
8680
          CK (OB_INVALID_ID == routine_info.get_routine_id());
8681
          OZ (update_routine_info(routine_info,
8682
                                  tenant_id,
8683
                                  routine_info.get_package_id(),
8684
                                  routine_info.get_owner_id(),
8685
                                  routine_info.get_database_id()));
8686
          OZ (schema_service_impl->get_routine_sql_service().create_routine(routine_info, &trans, NULL));
8687
        } else {
8688
          OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
8689
          OX (routine_info.set_schema_version(new_schema_version));
8690
          OZ (schema_service_impl->get_routine_sql_service().update_routine(routine_info, &trans));
8691
        }
8692
      }
8693
      OZ (new_package_info.assign(package_info));
8694
      OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
8695
      OX (new_package_info.set_schema_version(new_schema_version));
8696
      OZ (schema_service_impl->get_routine_sql_service().alter_package(new_package_info, &trans, ddl_stmt_str));
8697
    }
8698
  }
8699
  OZ (error_info.handle_error_info(trans, &package_info));
8700
  return ret;
8701
}
8702

8703
int ObDDLOperator::drop_package(const ObPackageInfo &package_info,
8704
                                ObMySQLTransaction &trans,
8705
                                ObSchemaGetterGuard &schema_guard,
8706
                                ObErrorInfo &error_info,
8707
                                const ObString *ddl_stmt_str)
8708
{
8709
  int ret = OB_SUCCESS;
8710
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
8711
  const uint64_t tenant_id = package_info.get_tenant_id();
8712
  int64_t new_schema_version = OB_INVALID_VERSION;
8713
  uint64_t package_id = package_info.get_package_id();
8714
  if (OB_ISNULL(schema_service_impl)) {
8715
    ret = OB_ERR_SYS;
8716
    LOG_ERROR("schema_service must not null", K(ret));
8717
  } else if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == package_id) {
8718
    ret = OB_INVALID_ARGUMENT;
8719
    LOG_WARN("invalid argument", K(ret));
8720
  }
8721
  if (OB_SUCC(ret)) {
8722
    if (package_info.is_package()
8723
        && OB_FAIL(del_routines_in_package(package_info, trans, schema_guard))) {
8724
      LOG_WARN("del routines in package failed", K(ret));
8725
    }
8726
  }
8727

8728
  if (OB_SUCC(ret)) {
8729
    if (PACKAGE_TYPE == package_info.get_type()) {
8730
      // delete privs on package
8731
      OZ (drop_obj_privs(tenant_id,
8732
                         package_info.get_package_id(),
8733
                         static_cast<uint64_t>(ObObjectType::PACKAGE),
8734
                         trans));
8735
      uint64_t database_id = package_info.get_database_id();
8736
      int64_t compatible_mode = package_info.get_compatibility_mode();
8737
      const ObString &package_name = package_info.get_package_name();
8738
      const ObPackageInfo *package_body_info = NULL;
8739
      if (OB_FAIL(schema_guard.get_package_info(tenant_id, database_id, package_name, PACKAGE_BODY_TYPE,
8740
                                                compatible_mode, package_body_info))) {
8741
        LOG_WARN("get package body info failed", K(tenant_id), K(database_id), K(package_name), K(ret));
8742
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8743
        LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8744
      } else if (NULL != package_body_info) {
8745
        if (OB_FAIL(schema_service_impl->get_routine_sql_service().drop_package(package_body_info->get_tenant_id(),
8746
                                                                                package_body_info->get_database_id(),
8747
                                                                                package_body_info->get_package_id(),
8748
                                                                                new_schema_version, trans))) {
8749
          LOG_WARN("drop package body info failed", K(package_body_info), K(ret));
8750
        }
8751
      } else {
8752
        // package spec
8753
        OZ (ObDependencyInfo::delete_schema_object_dependency(trans, tenant_id,
8754
                                                        package_info.get_package_id(),
8755
                                                        new_schema_version,
8756
                                                        package_info.get_object_type()));
8757
        if (OB_NOT_NULL(package_body_info)) {
8758
          OZ (ObDependencyInfo::delete_schema_object_dependency(trans, tenant_id,
8759
                                                        package_body_info->get_package_id(),
8760
                                                        new_schema_version,
8761
                                                        package_body_info->get_object_type()));
8762
        }
8763
      }
8764
    }
8765
  }
8766
  if (OB_SUCC(ret)) {
8767
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8768
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8769
    } else if (OB_FAIL(schema_service_impl->get_routine_sql_service().drop_package(package_info.get_tenant_id(),
8770
                                                                                   package_info.get_database_id(),
8771
                                                                                   package_info.get_package_id(),
8772
                                                                                   new_schema_version, trans, ddl_stmt_str))) {
8773
      LOG_WARN("drop package info failed", K(package_info), K(ret));
8774
    }
8775
  }
8776
  if (OB_SUCC(ret)) {
8777
    if (OB_FAIL(error_info.handle_error_info(trans, &package_info))) {
8778
      LOG_WARN("delete drop package error info failed", K(ret), K(error_info));
8779
    }
8780
  }
8781

8782
    // delete audit in package
8783
  if (OB_SUCC(ret)) {
8784
    ObArray<const ObSAuditSchema *> audits;
8785
    if (OB_FAIL(schema_guard.get_audit_schema_in_owner(tenant_id,
8786
                                                       AUDIT_PACKAGE,
8787
                                                       package_info.get_package_id(),
8788
                                                       audits))) {
8789
      LOG_WARN("get get_audit_schema_in_owner failed", K(tenant_id), K(ret));
8790
    } else if (!audits.empty()) {
8791
      common::ObSqlString public_sql_string;
8792
      for (int64_t i = 0; OB_SUCC(ret) && i < audits.count(); ++i) {
8793
        const ObSAuditSchema *audit_schema = audits.at(i);
8794
        if (OB_ISNULL(audit_schema)) {
8795
          ret = OB_ERR_UNEXPECTED;
8796
          LOG_WARN("audit_schema is NULL", K(ret));
8797
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8798
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8799
        } else if (OB_FAIL(schema_service_impl->get_audit_sql_service().handle_audit_metainfo(
8800
            *audit_schema,
8801
            AUDIT_MT_DEL,
8802
            false,
8803
            new_schema_version,
8804
            NULL,
8805
            trans,
8806
            public_sql_string))) {
8807
          LOG_WARN("drop audit_schema failed",  KPC(audit_schema), K(ret));
8808
        } else {
8809
          LOG_INFO("succ to delete audit_schema from drop package", KPC(audit_schema));
8810
        }
8811
      }
8812
    } else {
8813
      LOG_DEBUG("no need to delete audit_schema from drop package", K(audits), K(package_info));
8814
    }
8815
  }
8816
  return ret;
8817
}
8818

8819
int ObDDLOperator::del_routines_in_package(const ObPackageInfo &package_info,
8820
                                           ObMySQLTransaction &trans,
8821
                                           ObSchemaGetterGuard &schema_guard)
8822
{
8823
  int ret = OB_SUCCESS;
8824
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
8825
  const uint64_t tenant_id = package_info.get_tenant_id();
8826
  uint64_t package_id = package_info.get_package_id();
8827
  if (OB_INVALID_ID == tenant_id
8828
      || OB_INVALID_ID == package_id) {
8829
    ret = OB_INVALID_ARGUMENT;
8830
    LOG_WARN("invalid argument", K(ret));
8831
  } else {
8832
    ObArray<const ObRoutineInfo *> routines;
8833
    if (OB_FAIL(schema_guard.get_routine_infos_in_package(tenant_id, package_id, routines))) {
8834
      LOG_WARN("get routines in package failed", K(tenant_id), K(package_id), K(ret));
8835
    } else {
8836
      for (int64_t i = 0; OB_SUCC(ret) && i < routines.count(); ++i) {
8837
        const ObRoutineInfo *routine_info = routines.at(i);
8838
        int64_t new_schema_version = OB_INVALID_VERSION;
8839
        if (OB_ISNULL(routine_info)) {
8840
          ret = OB_ERR_UNEXPECTED;
8841
          LOG_WARN("routine info is NULL", K(ret));
8842
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
8843
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
8844
        } else if (OB_FAIL(schema_service_impl->get_routine_sql_service().drop_routine(
8845
                           *routine_info, new_schema_version, trans))) {
8846
          LOG_WARN("drop routine failed", "routine_id", routine_info->get_routine_id(), K(ret));
8847
        }
8848
      }
8849
    }
8850
  }
8851
  return ret;
8852
}
8853

8854
// functions for managing trigger
8855

8856
int ObDDLOperator::create_trigger(ObTriggerInfo &trigger_info,
8857
                                  ObMySQLTransaction &trans,
8858
                                  ObErrorInfo &error_info,
8859
                                  ObIArray<ObDependencyInfo> &dep_infos,
8860
                                  int64_t &table_schema_version,
8861
                                  const ObString *ddl_stmt_str,
8862
                                  bool is_update_table_schema_version,
8863
                                  bool is_for_truncate_table)
8864
{
8865
  int ret = OB_SUCCESS;
8866
  table_schema_version = OB_INVALID_VERSION;
8867
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8868
  const uint64_t tenant_id = trigger_info.get_tenant_id();
8869
  int64_t new_schema_version = OB_INVALID_VERSION;
8870
  bool is_replace = false;
8871
  OV (OB_NOT_NULL(schema_service));
8872
  if (!is_for_truncate_table) {
8873
    // If create_trigger through truncate table, trigger_info already has its own trigger_id.
8874
    // but there is no such trigger in the internal table at this time, so is_replace must be false
8875
    OX (is_replace = (OB_INVALID_ID != trigger_info.get_trigger_id()));
8876
    if (!is_replace) {
8877
      OZ (fill_trigger_id(*schema_service, trigger_info), trigger_info.get_trigger_name());
8878
    }
8879
  }
8880
  OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version),
8881
      tenant_id, trigger_info.get_trigger_name());
8882
  OX (trigger_info.set_schema_version(new_schema_version));
8883
  OZ (schema_service->get_trigger_sql_service().create_trigger(trigger_info, is_replace,
8884
                                                              trans, ddl_stmt_str),
8885
      trigger_info.get_trigger_name(), is_replace);
8886
  if (!trigger_info.is_system_type() && is_update_table_schema_version) {
8887
    uint64_t base_table_id = trigger_info.get_base_object_id();
8888
    OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
8889
    OX (table_schema_version = new_schema_version);
8890
    OZ (schema_service->get_table_sql_service().update_data_table_schema_version(
8891
        trans, tenant_id, base_table_id, false/*in offline ddl white list*/, new_schema_version),
8892
        base_table_id, trigger_info.get_trigger_name());
8893
  }
8894
  if (OB_FAIL(ret)) {
8895
  } else if (0 == dep_infos.count()) {
8896
    // create trigger in mysql mode or create trigger when truncate table, dep_infos.count() is 0,
8897
    // no need to deal with dependencies.
8898
  } else {
8899
    OZ (ObDependencyInfo::delete_schema_object_dependency(trans, trigger_info.get_tenant_id(),
8900
                                                          trigger_info.get_trigger_id(),
8901
                                                          trigger_info.get_schema_version(),
8902
                                                          trigger_info.get_object_type()));
8903
    OZ (insert_dependency_infos(trans, dep_infos, trigger_info.get_tenant_id(), trigger_info.get_trigger_id(),
8904
                                trigger_info.get_schema_version(), trigger_info.get_owner_id()));
8905
  }
8906
  if (OB_SUCC(ret)) {
8907
    if (OB_FAIL(error_info.handle_error_info(trans, &trigger_info))) {
8908
      LOG_WARN("insert trigger error info failed.", K(ret), K(error_info));
8909
    }
8910
  }
8911
  return ret;
8912
}
8913

8914
int ObDDLOperator::drop_trigger(const ObTriggerInfo &trigger_info,
8915
                                ObMySQLTransaction &trans,
8916
                                const ObString *ddl_stmt_str,
8917
                                bool is_update_table_schema_version,
8918
                                const bool in_offline_ddl_white_list)
8919
{
8920
  int ret = OB_SUCCESS;
8921
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8922
  const uint64_t tenant_id = trigger_info.get_tenant_id();
8923
  int64_t new_schema_version = OB_INVALID_VERSION;
8924
  OV (OB_NOT_NULL(schema_service));
8925
  OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version),
8926
      tenant_id, trigger_info.get_trigger_name());
8927
  OZ (schema_service->get_trigger_sql_service().drop_trigger(trigger_info, false,
8928
                                                             new_schema_version,
8929
                                                             trans, ddl_stmt_str),
8930
      trigger_info.get_trigger_name());
8931
  OZ (ObDependencyInfo::delete_schema_object_dependency(trans, tenant_id,
8932
                                                        trigger_info.get_trigger_id(),
8933
                                                        new_schema_version,
8934
                                                        trigger_info.get_object_type()));
8935
  if (OB_SUCC(ret) && !trigger_info.is_system_type() && is_update_table_schema_version) {
8936
    uint64_t base_table_id = trigger_info.get_base_object_id();
8937
    OZ (schema_service->get_table_sql_service().update_data_table_schema_version(trans,
8938
        tenant_id, base_table_id, in_offline_ddl_white_list),
8939
        base_table_id, trigger_info.get_trigger_name());
8940
  }
8941
  if (OB_SUCC(ret)) {
8942
    ObErrorInfo error_info;
8943
    if (OB_FAIL(error_info.handle_error_info(trans, &trigger_info))) {
8944
      LOG_WARN("delete trigger error info failed.", K(ret), K(error_info));
8945
    }
8946
  }
8947
  return ret;
8948
}
8949

8950
int ObDDLOperator::alter_trigger(ObTriggerInfo &trigger_info,
8951
                                 ObMySQLTransaction &trans,
8952
                                 const ObString *ddl_stmt_str,
8953
                                 bool is_update_table_schema_version)
8954
{
8955
  int ret = OB_SUCCESS;
8956
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8957
  const uint64_t tenant_id = trigger_info.get_tenant_id();
8958
  int64_t new_schema_version = OB_INVALID_VERSION;
8959
  OV (OB_NOT_NULL(schema_service));
8960
  OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version), tenant_id,
8961
      trigger_info.get_trigger_name());
8962
  OX (trigger_info.set_schema_version(new_schema_version));
8963
  OZ (schema_service->get_trigger_sql_service().alter_trigger(trigger_info, new_schema_version,
8964
                                                              trans, ddl_stmt_str),
8965
      trigger_info.get_trigger_name());
8966
  if (OB_SUCC(ret) && !trigger_info.is_system_type() && is_update_table_schema_version) {
8967
      uint64_t base_table_id = trigger_info.get_base_object_id();
8968
      OZ (schema_service->get_table_sql_service().update_data_table_schema_version(
8969
          trans, tenant_id, base_table_id, false/*in offline ddl white list*/),
8970
          base_table_id, trigger_info.get_trigger_name());
8971
  }
8972
  ObErrorInfo error_info;
8973
  OZ (error_info.handle_error_info(trans, &trigger_info), error_info);
8974
  return ret;
8975
}
8976

8977
int ObDDLOperator::drop_trigger_to_recyclebin(const ObTriggerInfo &trigger_info,
8978
                                              ObSchemaGetterGuard &schema_guard,
8979
                                              ObMySQLTransaction &trans)
8980
{
8981
  int ret = OB_SUCCESS;
8982
  ObSchemaService *schema_service = schema_service_.get_schema_service();
8983
  uint64_t tenant_id = trigger_info.get_tenant_id();
8984
  uint64_t recyclebin_id = OB_RECYCLEBIN_SCHEMA_ID;
8985
  uint64_t base_database_id = OB_INVALID_ID;
8986
  bool recyclebin_exist = false;
8987
  int64_t new_schema_version = OB_INVALID_VERSION;
8988
  const ObSimpleTableSchemaV2 *base_table_schema = NULL;
8989
  ObTriggerInfo new_trigger_info;
8990
  ObSqlString new_trigger_name;
8991
  ObRecycleObject recyclebin_object;
8992
  OV (OB_NOT_NULL(schema_service));
8993
  OV (OB_INVALID_TENANT_ID != tenant_id, OB_INVALID_ARGUMENT);
8994
  OZ (schema_guard.check_database_exist(tenant_id, recyclebin_id, recyclebin_exist));
8995
  OV (recyclebin_exist);
8996
  OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
8997
  OZ (new_trigger_info.deep_copy(trigger_info));
8998
  OX (new_trigger_info.set_database_id(recyclebin_id));
8999
  OX (new_trigger_info.set_schema_version(new_schema_version));
9000
  OZ (construct_new_name_for_recyclebin(new_trigger_info, new_trigger_name));
9001
  OZ (new_trigger_info.set_trigger_name(new_trigger_name.string()));
9002
  OZ (schema_guard.get_simple_table_schema(tenant_id, trigger_info.get_base_object_id(), base_table_schema),
9003
      trigger_info.get_base_object_id());
9004
  OV (OB_NOT_NULL(base_table_schema), trigger_info.get_base_object_id());
9005
  OX (base_database_id = base_table_schema->get_database_id());
9006
  OX (recyclebin_object.set_tenant_id(tenant_id));
9007
  OX (recyclebin_object.set_database_id(base_database_id));
9008
  OX (recyclebin_object.set_table_id(trigger_info.get_trigger_id()));
9009
  OX (recyclebin_object.set_tablegroup_id(OB_INVALID_ID));
9010
  OZ (recyclebin_object.set_object_name(new_trigger_name.string()));
9011
  OZ (recyclebin_object.set_original_name(trigger_info.get_trigger_name()));
9012
  OX (recyclebin_object.set_type(ObRecycleObject::TRIGGER));
9013
  OZ (schema_service->insert_recyclebin_object(recyclebin_object, trans));
9014
  OZ (schema_service->get_trigger_sql_service().drop_trigger(new_trigger_info, true,
9015
                                                             new_schema_version, trans),
9016
      trigger_info.get_trigger_name());
9017
  return ret;
9018
}
9019

9020
int ObDDLOperator::flashback_trigger(const ObTriggerInfo &trigger_info,
9021
                                     uint64_t new_database_id,
9022
                                     const ObString &new_table_name,
9023
                                     ObSchemaGetterGuard &schema_guard,
9024
                                     ObMySQLTransaction &trans)
9025
{
9026
  int ret = OB_SUCCESS;
9027
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9028
  uint64_t tenant_id = trigger_info.get_tenant_id();
9029
  const ObDatabaseSchema *database_schema = NULL;
9030
  ObSEArray<ObRecycleObject, 1> recycle_objects;
9031
  ObArenaAllocator allocator(ObModIds::OB_SCHEMA);
9032
  ObString new_trigger_name;
9033
  int64_t new_schema_version = OB_INVALID_VERSION;
9034
  ObTriggerInfo new_trigger_info;
9035
  OV (OB_NOT_NULL(schema_service));
9036
  OZ (schema_service->fetch_recycle_object(tenant_id, trigger_info.get_trigger_name(),
9037
                                           ObRecycleObject::TRIGGER, trans, recycle_objects));
9038
  OV (1 == recycle_objects.count(), OB_ERR_UNEXPECTED, recycle_objects.count());
9039
  OZ (new_trigger_info.deep_copy(trigger_info));
9040
  // database id.
9041
  if (OB_INVALID_ID == new_database_id) {
9042
    OX (new_database_id = recycle_objects.at(0).get_database_id());
9043
  }
9044
  OZ (schema_guard.get_database_schema(tenant_id, new_database_id, database_schema), new_database_id);
9045
  OV (OB_NOT_NULL(database_schema), new_database_id);
9046
  OV (!database_schema->is_in_recyclebin(), OB_OP_NOT_ALLOW, new_database_id);
9047
  OX (new_trigger_info.set_database_id(new_database_id));
9048
  // trigger name.
9049
  OZ (build_flashback_object_name(new_trigger_info, NULL, "OBTRG",
9050
                                  schema_guard, allocator, new_trigger_name));
9051
  OX (new_trigger_info.set_trigger_name(new_trigger_name));
9052
  // other operation.
9053
  OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version), tenant_id);
9054
  OZ (schema_service->delete_recycle_object(tenant_id, recycle_objects.at(0), trans));
9055
  if (OB_FAIL(ret)) {
9056
    //do nothing
9057
  } else if (new_table_name.empty()) {
9058
    // If new_table_name is empty, it means that the table does not have a rename, and rebuild_trigger_package is not required.
9059
    // Otherwise, table rename is required, and rebuild_trigger_package is required.
9060
    OZ (schema_service->get_trigger_sql_service().flashback_trigger(new_trigger_info,
9061
                                                                    new_schema_version, trans),
9062
        new_trigger_info.get_trigger_id());
9063
  } else {
9064
    OZ (schema_service->get_trigger_sql_service()
9065
                          .rebuild_trigger_package(new_trigger_info,
9066
                                                   database_schema->get_database_name(),
9067
                                                   new_table_name, new_schema_version,
9068
                                                   trans, OB_DDL_FLASHBACK_TRIGGER),
9069
        database_schema->get_database_name(), new_table_name);
9070
  }
9071
  return ret;
9072
}
9073

9074
int ObDDLOperator::purge_table_trigger(const ObTableSchema &table_schema,
9075
                                       ObSchemaGetterGuard &schema_guard,
9076
                                       ObMySQLTransaction &trans)
9077
{
9078
  int ret = OB_SUCCESS;
9079
  const uint64_t tenant_id = table_schema.get_tenant_id();
9080
  const ObIArray<uint64_t> &trigger_id_list = table_schema.get_trigger_list();
9081
  const ObTriggerInfo *trigger_info = NULL;
9082
  for (int i = 0; OB_SUCC(ret) && i < trigger_id_list.count(); i++) {
9083
    OZ (schema_guard.get_trigger_info(tenant_id, trigger_id_list.at(i), trigger_info), trigger_id_list.at(i));
9084
    OV (OB_NOT_NULL(trigger_info), OB_ERR_UNEXPECTED, trigger_id_list.at(i));
9085
    OZ (purge_trigger(*trigger_info, trans), trigger_id_list.at(i));
9086
  }
9087
  return ret;
9088
}
9089

9090
int ObDDLOperator::purge_trigger(const ObTriggerInfo &trigger_info, ObMySQLTransaction &trans)
9091
{
9092
  int ret = OB_SUCCESS;
9093
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9094
  ObRecycleObject::RecycleObjType recycle_type = ObRecycleObject::TRIGGER;
9095
  ObArray<ObRecycleObject> recycle_objects;
9096
  OV (OB_NOT_NULL(schema_service));
9097
  OZ (schema_service->fetch_recycle_object(trigger_info.get_tenant_id(),
9098
                                           trigger_info.get_trigger_name(),
9099
                                           recycle_type, trans, recycle_objects));
9100
  OV (1 == recycle_objects.count(), OB_ERR_UNEXPECTED, recycle_objects.count());
9101
  OZ (schema_service->delete_recycle_object(trigger_info.get_tenant_id(),
9102
                                            recycle_objects.at(0), trans));
9103
  OZ (drop_trigger(trigger_info, trans, NULL));
9104
  return ret;
9105
}
9106

9107
int ObDDLOperator::rebuild_trigger_package(const ObTriggerInfo &trigger_info,
9108
                                           const ObString &database_name,
9109
                                           const ObString &table_name,
9110
                                           ObMySQLTransaction &trans)
9111
{
9112
  int ret = OB_SUCCESS;
9113
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9114
  const uint64_t tenant_id = trigger_info.get_tenant_id();
9115
  int64_t new_schema_version = OB_INVALID_VERSION;
9116
  OV (OB_NOT_NULL(schema_service));
9117
  OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version),
9118
      tenant_id, trigger_info.get_trigger_name());
9119
  OZ (schema_service->get_trigger_sql_service().rebuild_trigger_package(trigger_info,
9120
                                                                        database_name, table_name,
9121
                                                                        new_schema_version, trans),
9122
      trigger_info.get_trigger_name());
9123
  return ret;
9124
}
9125

9126
int ObDDLOperator::fill_trigger_id(ObSchemaService &schema_service, ObTriggerInfo &trigger_info)
9127
{
9128
  int ret = OB_SUCCESS;
9129
  uint64_t new_trigger_id = OB_INVALID_ID;
9130
  OV (OB_INVALID_ID == trigger_info.get_trigger_id());
9131
  OZ (schema_service.fetch_new_trigger_id(trigger_info.get_tenant_id(), new_trigger_id),
9132
      trigger_info.get_trigger_name());
9133
  OX (trigger_info.set_trigger_id(new_trigger_id));
9134
  return ret;
9135
}
9136

9137
/* [data_table_prefix]_[data_table_id]_RECYCLE_[object_type_prefix]_[timestamp].
9138
 * data_table_prefix: if not null, use '[data_table_prefix]_[data_table_id]' as prefix,
9139
 *                    otherwise, skip this part.
9140
 * object_type_prefix: OBIDX / OBCHECK / OBTRG ...
9141
 */
9142
template <typename SchemaType>
9143
int ObDDLOperator::build_flashback_object_name(const SchemaType &object_schema,
9144
                                               const char *data_table_prefix,
9145
                                               const char *object_type_prefix,
9146
                                               ObSchemaGetterGuard &schema_guard,
9147
                                               ObIAllocator &allocator,
9148
                                               ObString &object_name)
9149
{
9150
  int ret = OB_SUCCESS;
9151
  char *buf = NULL;
9152
  int64_t buf_len = 0;
9153
  int64_t pos = 0;
9154
  int64_t saved_pos = 0;
9155
  bool object_exist = true;
9156
  static const char *RECYCLE = "RECYCLE";
9157
  static const int64_t INT64_STR_LEN = 20;
9158
  OV (OB_NOT_NULL(object_type_prefix));
9159
  if (OB_NOT_NULL(data_table_prefix)) {
9160
    OX (buf_len += (STRLEN(data_table_prefix) + 1 +   // [data_table_prefix]_
9161
                    INT64_STR_LEN + 1));              // [data_table_id]_
9162
  }
9163
  OX (buf_len += (STRLEN(RECYCLE) + 1 +               // RECYCLE_
9164
                  STRLEN(object_type_prefix) + 1 +    // [object_type_prefix]_
9165
                  INT64_STR_LEN));                    // [timestamp]
9166
  OV (OB_NOT_NULL(buf = static_cast<char *>(allocator.alloc(buf_len))),
9167
      OB_ALLOCATE_MEMORY_FAILED, buf_len);
9168
  if (OB_NOT_NULL(data_table_prefix)) {
9169
    OZ (BUF_PRINTF("%s_%lu_", data_table_prefix, object_schema.get_data_table_id()));
9170
  }
9171
  OZ (BUF_PRINTF("%s_%s_", RECYCLE, object_type_prefix));
9172
  OX (saved_pos = pos);
9173
  while (OB_SUCC(ret) && object_exist) {
9174
    OX (pos = saved_pos);
9175
    OZ (BUF_PRINTF("%ld", ObTimeUtility::current_time()));
9176
    OX (object_name.assign(buf, static_cast<int32_t>(pos)));
9177
    OZ (schema_guard.check_flashback_object_exist(object_schema, object_name, object_exist));
9178
  }
9179
  return ret;
9180
}
9181

9182
// functions for managing udt
9183

9184
int ObDDLOperator::create_udt(ObUDTTypeInfo &udt_info,
9185
                              ObMySQLTransaction &trans,
9186
                              ObErrorInfo &error_info,
9187
                              ObIArray<share::schema::ObRoutineInfo> &public_routine_infos,
9188
                              ObSchemaGetterGuard &schema_guard,
9189
                              ObIArray<ObDependencyInfo> &dep_infos,
9190
                              const ObString *ddl_stmt_str)
9191
{
9192
  UNUSED(schema_guard);
9193
  int ret = OB_SUCCESS;
9194
  uint64_t new_udt_id = OB_INVALID_ID;
9195
  const uint64_t tenant_id = udt_info.get_tenant_id();
9196
  int64_t new_schema_version = OB_INVALID_VERSION;
9197
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9198
  ObUDTObjectType *obj_info = NULL;
9199

9200
  if (OB_ISNULL(schema_service)) {
9201
    ret = OB_ERR_SYS;
9202
    LOG_ERROR("schema_service must not null", K(ret));
9203
  } else if (OB_SYS_TENANT_ID == tenant_id
9204
        && !is_inner_pl_udt_id(new_udt_id = udt_info.get_type_id())) {
9205
    ret = OB_ERR_UNEXPECTED;
9206
    LOG_WARN("failed to get new system udt id", K(tenant_id), K(ret));
9207
  } else if (OB_SYS_TENANT_ID != tenant_id
9208
        && OB_FAIL(schema_service->fetch_new_udt_id(tenant_id, new_udt_id))) {
9209
    LOG_WARN("failed to fetch new_udt_id", K(tenant_id), K(ret));
9210
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9211
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9212
  } else {
9213
    // object spec and collection
9214
    if (udt_info.is_object_spec_ddl() || !udt_info.is_object_type()) {
9215
      udt_info.set_type_id(new_udt_id);
9216
      if (udt_info.is_object_spec_ddl()
9217
          && 0 < udt_info.get_object_type_infos().count()) {
9218
        OX (obj_info = udt_info.get_object_type_infos().at(0));
9219
        CK (OB_NOT_NULL(obj_info));
9220
        // set object spec id
9221
        uint64_t new_obj_id = OB_INVALID_ID;
9222
        if (OB_SYS_TENANT_ID == tenant_id) {
9223
          OZ (schema_service->fetch_new_sys_pl_object_id(tenant_id, new_obj_id));
9224
        } else {
9225
          OZ (schema_service->fetch_new_udt_id(tenant_id, new_obj_id));
9226
        }
9227
        OX (obj_info->set_coll_type(new_obj_id));
9228
      }
9229
    } else { // object body
9230
      CK (2 == udt_info.get_object_type_infos().count());
9231
      OX (obj_info = udt_info.get_object_type_infos().at(1));
9232
      CK (OB_NOT_NULL(obj_info));
9233
      // set object body id
9234
      OX (obj_info->set_coll_type(new_udt_id));
9235
      // udt_info.set_type_id(new_udt_id);
9236
    }
9237
    udt_info.set_schema_version(new_schema_version);
9238
    if (FAILEDx(schema_service->get_udt_sql_service().create_udt(udt_info,
9239
                                                                 &trans,
9240
                                                                 ddl_stmt_str))) {
9241
      LOG_WARN("insert udt info failed", K(udt_info), K(ret));
9242
    } else {
9243
      ARRAY_FOREACH(public_routine_infos, routine_idx) {
9244
        ObRoutineInfo &routine_info = public_routine_infos.at(routine_idx);
9245
        if (udt_info.is_object_spec_ddl()) {
9246
          if (OB_FAIL(update_routine_info(routine_info,
9247
                                          tenant_id,
9248
                                          udt_info.get_type_id(),
9249
                                          udt_info.get_database_id(),
9250
                                          udt_info.get_database_id()))) {
9251
            LOG_WARN("failed to update routine info", K(ret));
9252
          } else if (OB_FAIL(schema_service->get_routine_sql_service().create_routine(routine_info,
9253
                                                                        &trans, NULL))) {
9254
            LOG_WARN("insert routine info failed", K(routine_info), K(ret));
9255
          }
9256
        } else {
9257
          // update routine route sql
9258
          int64_t new_schema_version = OB_INVALID_VERSION;
9259
          OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
9260
          OX (routine_info.set_schema_version(new_schema_version));
9261
          OZ (schema_service->get_routine_sql_service().update_routine(routine_info, &trans));
9262
        }
9263
      }
9264
    }
9265
  }
9266
  if (OB_SUCC(ret) && !is_inner_pl_udt_id(new_udt_id)) {
9267
    OZ (insert_dependency_infos(trans, dep_infos, tenant_id, new_udt_id,
9268
                                new_schema_version,
9269
                                udt_info.get_database_id()));
9270
  }
9271
  if (OB_SUCC(ret)) {
9272
    if (OB_FAIL(error_info.handle_error_info(trans, &udt_info))) {
9273
      LOG_WARN("insert trigger error info failed.", K(ret), K(error_info));
9274
    }
9275
  }
9276
  return ret;
9277
}
9278

9279
int ObDDLOperator::replace_udt(ObUDTTypeInfo &udt_info,
9280
                               const ObUDTTypeInfo *old_udt_info,
9281
                               ObMySQLTransaction &trans,
9282
                               ObErrorInfo &error_info,
9283
                               ObIArray<share::schema::ObRoutineInfo> &public_routine_infos,
9284
                               ObSchemaGetterGuard &schema_guard,
9285
                               ObIArray<ObDependencyInfo> &dep_infos,
9286
                               const ObString *ddl_stmt_str)
9287
{
9288
  int ret = OB_SUCCESS;
9289
  const uint64_t tenant_id = udt_info.get_tenant_id();
9290
  int64_t del_param_schema_version = OB_INVALID_VERSION;
9291
  int64_t new_schema_version = OB_INVALID_VERSION;
9292
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9293
  CK(OB_NOT_NULL(schema_service));
9294
  CK(OB_NOT_NULL(old_udt_info));
9295
  if (old_udt_info->get_attrs().count() > 0 || OB_NOT_NULL(old_udt_info->get_coll_info())) {
9296
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, del_param_schema_version))) {
9297
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9298
    }
9299
  }
9300

9301
  if (OB_FAIL(ret)) {
9302
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9303
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9304
  } else {
9305
    udt_info.set_schema_version(new_schema_version);
9306
    udt_info.set_type_id(old_udt_info->get_type_id());
9307
  }
9308

9309
  if (OB_SUCC(ret)) {
9310
    ObUDTObjectType *old_obj_info = NULL, *new_obj_info = NULL;
9311
    if (udt_info.is_object_spec_ddl()) {
9312
      // create or replace xxx is object(a number), no object type info
9313
      // CK (0 < old_udt_info->get_object_type_infos().count());
9314
      // CK (0 < udt_info.get_object_type_infos().count());
9315
      if (udt_info.get_object_type_infos().count() > 0) {
9316
        OX (new_obj_info = udt_info.get_object_type_infos().at(0));
9317
        if (old_udt_info->get_object_type_infos().count() > 0) {
9318
          OX (old_obj_info = old_udt_info->get_object_type_infos().at(0));
9319
          OX (new_obj_info->set_coll_type(old_obj_info->get_coll_type()));
9320
        } else {
9321
          uint64_t new_obj_id = OB_INVALID_ID;
9322
          if (OB_SYS_TENANT_ID == tenant_id) {
9323
            OZ (schema_service->fetch_new_sys_pl_object_id(tenant_id, new_obj_id));
9324
          } else {
9325
            OZ (schema_service->fetch_new_udt_id(tenant_id, new_obj_id));
9326
          }
9327
          OX (new_obj_info->set_coll_type(new_obj_id));
9328
        }
9329
      }
9330
    } else if (udt_info.is_object_body_ddl()) {
9331
      CK (2 == old_udt_info->get_object_type_infos().count());
9332
      CK (2 == udt_info.get_object_type_infos().count());
9333
      OX (old_obj_info = old_udt_info->get_object_type_infos().at(1));
9334
      OX (new_obj_info = udt_info.get_object_type_infos().at(1));
9335
      OX (new_obj_info->set_coll_type(old_obj_info->get_coll_type()));
9336
    } else {
9337
      // do nothing
9338
    }
9339
  }
9340

9341
  OZ (ObDependencyInfo::delete_schema_object_dependency(trans, tenant_id,
9342
                                     old_udt_info->get_type_id(),
9343
                                     new_schema_version,
9344
                                     old_udt_info->get_object_type()));
9345
  OZ (ObDependencyInfo::delete_schema_object_dependency(trans, tenant_id,
9346
                                     udt_info.get_type_id(),
9347
                                     new_schema_version,
9348
                                     udt_info.get_object_type()));
9349
  if (OB_SUCC(ret)) {
9350
    // Discuss whether the built-in functions of the object type need to be deleted and then inserted in several situations
9351
    // 1. spec spec replace , need delete, Because the definition of the function may have changed
9352
    // 2. spec body replace, need delete, Although the function definition cannot be changed,
9353
    // the parameters may change, because some member functions will add a self parameter,
9354
    // which needs to be added to the __all_routine_param table.
9355
    // 3. body body replace, need delete, Because the function body may have changed. type_id has also changed
9356
    // bool need_del_routines = true;
9357
    // if ((udt_info.is_object_type() && udt_info.is_object_body_ddl()
9358
    //      && old_udt_info->is_object_type() && old_udt_info->is_object_body_ddl())) {
9359
    //           need_del_routines = false;
9360
    // }
9361
    if (udt_info.is_object_spec_ddl() && OB_FAIL(del_routines_in_udt(udt_info, trans, schema_guard))) {
9362
      LOG_WARN("failed to delete functions", K(ret));
9363
    } else if (OB_FAIL(schema_service->get_udt_sql_service().replace_udt(udt_info,
9364
                                                                   old_udt_info,
9365
                                                                   del_param_schema_version,
9366
                                                                   &trans,
9367
                                                                   ddl_stmt_str))) {
9368
      LOG_WARN("replace udt info failed", K(udt_info), K(ret));
9369
    } else {
9370
      ARRAY_FOREACH(public_routine_infos, routine_idx) {
9371
        ObRoutineInfo &routine_info = public_routine_infos.at(routine_idx);
9372
        if (udt_info.is_object_spec_ddl()) {
9373
          if (OB_FAIL(update_routine_info(routine_info,
9374
                                        tenant_id,
9375
                                        udt_info.get_type_id(),
9376
                                        udt_info.get_database_id(),
9377
                                        udt_info.get_database_id()))) {
9378
            LOG_WARN("failed to update routine info", K(ret));
9379
          } else if (OB_FAIL(schema_service->get_routine_sql_service().create_routine(routine_info,
9380
                                                                        &trans, NULL))) {
9381
            LOG_WARN("insert routine info failed", K(routine_info), K(ret));
9382
          }
9383
        } else {
9384
          // update routine route sql
9385
          int64_t new_schema_version = OB_INVALID_VERSION;
9386
          OZ (schema_service_.gen_new_schema_version(tenant_id, new_schema_version));
9387
          OX (routine_info.set_schema_version(new_schema_version));
9388
          OZ (schema_service->get_routine_sql_service().update_routine(routine_info, &trans));
9389
        }
9390
      }
9391
    }
9392
  }
9393
  OZ (insert_dependency_infos(trans, dep_infos, tenant_id, udt_info.get_type_id(),
9394
                                udt_info.get_schema_version(),
9395
                                udt_info.get_database_id()));
9396
  if (OB_SUCC(ret)) {
9397
    if (OB_FAIL(error_info.handle_error_info(trans, &udt_info))) {
9398
      LOG_WARN("insert trigger error info failed.", K(ret), K(error_info));
9399
    }
9400
  }
9401
  return ret;
9402
}
9403

9404
int ObDDLOperator::drop_udt(const ObUDTTypeInfo &udt_info,
9405
                            ObMySQLTransaction &trans,
9406
                            ObSchemaGetterGuard &schema_guard,
9407
                            const ObString *ddl_stmt_str)
9408
{
9409
  int ret = OB_SUCCESS;
9410
  const uint64_t tenant_id = udt_info.get_tenant_id();
9411
  int64_t new_schema_version = OB_INVALID_VERSION;
9412
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9413

9414
  if (OB_ISNULL(schema_service)) {
9415
    ret = OB_ERR_SYS;
9416
    LOG_ERROR("schema_service must not null", K(ret));
9417
  } else if (OB_FAIL(drop_obj_privs(tenant_id, udt_info.get_type_id(),
9418
                                    static_cast<uint64_t>(ObObjectType::TYPE),
9419
                                    trans))) {
9420
    LOG_WARN("fail to drop_obj_privs", K(ret), K(udt_info), K(tenant_id));
9421
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9422
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9423
  } else if (udt_info.is_object_spec_ddl() && OB_FAIL(del_routines_in_udt(udt_info,
9424
                                                                      trans, schema_guard))) {
9425
    LOG_WARN("faile to drop routines in udt", K(ret));
9426
  } else if (OB_FAIL(schema_service->get_udt_sql_service().drop_udt(udt_info,
9427
                                                                    new_schema_version,
9428
                                                                    trans, ddl_stmt_str))) {
9429
    LOG_WARN("drop udt info failed", K(udt_info), K(ret));
9430
  }
9431
  OZ (ObDependencyInfo::delete_schema_object_dependency(trans, tenant_id,
9432
                                     udt_info.get_type_id(),
9433
                                     new_schema_version,
9434
                                     udt_info.get_object_type()));
9435
  if (OB_SUCC(ret)) {
9436
    ObErrorInfo error_info;
9437
    if (OB_FAIL(error_info.handle_error_info(trans, &udt_info))) {
9438
      LOG_WARN("insert trigger error info failed.", K(ret), K(error_info));
9439
    }
9440
  }
9441
  return ret;
9442
}
9443

9444
int ObDDLOperator::del_routines_in_udt(const ObUDTTypeInfo &udt_info,
9445
                                           ObMySQLTransaction &trans,
9446
                                           ObSchemaGetterGuard &schema_guard)
9447
{
9448
  int ret = OB_SUCCESS;
9449
  ObSchemaService *schema_service_impl = schema_service_.get_schema_service();
9450
  const uint64_t tenant_id = udt_info.get_tenant_id();
9451
  uint64_t udt_id = udt_info.get_type_id();
9452
  if (OB_INVALID_ID == tenant_id
9453
      || OB_INVALID_ID == udt_id) {
9454
    ret = OB_INVALID_ARGUMENT;
9455
    LOG_WARN("invalid argument", K(ret));
9456
  } else {
9457
    ObArray<const ObRoutineInfo *> routines;
9458
    if (OB_FAIL(schema_guard.get_routine_infos_in_udt(tenant_id, udt_id, routines))) {
9459
      LOG_WARN("get routines in udt failed", K(tenant_id), K(udt_id), K(ret));
9460
    } else {
9461
      for (int64_t i = 0; OB_SUCC(ret) && i < routines.count(); ++i) {
9462
        const ObRoutineInfo *routine_info = routines.at(i);
9463
        int64_t new_schema_version = OB_INVALID_VERSION;
9464
        if (OB_ISNULL(routine_info)) {
9465
          ret = OB_ERR_UNEXPECTED;
9466
          LOG_WARN("routine info is NULL", K(ret));
9467
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9468
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9469
        } else if (OB_FAIL(schema_service_impl->get_routine_sql_service().drop_routine(
9470
                           *routine_info, new_schema_version, trans))) {
9471
          LOG_WARN("drop routine failed", "routine_id", routine_info->get_routine_id(), K(ret));
9472
        }
9473
      }
9474
    }
9475
  }
9476
  return ret;
9477
}
9478

9479
//----Functions for managing UDF----
9480
int ObDDLOperator::create_user_defined_function(share::schema::ObUDF &udf_info,
9481
                                                common::ObMySQLTransaction &trans,
9482
                                                const common::ObString *ddl_stmt_str/*=NULL*/)
9483
{
9484
  int ret = OB_SUCCESS;
9485
  uint64_t new_udf_id = OB_INVALID_ID;
9486
  const uint64_t tenant_id = udf_info.get_tenant_id();
9487
  int64_t new_schema_version = OB_INVALID_VERSION;
9488
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9489
  if (OB_ISNULL(schema_service)) {
9490
    ret = OB_ERR_SYS;
9491
    LOG_ERROR("schema_service must exist", K(ret));
9492
  } else if (OB_FAIL(schema_service->fetch_new_udf_id(tenant_id, new_udf_id))) {
9493
    LOG_WARN("failed to fetch new_udf_id", K(tenant_id), K(ret));
9494
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9495
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9496
  } else {
9497
    udf_info.set_udf_id(new_udf_id);
9498
    udf_info.set_schema_version(new_schema_version);
9499
    if (OB_FAIL(schema_service->get_udf_sql_service().insert_udf(udf_info, &trans, ddl_stmt_str))) {
9500
      LOG_WARN("insert udf info failed", K(udf_info.get_name_str()), K(ret));
9501
    }
9502
  }
9503
  return ret;
9504
}
9505

9506
int ObDDLOperator::drop_user_defined_function(const uint64_t tenant_id,
9507
                                              const common::ObString &name,
9508
                                              common::ObMySQLTransaction &trans,
9509
                                              const common::ObString *ddl_stmt_str/*=NULL*/)
9510
{
9511
  int ret = OB_SUCCESS;
9512
  int64_t new_schema_version = OB_INVALID_VERSION;
9513
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9514
  if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) {
9515
    ret = OB_INVALID_ARGUMENT;
9516
    LOG_WARN("invalid arguments", K(tenant_id), K(ret));
9517
  } else if (OB_ISNULL(schema_service)) {
9518
    ret = OB_ERR_SYS;
9519
    LOG_ERROR("schema_service must exist", K(ret));
9520
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9521
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9522
  } else if (OB_FAIL(schema_service->get_udf_sql_service().delete_udf(
9523
      tenant_id,
9524
      name,
9525
      new_schema_version,
9526
      &trans,
9527
      ddl_stmt_str))) {
9528
    LOG_WARN("drop udf failed", K(tenant_id), K(name), K(ret));
9529
  } else {/*do nothing*/}
9530
  return ret;
9531
}
9532
//----End of functions for managing UDF----
9533

9534
int ObDDLOperator::insert_ori_schema_version(
9535
    ObMySQLTransaction &trans,
9536
    const uint64_t tenant_id,
9537
    const uint64_t table_id,
9538
    const int64_t &ori_schema_version)
9539
{
9540
  int ret = OB_SUCCESS;
9541
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9542
  if (OB_INVALID_VERSION == ori_schema_version
9543
      || !is_valid_tenant_id(tenant_id)) {
9544
    ret = OB_ERR_UNEXPECTED;
9545
    LOG_WARN("invalid schema version" , K(ret), K(tenant_id), K(table_id), K(ori_schema_version));
9546
  } else if (OB_FAIL(schema_service->get_table_sql_service().insert_ori_schema_version(
9547
             trans, tenant_id, table_id, ori_schema_version))) {
9548
    LOG_WARN("insert_ori_schema_version failed", K(ret), K(tenant_id), K(table_id), K(ori_schema_version));
9549
  }
9550
  return ret;
9551
}
9552

9553
int ObDDLOperator::insert_temp_table_info(ObMySQLTransaction &trans, const ObTableSchema &table_schema)
9554
{
9555
  int ret = OB_SUCCESS;
9556
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9557
  if (OB_ISNULL(schema_service)) {
9558
    ret = OB_ERR_UNEXPECTED;
9559
    LOG_WARN("get invalid schema service", K(ret));
9560
  } else if (table_schema.is_ctas_tmp_table() || table_schema.is_tmp_table()) {
9561
    if (is_inner_table(table_schema.get_table_id())) {
9562
      ret = OB_OP_NOT_ALLOW;
9563
      LOG_WARN("create tmp sys table not allowed", K(ret), "table_id", table_schema.get_table_id());
9564
    } else if (OB_FAIL(schema_service->get_table_sql_service().insert_temp_table_info(trans, table_schema))) {
9565
      LOG_WARN("insert_temp_table_info failed", K(ret));
9566
    }
9567
  }
9568
  return ret;
9569
}
9570

9571
int ObDDLOperator::delete_temp_table_info(ObMySQLTransaction &trans, const ObTableSchema &table_schema)
9572
{
9573
  int ret = OB_SUCCESS;
9574
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9575
  if (OB_ISNULL(schema_service)) {
9576
    ret = OB_ERR_UNEXPECTED;
9577
    LOG_WARN("get invalid schema service", K(ret));
9578
  } else if (is_inner_table(table_schema.get_table_id())) {
9579
    ret = OB_OP_NOT_ALLOW;
9580
    LOG_WARN("create tmp sys table not allowed", K(ret), "table_id", table_schema.get_table_id());
9581
  } else if (OB_FAIL(schema_service->get_table_sql_service().delete_from_all_temp_table(
9582
              trans, table_schema.get_tenant_id(), table_schema.get_table_id()))) {
9583
    LOG_WARN("insert_temp_table_info failed", K(ret));
9584
  }
9585
  return ret;
9586
}
9587

9588
int ObDDLOperator::drop_trigger_cascade(const ObTableSchema &table_schema,
9589
                                        ObMySQLTransaction &trans)
9590
{
9591
  int ret = OB_SUCCESS;
9592
  ObSchemaGetterGuard schema_guard;
9593
  const ObIArray<uint64_t> &trigger_list = table_schema.get_trigger_list();
9594
  const ObTriggerInfo *trigger_info = NULL;
9595
  uint64_t tenant_id = table_schema.get_tenant_id();
9596
  uint64_t trigger_id = OB_INVALID_ID;
9597
  OZ (schema_service_.get_tenant_schema_guard(tenant_id, schema_guard), tenant_id);
9598
  for (int64_t i = 0; OB_SUCC(ret) && i < trigger_list.count(); i++) {
9599
    OX (trigger_id = trigger_list.at(i));
9600
    OZ (schema_guard.get_trigger_info(tenant_id, trigger_id, trigger_info));
9601
    OV (OB_NOT_NULL(trigger_info));
9602
    OZ (drop_trigger(*trigger_info, trans, NULL), trigger_info);
9603
  }
9604
  return ret;
9605
}
9606

9607
int ObDDLOperator::drop_inner_generated_index_column(ObMySQLTransaction &trans,
9608
                                                    ObSchemaGetterGuard &schema_guard,
9609
                                                    const ObTableSchema &index_schema,
9610
                                                    ObTableSchema &new_data_table_schema)
9611
{
9612
  int ret = OB_SUCCESS;
9613
  const ObTableSchema *data_table = NULL;
9614
  const ObColumnSchemaV2 *index_col = NULL;
9615
  const uint64_t tenant_id = index_schema.get_tenant_id();
9616
  uint64_t data_table_id = index_schema.get_data_table_id();
9617
  const ObIndexInfo &index_info = index_schema.get_index_info();
9618
  if (OB_FAIL(schema_guard.get_table_schema(tenant_id, data_table_id, data_table))) {
9619
    LOG_WARN("get table schema failed", KR(ret), K(tenant_id), K(data_table_id));
9620
  } else if (OB_ISNULL(data_table)) {
9621
    ret = OB_ERR_UNEXPECTED;
9622
    LOG_WARN("data table schema is unknown", K(data_table_id));
9623
  } else if (!new_data_table_schema.is_valid()) {
9624
    if (OB_FAIL(new_data_table_schema.assign(*data_table))) {
9625
      LOG_WARN("fail to assign schema", K(ret));
9626
    }
9627
  }
9628
  ObSEArray<ObAuxTableMetaInfo, 16> simple_index_infos;
9629
  if (OB_FAIL(ret)) {
9630
  } else if (OB_FAIL(new_data_table_schema.get_simple_index_infos(simple_index_infos))) {
9631
    LOG_WARN("get simple_index_infos failed", K(ret));
9632
  } else {
9633
    new_data_table_schema.set_in_offline_ddl_white_list(index_schema.get_in_offline_ddl_white_list());
9634
  }
9635
  for (int64_t i = 0; OB_SUCC(ret) && i < index_info.get_size(); ++i) {
9636
    // Generated columns on index table are converted to normal column,
9637
    // we need to get column schema from data table here.
9638
    if (OB_ISNULL(index_col = data_table->get_column_schema(
9639
        tenant_id, index_info.get_column(i)->column_id_))) {
9640
      ret = OB_ERR_UNEXPECTED;
9641
      LOG_WARN("get index column schema failed", K(ret), K(tenant_id), K(index_info));
9642
    } else if (index_col->is_hidden() && index_col->is_generated_column()) {
9643
      // delete the generated column generated internally when the index is created,
9644
      // This kind of generated column is hidden.
9645
      // delete generated column in data table for spatial index
9646
      bool exist_index = false;
9647
      for (int64_t j = 0; OB_SUCC(ret) && !exist_index && j < simple_index_infos.count(); ++j) {
9648
        const ObColumnSchemaV2 *tmp_col = NULL;
9649
        if (simple_index_infos.at(j).table_id_ != index_schema.get_table_id()) {
9650
          // If there are other indexes on the hidden column, they cannot be deleted.
9651
          if (OB_FAIL(schema_guard.get_column_schema(tenant_id,
9652
              simple_index_infos.at(j).table_id_, index_col->get_column_id(), tmp_col))) {
9653
            LOG_WARN("get column schema from schema guard failed", KR(ret), K(tenant_id),
9654
                     K(simple_index_infos.at(j).table_id_), K(index_col->get_column_id()));
9655
          } else if (tmp_col != NULL) {
9656
            exist_index = true;
9657
          }
9658
        }
9659
      }
9660
      // There are no other indexes, delete the hidden column.
9661
      if (OB_SUCC(ret) && !exist_index) {
9662
				// if generate column is not the last column // 1. update prev_column_id // 2. update inner table
9663
        if (OB_FAIL(update_prev_id_for_delete_column(*data_table, new_data_table_schema, *index_col, trans))) {
9664
          LOG_WARN("failed to update column previous id for delete column", K(ret));
9665
        } else if (OB_FAIL(delete_single_column(trans, new_data_table_schema, index_col->get_column_name_str()))) {
9666
          LOG_WARN("delete index inner generated column failed", K(new_data_table_schema), K(*index_col));
9667
        }
9668
      }
9669
    }
9670
  }
9671
  if (OB_SUCC(ret)) {
9672
    if (OB_FAIL(alter_table_options(schema_guard,
9673
                                    new_data_table_schema,
9674
                                    *data_table,
9675
                                    false,
9676
                                    trans))) {
9677
      LOG_WARN("alter table options failed", K(ret), K(new_data_table_schema));
9678
    } else {
9679
      for (int64_t j = 0; OB_SUCC(ret) && j < simple_index_infos.count(); ++j) {
9680
        if (simple_index_infos.at(j).table_id_ == index_schema.get_table_id()) {
9681
          simple_index_infos.remove(j);
9682
          if (OB_FAIL(new_data_table_schema.set_simple_index_infos(simple_index_infos))) {
9683
            LOG_WARN("fail to set simple index infos", K(ret));
9684
          }
9685
          break;
9686
        }
9687
      }
9688
    }
9689
  }
9690

9691
  return ret;
9692
}
9693

9694
int ObDDLOperator::create_tablespace(ObTablespaceSchema &tablespace_schema,
9695
    common::ObMySQLTransaction &trans,
9696
    share::schema::ObSchemaGetterGuard &schema_guard,
9697
    const common::ObString *ddl_stmt_str)
9698
{
9699
  int ret = OB_SUCCESS;
9700
  UNUSED(schema_guard);
9701
  uint64_t new_ts_id = OB_INVALID_ID;
9702
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9703
  const uint64_t tenant_id = tablespace_schema.get_tenant_id();
9704
  int64_t new_schema_version = OB_INVALID_VERSION;
9705
  if (OB_ISNULL(schema_service)) {
9706
    ret = OB_ERR_UNEXPECTED;
9707
    LOG_WARN("get invalid schema service", K(ret));
9708
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9709
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9710
  } else {
9711
    tablespace_schema.set_schema_version(new_schema_version);
9712
  }
9713
  if (OB_FAIL(ret)) {
9714
    /*do nothing*/
9715
  } else if (OB_FAIL(schema_service->fetch_new_tablespace_id(
9716
          tablespace_schema.get_tenant_id(), new_ts_id))) {
9717
    LOG_WARN("failed to fetch_new_table_id", K(ret));
9718
  } else if (OB_INVALID_ID == new_ts_id) {
9719
    ret = OB_ERR_UNEXPECTED;
9720
    LOG_WARN("get invalid schema id", K(ret));
9721
  } else if (FALSE_IT(tablespace_schema.set_tablespace_id(new_ts_id))) {
9722
  } else if(OB_FAIL(schema_service->get_tablespace_sql_service().create_tablespace(
9723
      tablespace_schema, trans, ddl_stmt_str))) {
9724
    LOG_WARN("create tablespace failed", K(ret));
9725
  }
9726

9727
  return ret;
9728
}
9729

9730
int ObDDLOperator::alter_tablespace(ObTablespaceSchema &tablespace_schema,
9731
    common::ObMySQLTransaction &trans,
9732
    share::schema::ObSchemaGetterGuard &schema_guard,
9733
    const common::ObString *ddl_stmt_str)
9734
{
9735
  int ret = OB_SUCCESS;
9736
  UNUSED(schema_guard);
9737
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9738
  const uint64_t tenant_id = tablespace_schema.get_tenant_id();
9739
  int64_t new_schema_version = OB_INVALID_VERSION;
9740
  if (OB_ISNULL(schema_service)) {
9741
    ret = OB_ERR_UNEXPECTED;
9742
    LOG_WARN("get invalid schema service", K(ret));
9743
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9744
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9745
  } else {
9746
    tablespace_schema.set_schema_version(new_schema_version);
9747
  }
9748
  if (OB_FAIL(ret)) {
9749
    /*do nothing*/
9750
  } else if(OB_FAIL(schema_service->get_tablespace_sql_service().alter_tablespace(
9751
      tablespace_schema, trans, ddl_stmt_str))) {
9752
    LOG_WARN("alter tablespace failed", K(ret));
9753
  } else {
9754
    // Change of tablespace state, change the cascading table_schema attribute under tablespace
9755
    // Currently only supports encryption, it needs to be changed, so there is no more judgment here
9756
    common::ObArray<const share::schema::ObTableSchema *> table_schemas;
9757
    if (OB_FAIL(schema_guard.get_table_schemas_in_tenant(tenant_id, table_schemas))) {
9758
      LOG_WARN("fail to get table schemas in tenant", K(ret));
9759
    } else {
9760
      for (int i = 0; i < table_schemas.count() && OB_SUCC(ret); ++i) {
9761
        if (table_schemas.at(i)->get_tablespace_id() != OB_INVALID_ID &&
9762
          table_schemas.at(i)->get_tablespace_id() == tablespace_schema.get_tablespace_id()) {
9763
          if (OB_FAIL(update_tablespace_table(table_schemas.at(i), trans, tablespace_schema))) {
9764
            LOG_WARN("fail to push back table schema", K(ret));
9765
          }
9766
        }
9767
      }
9768
    }
9769
  }
9770
  return ret;
9771
}
9772

9773
int ObDDLOperator::update_tablespace_table(
9774
    const share::schema::ObTableSchema *table_schema,
9775
    common::ObMySQLTransaction &trans,
9776
    ObTablespaceSchema &tablespace_schema)
9777
{
9778
  int ret = OB_SUCCESS;
9779
  // Currently this interface only supports cascading update encryption
9780
  share::schema::ObTableSchema new_table_schema;
9781
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9782
  int64_t tenant_id = table_schema->get_tenant_id();
9783
  int64_t new_schema_version = OB_INVALID_VERSION;
9784
  if (OB_ISNULL(schema_service)) {
9785
    ret = OB_ERR_UNEXPECTED;
9786
    LOG_WARN("get invalid schema service", K(ret));
9787
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9788
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9789
  } else if (OB_FAIL(new_table_schema.assign(*table_schema))) {
9790
    LOG_WARN("fail to assign table schema", K(ret));
9791
  } else {
9792
    new_table_schema.set_schema_version(new_schema_version);
9793
    new_table_schema.set_encryption_str(tablespace_schema.get_encryption_name());
9794
    if (OB_FAIL(schema_service->get_table_sql_service().update_table_options(trans,
9795
      *table_schema, new_table_schema, OB_DDL_ALTER_TABLE, NULL))) {
9796
      LOG_WARN("fail to update data table schema version", K(ret),
9797
          K(new_table_schema.get_table_id()));
9798
    }
9799
  }
9800
  return ret;
9801
}
9802

9803
int ObDDLOperator::drop_tablespace(ObTablespaceSchema &tablespace_schema,
9804
    common::ObMySQLTransaction &trans,
9805
    share::schema::ObSchemaGetterGuard &schema_guard,
9806
    const common::ObString *ddl_stmt_str)
9807
{
9808
  int ret = OB_SUCCESS;
9809
  ObArray<const ObTableSchema *> tables;
9810
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9811
  uint64_t tablespace_id = tablespace_schema.get_tablespace_id();
9812
  const uint64_t tenant_id = tablespace_schema.get_tenant_id();
9813
  int64_t new_schema_version = OB_INVALID_VERSION;
9814
  if (OB_ISNULL(schema_service)) {
9815
    ret = OB_ERR_UNEXPECTED;
9816
    LOG_WARN("get invalid schema service", K(ret));
9817
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9818
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9819
  } else {
9820
    tablespace_schema.set_schema_version(new_schema_version);
9821
  }
9822
  if (OB_FAIL(ret)) {
9823
    /*do nothing*/
9824
  } else if (OB_FAIL(schema_guard.get_table_schemas_in_tablespace(tenant_id, tablespace_id, tables))) {
9825
    LOG_WARN("get tables in tablespace failed", K(tenant_id), KT(tablespace_id), K(ret));
9826
  } else if (tables.count() > 0) {
9827
    ret = OB_TABLESPACE_DELETE_NOT_EMPTY;
9828
    LOG_WARN("can not delete a tablespace which is not empty", K(ret));
9829
  } else if (OB_FAIL(schema_service->get_tablespace_sql_service().drop_tablespace(
9830
      tablespace_schema, trans, ddl_stmt_str))) {
9831
    LOG_WARN("drop tablespace failed", K(ret));
9832
  }
9833
  return ret;
9834
}
9835

9836
// revise column info of check constraints
9837
int ObDDLOperator::revise_constraint_column_info(
9838
    obrpc::ObSchemaReviseArg arg,
9839
    common::ObMySQLTransaction &trans)
9840
{
9841
  int ret = OB_SUCCESS;
9842
  const uint64_t tenant_id = arg.tenant_id_;
9843
  int64_t new_schema_version = OB_INVALID_VERSION;
9844
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9845
  ObSchemaGetterGuard schema_guard;
9846
  const ObTableSchema *table_schema = nullptr;
9847
  if (OB_ISNULL(schema_service)) {
9848
    ret = OB_ERR_UNEXPECTED;
9849
    LOG_WARN("schema_service is NULL", K(ret));
9850
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
9851
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
9852
  } else {
9853
    for (int64_t i = 0; OB_SUCC(ret) && i < arg.csts_array_.count(); ++i) {
9854
      arg.csts_array_.at(i).set_schema_version(new_schema_version);
9855
    }
9856
  }
9857
  if (OB_SUCC(ret)) {
9858
    if (OB_FAIL(schema_service_.get_tenant_schema_guard(tenant_id, schema_guard))) {
9859
      LOG_WARN("get tenant schema guard failed", K(ret), K(tenant_id));
9860
    } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, arg.table_id_, table_schema))) {
9861
      LOG_WARN("get table schema failed", K(ret), K(tenant_id), K(arg.table_id_));
9862
    } else if (nullptr == table_schema) {
9863
      ret = OB_ERR_UNEXPECTED;
9864
      LOG_WARN("error unexpected, table schema must not be nullptr", K(ret));
9865
    } else if (OB_FAIL(schema_service->get_table_sql_service().revise_check_cst_column_info(
9866
                trans, *table_schema, arg.csts_array_))) {
9867
      LOG_WARN("insert single constraint failed", K(ret), K(arg.csts_array_));
9868
    } else if (OB_FAIL(schema_service->get_table_sql_service().update_data_table_schema_version(
9869
               trans, tenant_id, arg.table_id_, table_schema->get_in_offline_ddl_white_list()))) {
9870
      LOG_WARN("update data_table_schema version failed", K(ret), K(arg.table_id_));
9871
    }
9872
  }
9873
  return ret;
9874
}
9875

9876
// revise info of not null constraints
9877
int ObDDLOperator::revise_not_null_constraint_info(
9878
    obrpc::ObSchemaReviseArg arg,
9879
    share::schema::ObSchemaGetterGuard &schema_guard,
9880
    common::ObMySQLTransaction &trans)
9881
{
9882
  int ret = OB_SUCCESS;
9883
  const uint64_t tenant_id = arg.tenant_id_;
9884
  const uint64_t table_id = arg.table_id_;
9885
  int64_t new_schema_version = OB_INVALID_VERSION;
9886
  ObSchemaService *schema_service = schema_service_.get_schema_service();
9887
  const ObTableSchema *ori_table_schema = NULL;
9888
  ObSEArray<const ObColumnSchemaV2 *, 16> not_null_cols;
9889
  const bool update_object_status_ignore_version = false;
9890
  if (OB_ISNULL(schema_service)) {
9891
    ret = OB_ERR_UNEXPECTED;
9892
    LOG_WARN("schema_service is NULL", K(ret));
9893
  } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, ori_table_schema))) {
9894
    LOG_WARN("get table schema faield", K(ret), K(tenant_id), K(table_id));
9895
  } else if (OB_ISNULL(ori_table_schema)) {
9896
    ret = OB_ERR_UNEXPECTED;
9897
    LOG_WARN("table schema is null", K(ret), K(table_id), K(tenant_id));
9898
  } else {
9899
    bool is_heap_table = ori_table_schema->is_heap_table();
9900
    ObTableSchema::const_column_iterator col_iter = ori_table_schema->column_begin();
9901
    ObTableSchema::const_column_iterator col_iter_end = ori_table_schema->column_end();
9902
    for (; col_iter != col_iter_end && OB_SUCC(ret); col_iter++) {
9903
      if (OB_ISNULL(*col_iter)) {
9904
        ret = OB_ERR_UNEXPECTED;
9905
        LOG_WARN("column schema is null", K(ret), KPC(ori_table_schema));
9906
      } else if (!(*col_iter)->is_nullable() && !(*col_iter)->is_hidden()) {
9907
        if (!is_heap_table && (*col_iter)->is_rowkey_column()) {
9908
          // do nothing for rowkey columns.
9909
          // not filter rowkey column of no_pk_table since it may be partition key and can be null.
9910
        } else if (OB_UNLIKELY((*col_iter)->has_not_null_constraint())) {
9911
          ret = OB_ERR_UNEXPECTED;
9912
          LOG_WARN("column with not null attr should not have not null constraint", K(ret),
9913
                    KPC(*col_iter));
9914
        } else if (OB_FAIL(not_null_cols.push_back(*col_iter))) {
9915
          LOG_WARN("push back failed", K(ret));
9916
        }
9917
      }
9918
    }
9919
  }
9920

9921
  if (OB_FAIL(ret) || 0 == not_null_cols.count()) {
9922
    // do nothing
9923
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(arg.tenant_id_, new_schema_version))) {
9924
    LOG_WARN("fail to gen new schema_version", K(ret), K(arg.tenant_id_));
9925
  } else {
9926
    bool is_oracle_mode = false;
9927
    uint64_t new_cst_id = OB_INVALID_ID;
9928
    if (OB_FAIL(ori_table_schema->check_if_oracle_compat_mode(is_oracle_mode))) {
9929
      LOG_WARN("fail check if oracle mode", K(ret));
9930
    }
9931
    for (int64_t i = 0; OB_SUCC(ret) && i < not_null_cols.count(); ++i) {
9932
      ObArenaAllocator allocator("ReviseNotNulCst");
9933
      ObString cst_name;
9934
      ObString check_expr_str;
9935
      ObConstraint cst;
9936
      const ObColumnSchemaV2 *col_schema = not_null_cols.at(i);
9937
      uint64_t column_id = col_schema->get_column_id();
9938
      bool cst_name_generated = false;
9939
      ObColumnSchemaV2 new_col_schema;
9940
      if (OB_FAIL(ObTableSchema::create_cons_name_automatically_with_dup_check(cst_name,
9941
            ori_table_schema->get_table_name_str(),
9942
            allocator,
9943
            CONSTRAINT_TYPE_NOT_NULL,
9944
            schema_guard,
9945
            tenant_id,
9946
            ori_table_schema->get_database_id(),
9947
            10, /* retry_times */
9948
            cst_name_generated,
9949
            true))) {
9950
        LOG_WARN("create cons name automatically failed", K(ret));
9951
      } else if (OB_UNLIKELY(!cst_name_generated)) {
9952
        ret = OB_ERR_UNEXPECTED;
9953
        LOG_WARN("duplicate name constraint already exists", K(ret), KPC(ori_table_schema));
9954
      } else if (OB_FAIL(ObResolverUtils::create_not_null_expr_str(
9955
                  col_schema->get_column_name_str(), allocator, check_expr_str, is_oracle_mode))) {
9956
        LOG_WARN("create not null expr str failed", K(ret));
9957
      } else if (OB_FAIL(schema_service->fetch_new_constraint_id(tenant_id, new_cst_id))) {
9958
        LOG_WARN("failed to fetch new constraint id", K(ret));
9959
      } else if (OB_FAIL(new_col_schema.assign(*col_schema))) {
9960
        LOG_WARN("fail to assign column schema", KR(ret));
9961
      } else {
9962
        const bool only_history = false;
9963
        const bool need_to_deal_with_cst_cols = true;
9964
        const bool do_cst_revise = true;
9965
        cst.set_tenant_id(tenant_id);
9966
        cst.set_table_id(table_id);
9967
        cst.set_constraint_id(new_cst_id);
9968
        cst.set_schema_version(new_schema_version);
9969
        cst.set_constraint_name(cst_name);
9970
        cst.set_name_generated_type(GENERATED_TYPE_SYSTEM);
9971
        cst.set_check_expr(check_expr_str);
9972
        cst.set_constraint_type(CONSTRAINT_TYPE_NOT_NULL);
9973
        cst.set_rely_flag(false);
9974
        cst.set_enable_flag(true);
9975
        cst.set_validate_flag(CST_FK_VALIDATED);
9976

9977
        new_col_schema.set_schema_version(new_schema_version);
9978
        new_col_schema.add_not_null_cst();
9979
        new_col_schema.set_nullable(true);
9980
        if (OB_FAIL(cst.assign_not_null_cst_column_id(column_id))) {
9981
          LOG_WARN("assign not null constraint column id failed", K(ret));
9982
        } else if (OB_FAIL(schema_service->get_table_sql_service().add_single_constraint(
9983
                  trans, cst, only_history,need_to_deal_with_cst_cols, do_cst_revise))) {
9984
          LOG_WARN("add single constraint failed", K(ret), K(cst));
9985
        } else if (OB_FAIL(schema_service->get_table_sql_service().update_single_column(
9986
          trans, *ori_table_schema, *ori_table_schema, new_col_schema, false))) {
9987
          LOG_WARN("update single column failed", K(ret));
9988
        }
9989
      }
9990
    }
9991
    if (OB_SUCC(ret)) {
9992
      ObTableSchema new_table_schema;
9993
      if (OB_FAIL(new_table_schema.assign(*ori_table_schema))) {
9994
        LOG_WARN("assign table schema failed", K(ret));
9995
      } else {
9996
        new_table_schema.set_schema_version(new_schema_version);
9997
        if (OB_FAIL(schema_service->get_table_sql_service().update_table_attribute(
9998
            trans, new_table_schema, OB_DDL_ADD_CONSTRAINT, update_object_status_ignore_version))) {
9999
          LOG_WARN("update table attribute faield", K(ret));
10000
        }
10001
      }
10002
    }
10003
  }
10004
  LOG_INFO("revise not null constraint info", K(ret), K(arg));
10005
  return ret;
10006
}
10007

10008
int ObDDLOperator::create_keystore(ObKeystoreSchema &keystore_schema,
10009
    common::ObMySQLTransaction &trans,
10010
    share::schema::ObSchemaGetterGuard &schema_guard,
10011
    const common::ObString *ddl_stmt_str)
10012
{
10013
  int ret = OB_SUCCESS;
10014
  UNUSED(schema_guard);
10015
  uint64_t new_ts_id = OB_INVALID_ID;
10016
  const uint64_t tenant_id = keystore_schema.get_tenant_id();
10017
  ObSchemaService *schema_service = schema_service_.get_schema_service();
10018
  int64_t new_schema_version = OB_INVALID_VERSION;
10019
  if (OB_ISNULL(schema_service)) {
10020
    ret = OB_ERR_UNEXPECTED;
10021
    LOG_WARN("get invalid schema service", K(ret));
10022
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10023
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
10024
  } else {
10025
    keystore_schema.set_schema_version(new_schema_version);
10026
  }
10027
  if (OB_FAIL(ret)) {
10028
   /*do nothing*/
10029
  } else if (is_mysql_inner_keystore_id(keystore_schema.get_keystore_id())) {
10030
    /* If the id is equal to the internal keystore id, no fetch is required */
10031
  } else if (OB_FAIL(schema_service->fetch_new_keystore_id(
10032
      keystore_schema.get_tenant_id(), new_ts_id))) {
10033
    LOG_WARN("failed to fetch_new_table_id", K(ret));
10034
  } else if (OB_INVALID_ID == new_ts_id) {
10035
    ret = OB_ERR_UNEXPECTED;
10036
    LOG_WARN("get invalid schema id", K(ret));
10037
  } else if (FALSE_IT(keystore_schema.set_keystore_id(new_ts_id))) {
10038
  }
10039

10040
  if (OB_SUCC(ret)) {
10041
    if (OB_FAIL(schema_service->get_keystore_sql_service().create_keystore(
10042
        keystore_schema, trans, ddl_stmt_str))) {
10043
      LOG_WARN("create keystore failed", K(ret));
10044
    }
10045
  }
10046

10047
  return ret;
10048
}
10049

10050
int ObDDLOperator::alter_keystore(ObKeystoreSchema &keystore_schema,
10051
    common::ObMySQLTransaction &trans,
10052
    share::schema::ObSchemaGetterGuard &schema_guard,
10053
    const common::ObString *ddl_stmt_str,
10054
    bool &is_set_key,
10055
    bool is_kms)
10056
{
10057
  int ret = OB_SUCCESS;
10058
  uint64_t new_ms_id = OB_INVALID_ID;
10059
  ObSchemaService *schema_service = schema_service_.get_schema_service();
10060
  const uint64_t tenant_id = keystore_schema.get_tenant_id();
10061
  int64_t new_schema_version = OB_INVALID_VERSION;
10062
  if (OB_ISNULL(schema_service)) {
10063
    ret = OB_ERR_UNEXPECTED;
10064
    LOG_WARN("get invalid schema service", K(ret));
10065
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10066
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
10067
  } else {
10068
    keystore_schema.set_schema_version(new_schema_version);
10069
  }
10070
  if (OB_FAIL(ret)) {
10071
    /*do nothing*/
10072
  } else if (is_set_key && !is_kms) {
10073
    if (OB_FAIL(schema_service->fetch_new_master_key_id(
10074
        keystore_schema.get_tenant_id(), new_ms_id))) {
10075
      LOG_WARN("failed to fetch_new_master_id", K(ret));
10076
    } else if (OB_INVALID_ID == new_ms_id) {
10077
      ret = OB_ERR_UNEXPECTED;
10078
      LOG_WARN("get invalid master id", K(ret));
10079
    } else if (FALSE_IT(keystore_schema.set_master_key_id(new_ms_id))) {
10080
    }
10081
  }
10082

10083
  if (OB_FAIL(ret)) {
10084
    /*do nothing*/
10085
  } else if(OB_FAIL(schema_service->get_keystore_sql_service().alter_keystore(
10086
      keystore_schema, trans, ddl_stmt_str))) {
10087
    LOG_WARN("alter keystore failed", K(ret));
10088
  } else {
10089
    // The keystore state changes, the table_schema version needs to be pushed up.
10090
    common::ObArray<const share::schema::ObSimpleTableSchemaV2 *> table_schemas;
10091
    if (OB_FAIL(schema_guard.get_table_schemas_in_tenant(tenant_id, table_schemas))) {
10092
      LOG_WARN("fail to get table schemas in tenant", K(ret));
10093
    }
10094
    common::ObArray<const share::schema::ObSimpleTableSchemaV2 *> need_encrypt_table_schemas;
10095
    for (int i = 0; i < table_schemas.count() && OB_SUCC(ret); ++i) {
10096
      if (table_schemas.at(i)->need_encrypt()) {
10097
        ret = need_encrypt_table_schemas.push_back(table_schemas.at(i));
10098
      }
10099
    }
10100
    for (int i = 0; i < need_encrypt_table_schemas.count() && OB_SUCC(ret); ++i) {
10101
      const ObSimpleTableSchemaV2 *table_schema = need_encrypt_table_schemas.at(i);
10102
      if (OB_FAIL(schema_service->get_table_sql_service().update_data_table_schema_version(trans,
10103
          tenant_id, table_schema->get_table_id(), table_schema->get_in_offline_ddl_white_list()))) {
10104
        LOG_WARN("fail to update data table schema version", K(ret), "id", table_schema->get_table_id());
10105
      }
10106
    }
10107
  }
10108
  return ret;
10109
}
10110

10111
int ObDDLOperator::handle_label_se_policy_function(ObSchemaOperationType ddl_type,
10112
                                                   const ObString &ddl_stmt_str,
10113
                                                   ObSchemaGetterGuard &schema_guard,
10114
                                                   ObLabelSePolicySchema &schema,
10115
                                                   ObMySQLTransaction &trans)
10116
{
10117
  int ret = OB_SUCCESS;
10118
  uint64_t tenant_id = schema.get_tenant_id();
10119
  ObSchemaService *schema_sql_service = NULL;
10120

10121
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10122
    ret = OB_ERR_SYS;
10123
    LOG_ERROR("schema_sql_service must not null", K(ret));
10124
  }
10125

10126
  if (OB_SUCC(ret)) {
10127
    int64_t new_schema_version = OB_INVALID_VERSION;
10128

10129
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10130
      LOG_WARN("fail to gen new schema_version", K(ret));
10131
    } else {
10132
      schema.set_schema_version(new_schema_version);
10133
    }
10134
  }
10135

10136
  if (OB_SUCC(ret)) {
10137
    bool is_policy_name_exist = false;
10138
    bool is_column_name_exist = false;
10139
    const ObLabelSePolicySchema *old_schema = NULL;
10140
    const ObLabelSePolicySchema *temp_schema = NULL;
10141

10142
    //check if the schema is already existed
10143
    if (OB_SUCC(ret)) {
10144
      if (OB_FAIL(schema_guard.get_label_se_policy_schema_by_name(
10145
                    tenant_id, schema.get_policy_name_str(), old_schema))) {
10146
        LOG_WARN("fail to check schema exist", K(ret));
10147
      } else if (FALSE_IT(is_policy_name_exist = OB_NOT_NULL(old_schema))) {
10148
      } else if (!schema.get_column_name_str().empty()
10149
                 && OB_FAIL(schema_guard.get_label_se_policy_schema_by_column_name(
10150
                              tenant_id, schema.get_column_name_str(), temp_schema))) {
10151
        LOG_WARN("fail to check schema exist", K(ret));
10152
      } else if (FALSE_IT(is_column_name_exist = OB_NOT_NULL(temp_schema))) {
10153
      }
10154
    }
10155

10156
    //other stuff case by case
10157
    if (OB_SUCC(ret)) {
10158
      uint64_t label_se_policy_id = OB_INVALID_ID;
10159

10160
      switch (ddl_type) {
10161
      case OB_DDL_CREATE_LABEL_SE_POLICY:
10162
        if (OB_UNLIKELY(is_policy_name_exist | is_column_name_exist)) {
10163
          ret = is_policy_name_exist ? OB_OBJECT_NAME_EXIST : OB_ERR_COLUMN_DUPLICATE;
10164
          LOG_WARN("policy already existed", K(ret), K(tenant_id));
10165
        } else if (OB_FAIL(schema_sql_service->fetch_new_label_se_policy_id(tenant_id, label_se_policy_id))) {
10166
          LOG_WARN("fail to fetch new label se policy id", K(tenant_id), K(ret));
10167
        } else {
10168
          schema.set_label_se_policy_id(label_se_policy_id);
10169
        }
10170
        break;
10171
      case OB_DDL_ALTER_LABEL_SE_POLICY:
10172
      case OB_DDL_DROP_LABEL_SE_POLICY:
10173
        if (OB_UNLIKELY(!is_policy_name_exist)) {
10174
          ret = OB_OBJECT_NAME_NOT_EXIST;
10175
          LOG_WARN("policy not existed", K(ret), K(tenant_id));
10176
        } else {
10177
          schema.set_label_se_policy_id(old_schema->get_label_se_policy_id());
10178
          schema.set_column_name(old_schema->get_column_name_str());
10179
          if (schema.get_default_options() < 0) {
10180
            schema.set_default_options(old_schema->get_default_options());
10181
          }
10182
          if (schema.get_flag() < 0) {
10183
            schema.set_flag(old_schema->get_flag());
10184
          }
10185
        }
10186
        break;
10187
      default:
10188
        ret = OB_ERR_UNEXPECTED;
10189
        LOG_WARN("unknown ddl type", K(ret), K(ddl_type));
10190
      }
10191
    }
10192
  }
10193

10194
  if (OB_SUCC(ret)) {
10195
    if (OB_FAIL(schema_sql_service->get_label_se_policy_sql_service()
10196
                       .apply_new_schema(schema, trans, ddl_type, ddl_stmt_str))) {
10197
      LOG_WARN("create policy info failed", K(ret));
10198
    }
10199
  }
10200

10201
  LOG_DEBUG("ddl operator create plan label security policy", K(schema));
10202
  return ret;
10203
}
10204

10205
int ObDDLOperator::handle_label_se_component_function(ObSchemaOperationType ddl_type,
10206
                                                      const ObString &ddl_stmt_str,
10207
                                                      const ObString &policy_name,
10208
                                                      ObSchemaGetterGuard &schema_guard,
10209
                                                      ObLabelSeComponentSchema &schema,
10210
                                                      ObMySQLTransaction &trans)
10211
{
10212
  int ret = OB_SUCCESS;
10213
  uint64_t tenant_id = schema.get_tenant_id();
10214
  ObSchemaService *schema_sql_service = NULL;
10215

10216
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10217
    ret = OB_ERR_SYS;
10218
    LOG_ERROR("schema_sql_service must not null", K(ret));
10219
  }
10220

10221
  if (OB_SUCC(ret)) {
10222
    int64_t new_schema_version = OB_INVALID_VERSION;
10223

10224
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10225
      LOG_WARN("fail to gen new schema_version", K(ret));
10226
    } else {
10227
      schema.set_schema_version(new_schema_version);
10228
    }
10229
  }
10230

10231
  if (OB_SUCC(ret)) {
10232

10233
    //check and get policy id of the policy_name
10234
    uint64_t policy_id = OB_INVALID_ID;
10235
    if (OB_SUCC(ret)) {
10236
      const ObLabelSePolicySchema *policy_schema = NULL;
10237
      if (OB_FAIL(schema_guard.get_label_se_policy_schema_by_name(tenant_id,
10238
                                                                  policy_name,
10239
                                                                  policy_schema))) {
10240
        LOG_WARN("fail to check schema exist", K(ret));
10241
      } else if (OB_ISNULL(policy_schema)) {
10242
        ret = OB_ERR_POLICY_STRING_NOT_FOUND;
10243
        LOG_WARN("the schema exists, but the schema pointer is NULL", K(ret));
10244
      } else {
10245
        policy_id = policy_schema->get_label_se_policy_id();
10246
      }
10247
    }
10248

10249
    bool is_schema_exist = false;
10250
    const ObLabelSeComponentSchema *old_schema = NULL;
10251
    if (OB_SUCC(ret)) {
10252
      if (OB_FAIL(schema_guard.get_label_se_component_schema_by_comp_num(tenant_id,
10253
                                                                         policy_id,
10254
                                                                         schema.get_comp_type(),
10255
                                                                         schema.get_comp_num(),
10256
                                                                         old_schema))) {
10257
        LOG_WARN("fail to check schema exist", K(ret));
10258
      } else {
10259
        is_schema_exist = (old_schema != NULL);
10260
      }
10261
    }
10262

10263
    //check short name unique
10264
    if (OB_SUCC(ret) && !schema.get_short_name_str().empty()
10265
        && (!is_schema_exist || old_schema->get_short_name_str() != schema.get_short_name_str())) {
10266
      bool is_exist = false;
10267
      if (OB_FAIL(schema_service_.check_label_se_component_short_name_exist(tenant_id,
10268
                                                                            policy_id,
10269
                                                                            schema.get_comp_type(),
10270
                                                                            schema.get_short_name_str(),
10271
                                                                            is_exist))) {
10272
        LOG_WARN("check component short name failed", K(ret));
10273
      } else if (is_exist) {
10274
        ret = OB_OBJECT_NAME_EXIST; //TODO [label]
10275
      }
10276
    }
10277
    //check the long name unique
10278
    if (OB_SUCC(ret) && !schema.get_long_name_str().empty()
10279
        && (!is_schema_exist || old_schema->get_long_name_str() != schema.get_long_name_str())) {
10280
      bool is_exist = false;
10281
      if (OB_FAIL(schema_service_.check_label_se_component_long_name_exist(tenant_id,
10282
                                                                           policy_id,
10283
                                                                           schema.get_comp_type(),
10284
                                                                           schema.get_long_name_str(),
10285
                                                                           is_exist))) {
10286
        LOG_WARN("check component long name failed", K(ret));
10287
      } else if (is_exist) {
10288
        ret = OB_OBJECT_NAME_EXIST; //TODO [label]
10289
      }
10290
    }
10291

10292
    //other stuff case by case
10293
    if (OB_SUCC(ret)) {
10294
      uint64_t label_se_component_id = OB_INVALID_ID;
10295

10296
      schema.set_label_se_policy_id(policy_id);
10297

10298
      switch (ddl_type) {
10299
      case OB_DDL_CREATE_LABEL_SE_LEVEL:
10300
        if (OB_UNLIKELY(is_schema_exist)) {
10301
          ret = OB_OBJECT_NAME_EXIST;
10302
          LOG_WARN("level already existed", K(ret), K(tenant_id));
10303
        } else if (OB_FAIL(schema_sql_service->fetch_new_label_se_component_id(tenant_id, label_se_component_id))) {
10304
          LOG_WARN("fail to fetch new label se policy id", K(tenant_id), K(ret));
10305
        } else {
10306
          schema.set_label_se_component_id(label_se_component_id);
10307
        }
10308
        break;
10309
      case OB_DDL_ALTER_LABEL_SE_LEVEL:
10310
      case OB_DDL_DROP_LABEL_SE_LEVEL:
10311
        if (OB_UNLIKELY(!is_schema_exist)) {
10312
          ret = OB_OBJECT_NAME_NOT_EXIST;
10313
          LOG_WARN("level not exist", K(ret), K(schema));
10314
        } else {
10315
          schema.set_label_se_component_id(old_schema->get_label_se_component_id());
10316
          if (schema.get_short_name_str().empty()) {
10317
            schema.set_short_name(old_schema->get_short_name_str());
10318
          }
10319
          if (schema.get_long_name_str().empty()) {
10320
            schema.set_long_name(old_schema->get_long_name_str());
10321
          }
10322
          if (schema.get_parent_name_str().empty()) {
10323
            schema.set_parent_name(old_schema->get_parent_name_str());
10324
          }
10325
        }
10326
        break;
10327
      default:
10328
        ret = OB_ERR_UNEXPECTED;
10329
        LOG_WARN("unknown ddl type", K(ret), K(ddl_type));
10330
      }
10331
    }
10332

10333
    // When deleting component, it need to check whether the component is used in the label
10334
    if (OB_SUCC(ret) && OB_DDL_DROP_LABEL_SE_LEVEL == ddl_type) {
10335
      ObSEArray<const ObLabelSeLabelSchema *, 4> label_schemas;
10336
      if (OB_FAIL(schema_guard.get_label_se_label_infos_in_tenant(tenant_id, label_schemas))) {
10337
        LOG_WARN("fail to get label se schemas", K(ret));
10338
      }
10339

10340
      const ObLabelSeLabelSchema *label_schema = NULL;
10341
      ObLabelSeDecomposedLabel label_comps;
10342
      ObLabelSeLabelCompNums label_nums;
10343

10344
      for (int64_t i = 0; OB_SUCC(ret) && i < label_schemas.count(); ++i) {
10345
        label_comps.reset();
10346
        if (OB_ISNULL(label_schema = label_schemas[i])) {
10347
          ret = OB_ERR_UNEXPECTED;
10348
          LOG_WARN("label schema is NULL", K(ret));
10349
        } else if (OB_FAIL(ObLabelSeResolver::resolve_label_text(label_schema->get_label_str(),
10350
                                                                 label_comps))) {
10351
          LOG_WARN("fail to resolve label text", K(ret));
10352
        } else if (OB_FAIL(ObLabelSeUtil::convert_label_comps_name_to_num(tenant_id,
10353
                                                                          policy_id,
10354
                                                                          schema_guard,
10355
                                                                          label_comps,
10356
                                                                          label_nums))) {
10357
          LOG_WARN("fail to convert comp names to num", K(ret));
10358
        } else if (label_nums.level_num_ == schema.get_comp_num()) {
10359
          ret = OB_ERR_LBAC_ERROR;
10360
          LOG_USER_ERROR(OB_ERR_LBAC_ERROR, "level in use by existing labels");
10361
        }
10362
      }
10363
    }
10364
  }
10365

10366
  if (OB_SUCC(ret)) {
10367
    if (OB_FAIL(schema_sql_service->get_label_se_policy_sql_service()
10368
                       .apply_new_schema(schema, trans, ddl_type, ddl_stmt_str))) {
10369
      LOG_WARN("create policy info failed", K(ret));
10370
    }
10371
  }
10372
  LOG_DEBUG("ddl operator create plan label security policy", K(schema));
10373
  return ret;
10374
}
10375

10376

10377
int ObDDLOperator::handle_label_se_label_function(ObSchemaOperationType ddl_type,
10378
                                                  const ObString &ddl_stmt_str,
10379
                                                  const ObString &policy_name,
10380
                                                  ObSchemaGetterGuard &schema_guard,
10381
                                                  ObLabelSeLabelSchema &schema,
10382
                                                  ObMySQLTransaction &trans)
10383
{
10384
  int ret = OB_SUCCESS;
10385
  uint64_t tenant_id = schema.get_tenant_id();
10386
  ObSchemaService *schema_sql_service = NULL;
10387

10388
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10389
    ret = OB_ERR_SYS;
10390
    LOG_ERROR("schema_sql_service must not null", K(ret));
10391
  }
10392

10393
  if (OB_SUCC(ret)) {
10394
    int64_t new_schema_version = OB_INVALID_VERSION;
10395

10396
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10397
      LOG_WARN("fail to gen new schema_version", K(ret));
10398
    } else {
10399
      schema.set_schema_version(new_schema_version);
10400
    }
10401
  }
10402

10403
  if (OB_SUCC(ret)) {
10404
    //check and get policy id of the policy_name
10405
    uint64_t policy_id = OB_INVALID_ID;
10406
    if (OB_SUCC(ret)) {
10407
      const ObLabelSePolicySchema *policy_schema = NULL;
10408
      if (OB_FAIL(schema_guard.get_label_se_policy_schema_by_name(tenant_id,
10409
                                                                  policy_name,
10410
                                                                  policy_schema))) {
10411
        LOG_WARN("fail to check schema exist", K(ret));
10412
      } else if (OB_ISNULL(policy_schema)) {
10413
        ret = OB_ERR_POLICY_STRING_NOT_FOUND;
10414
        LOG_WARN("the schema exists, but the schema pointer is NULL", K(ret));
10415
      } else {
10416
        policy_id = policy_schema->get_label_se_policy_id();
10417
      }
10418
    }
10419

10420
    //check label schema secondly
10421
    const ObLabelSeLabelSchema *old_schema = NULL;
10422
    const ObLabelSeLabelSchema *temp_schema = NULL;
10423
    bool is_label_tag_exist = false;
10424
    bool is_label_name_exist = false;
10425
    if (OB_SUCC(ret)) {
10426
      if (OB_FAIL(schema_guard.get_label_se_label_by_label_tag(tenant_id,
10427
                                                               schema.get_label_tag(),
10428
                                                               old_schema))) {
10429
        LOG_WARN("fail to check schema exist", K(ret));
10430
      } else if (FALSE_IT(is_label_tag_exist = OB_NOT_NULL(old_schema))) {
10431
      } else if (!schema.get_label_str().empty()
10432
                 && OB_FAIL(schema_guard.get_label_se_label_schema_by_name(tenant_id,
10433
                                                                  schema.get_label_str(),
10434
                                                                  temp_schema))) {
10435
        LOG_WARN("fail to check schema exist", K(ret));
10436
      } else if (FALSE_IT(is_label_name_exist = OB_NOT_NULL(temp_schema))) {
10437
      }
10438
    }
10439

10440
    //other stuff case by case
10441
    if (OB_SUCC(ret)) {
10442
      uint64_t label_se_label_id = OB_INVALID_ID;
10443

10444
      schema.set_label_se_policy_id(policy_id);
10445

10446
      switch (ddl_type) {
10447
      case OB_DDL_CREATE_LABEL_SE_LABEL:
10448
        if (OB_UNLIKELY(is_label_tag_exist | is_label_name_exist)) {
10449
          ret = OB_OBJECT_NAME_EXIST;
10450
          LOG_WARN("policy already existed", K(ret), K(schema));
10451
        } else if (OB_FAIL(schema_sql_service->fetch_new_label_se_label_id(tenant_id, label_se_label_id))) {
10452
          LOG_WARN("fail to fetch new label se policy id", K(schema), K(ret));
10453
        } else {
10454
          schema.set_label_se_label_id(label_se_label_id);
10455
        }
10456
        break;
10457
      case OB_DDL_ALTER_LABEL_SE_LABEL:
10458
      case OB_DDL_DROP_LABEL_SE_LABEL:
10459
        if (OB_UNLIKELY(!is_label_tag_exist)) {
10460
          ret = OB_OBJECT_NAME_NOT_EXIST;
10461
          LOG_WARN("policy not existed", K(ret), K(schema));
10462
        } else {
10463
          schema.set_label_se_label_id(old_schema->get_label_se_label_id());
10464
          if (schema.get_label_str().empty()) {
10465
            schema.set_label(old_schema->get_label());
10466
          } else if (old_schema->get_label_str() == schema.get_label_str()) {
10467
            //do nothing
10468
          } else if (OB_UNLIKELY(is_label_name_exist)) {
10469
            ret = OB_OBJECT_NAME_EXIST;
10470
            LOG_WARN("policy existed", K(ret), K(schema));
10471
          }
10472
          if (schema.get_flag() < 0) {
10473
            schema.set_flag(old_schema->get_flag());
10474
          } else {
10475
            if (ddl_type == OB_DDL_ALTER_LABEL_SE_LABEL
10476
                && old_schema->get_flag() != 0 && schema.get_flag() == 0) {
10477
              ret = OB_ERR_LBAC_ERROR;
10478
              LOG_USER_ERROR(OB_ERR_LBAC_ERROR, "cannot change data label to user label");
10479
            }
10480
          }
10481
        }
10482
        break;
10483
      default:
10484
        ret = OB_ERR_UNEXPECTED;
10485
        LOG_WARN("unknown ddl type", K(ret), K(ddl_type));
10486
      }
10487
    }
10488
  }
10489

10490
  if (OB_SUCC(ret)) {
10491
    if (OB_FAIL(schema_sql_service->get_label_se_policy_sql_service()
10492
                       .apply_new_schema(schema, trans, ddl_type, ddl_stmt_str))) {
10493
      LOG_WARN("create policy info failed", K(ret));
10494
    }
10495
  }
10496

10497
  LOG_DEBUG("ddl operator handle label schema", K(schema));
10498
  return ret;
10499
}
10500

10501
int ObDDLOperator::drop_all_label_se_table_column(uint64_t tenant_id,
10502
                                                  uint64_t policy_id,
10503
                                                  ObMySQLTransaction &trans,
10504
                                                  ObSchemaGetterGuard &schema_guard)
10505
{
10506
  int ret = OB_SUCCESS;
10507
  ObSEArray<const ObTableSchema *, 32> tables;
10508
  const ObLabelSePolicySchema *policy = NULL;
10509
  ObString policy_column_name;
10510
  ObSchemaService *schema_service = NULL;
10511

10512
  if (OB_ISNULL(schema_service = schema_service_.get_schema_service())) {
10513
    ret = OB_ERR_UNEXPECTED;
10514
    LOG_WARN("schema service is null", K(ret));
10515
  } else if (OB_FAIL(schema_guard.get_table_schemas_in_tenant(tenant_id, tables))) {
10516
    LOG_WARN("fail to get all table schemas", K(ret));
10517
  } else if (OB_FAIL(schema_guard.get_label_se_policy_schema_by_id(tenant_id, policy_id, policy))) {
10518
    LOG_WARN("fail to get policy schema", K(ret));
10519
  } else if (OB_ISNULL(policy)) {
10520
    ret = OB_ERR_UNEXPECTED;
10521
    LOG_WARN("fail to get policy schema", K(ret));
10522
  } else {
10523
    policy_column_name = policy->get_column_name_str();
10524
  }
10525
  for (int64_t t_i = 0; OB_SUCC(ret) && t_i < tables.count(); ++t_i) {
10526
    const ObTableSchema *table = NULL;
10527
    ObTableSchema new_table_schema;
10528
    if (OB_ISNULL(table = tables.at(t_i))) {
10529
      ret = OB_ERR_UNEXPECTED;
10530
      LOG_WARN("table is NULL", K(ret));
10531
    } else if (OB_FAIL(new_table_schema.assign(*table))) {
10532
      LOG_WARN("fail to assign table schema", K(ret));
10533
    }
10534
    for (int64_t c_j = 0; OB_SUCC(ret) && c_j < table->get_label_se_column_ids().count(); ++c_j) {
10535
      const ObColumnSchemaV2 *column = NULL;
10536
      column = schema_guard.get_column_schema(table->get_tenant_id(),
10537
                                              table->get_table_id(),
10538
                                              table->get_label_se_column_ids().at(c_j));
10539
      if (OB_ISNULL(column)) {
10540
        ret = OB_ERR_UNEXPECTED;
10541
        LOG_WARN("fail to get column schema", K(ret));
10542
      } else if (0 == column->get_column_name_str().compare(policy_column_name)) {
10543
        ret = OB_NOT_SUPPORTED;
10544
        LOG_WARN("drop policy with table column", K(ret), K(table->get_table_name_str()));
10545
        LOG_USER_ERROR(OB_NOT_SUPPORTED, "drop policy with table column");
10546
        /*
10547
        int64_t new_schema_version = OB_INVALID_SCHEMA_VERSION;
10548
        if (table->is_index_table()) {
10549
          ret = OB_ERR_ALTER_INDEX_COLUMN;
10550
          LOG_WARN("can't not drop index column", K(ret));
10551
        } else if (OB_FAIL(update_prev_id_for_delete_column(*table, new_table_schema, *column, trans))) {
10552
          LOG_WARN("fail to update prev id for delete column", K(ret));
10553
        } else if (OB_FAIL(new_table_schema.delete_column(column->get_column_name_str()))) {
10554
          LOG_WARN("fail to delete column", K(ret));
10555
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10556
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
10557
        } else if (OB_FAIL(schema_service->get_table_sql_service().delete_single_column(
10558
                             new_schema_version, trans, *table, *column))) {
10559
          LOG_WARN("fail to delete column", K(ret));
10560
        } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10561
          LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
10562
        } else if (OB_FAIL(schema_service->get_table_sql_service()
10563
                           .sync_aux_schema_version_for_history(
10564
                             trans, *table, new_schema_version ))) {
10565
          LOG_WARN("fail to sync aux schema version column", K(ret));
10566
        }
10567
        */
10568
      }
10569
    }
10570
  }
10571
  return ret;
10572
}
10573

10574
int ObDDLOperator::drop_all_label_se_labels_in_policy(uint64_t tenant_id,
10575
                                                      uint64_t policy_id,
10576
                                                      ObMySQLTransaction &trans,
10577
                                                      const ObString &ddl_stmt_str,
10578
                                                      ObSchemaGetterGuard &schema_guard)
10579
{
10580
  int ret = OB_SUCCESS;
10581

10582
  ObSchemaService *schema_sql_service = NULL;
10583

10584
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10585
    ret = OB_ERR_SYS;
10586
    LOG_ERROR("schema_sql_service must not null", K(ret));
10587
  }
10588

10589
  ObSEArray<const ObLabelSeLabelSchema*, 16> labels;
10590
  if (OB_SUCC(ret)) {
10591
    if (OB_FAIL(schema_guard.get_label_se_label_infos_in_tenant(tenant_id, labels))) {
10592
      LOG_WARN("fail to get user level infos in tenant", K(ret), K(tenant_id));
10593
    }
10594
  }
10595

10596
  const ObLabelSeLabelSchema *label_schema = NULL;
10597
  int64_t new_schema_version = OB_INVALID_VERSION;
10598

10599
  for (int64_t i = 0; OB_SUCC(ret) && i < labels.count(); ++i) {
10600

10601
    if (OB_ISNULL(label_schema = labels.at(i))) {
10602
      ret = OB_ERR_UNEXPECTED;
10603
      LOG_WARN("schema is NULL", K(ret));
10604
    }
10605

10606
    if (OB_SUCC(ret) && label_schema->get_label_se_policy_id() == policy_id) {
10607
      ObLabelSeLabelSchema schema;
10608
      if (OB_FAIL(schema.assign(*label_schema))) {
10609
        LOG_WARN("fail to assign label schema", KR(ret));
10610
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10611
        LOG_WARN("fail to gen new schema_version", K(ret));
10612
      } else {
10613
        schema.set_schema_version(new_schema_version);
10614
      }
10615
      if (OB_SUCC(ret)) {
10616
        if (OB_FAIL(schema_sql_service->get_label_se_policy_sql_service()
10617
                           .apply_new_schema(schema, trans, OB_DDL_DROP_LABEL_SE_LABEL, ddl_stmt_str))) {
10618
          LOG_WARN("apply schema failed", K(ret));
10619
        }
10620
      }
10621
    }
10622

10623
  }
10624

10625
  return ret;
10626
}
10627

10628
int ObDDLOperator::drop_all_label_se_components_in_policy(uint64_t tenant_id,
10629
                                                          uint64_t policy_id,
10630
                                                          ObMySQLTransaction &trans,
10631
                                                          const ObString &ddl_stmt_str,
10632
                                                          ObSchemaGetterGuard &schema_guard)
10633
{
10634
  int ret = OB_SUCCESS;
10635

10636
  ObSchemaService *schema_sql_service = NULL;
10637

10638
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10639
    ret = OB_ERR_SYS;
10640
    LOG_ERROR("schema_sql_service must not null", K(ret));
10641
  }
10642

10643
  ObSEArray<const ObLabelSeComponentSchema*, 16> components;
10644
  if (OB_SUCC(ret)) {
10645
    if (OB_FAIL(schema_guard.get_label_se_component_infos_in_tenant(tenant_id, components))) {
10646
      LOG_WARN("fail to get user level infos in tenant", K(ret), K(tenant_id));
10647
    }
10648
  }
10649

10650
  const ObLabelSeComponentSchema *component_schema = NULL;
10651
  int64_t new_schema_version = OB_INVALID_VERSION;
10652

10653
  for (int64_t i = 0; OB_SUCC(ret) && i < components.count(); ++i) {
10654

10655
    if (OB_ISNULL(component_schema = components.at(i))) {
10656
      ret = OB_ERR_UNEXPECTED;
10657
      LOG_WARN("schema is NULL", K(ret));
10658
    }
10659

10660
    if (OB_SUCC(ret) && component_schema->get_label_se_policy_id() == policy_id) {
10661
      ObLabelSeComponentSchema schema;
10662
      ObSchemaOperationType ddl_type = OB_INVALID_DDL_OP;
10663
      if (OB_FAIL(schema.assign(*component_schema))) {
10664
        LOG_WARN("fail to assign component_schema", KR(ret));
10665
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10666
        LOG_WARN("fail to gen new schema_version", K(ret));
10667
      } else {
10668
        schema.set_schema_version(new_schema_version);
10669
      }
10670

10671
      if (OB_SUCC(ret)) {
10672
        switch (component_schema->get_comp_type()) {
10673
        case static_cast<int64_t>(ObLabelSeComponentSchema::CompType::LEVEL):
10674
          ddl_type = OB_DDL_DROP_LABEL_SE_LEVEL;
10675
          break;
10676
        default:
10677
          ret = OB_NOT_SUPPORTED;
10678
          LOG_WARN("compartment and group not supported", K(ret), K(component_schema->get_comp_type()));
10679
        }
10680
      }
10681

10682
      if (OB_SUCC(ret)) {
10683
        if (OB_FAIL(schema_sql_service->get_label_se_policy_sql_service()
10684
                           .apply_new_schema(schema, trans, ddl_type, ddl_stmt_str))) {
10685
          LOG_WARN("apply schema failed", K(ret));
10686
        }
10687
      }
10688
    }
10689
  }
10690
  return ret;
10691
}
10692

10693
int ObDDLOperator::drop_all_label_se_user_components(uint64_t tenant_id,
10694
                                                     uint64_t user_id,
10695
                                                     uint64_t policy_id,
10696
                                                     ObMySQLTransaction &trans,
10697
                                                     const ObString &ddl_stmt_str,
10698
                                                     ObSchemaGetterGuard &schema_guard)
10699
{
10700
  int ret = OB_SUCCESS;
10701

10702
  ObSchemaService *schema_sql_service = NULL;
10703

10704
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10705
    ret = OB_ERR_SYS;
10706
    LOG_ERROR("schema_sql_service must not null", K(ret));
10707
  }
10708

10709
  ObSEArray<const ObLabelSeUserLevelSchema*, 4> user_levels;
10710
  if (OB_SUCC(ret)) {
10711
    if (OB_FAIL(schema_guard.get_label_se_user_level_infos_in_tenant(tenant_id, user_levels))) {
10712
      LOG_WARN("fail to get user level infos in tenant", K(ret), K(tenant_id));
10713
    }
10714
  }
10715

10716
  const ObLabelSeUserLevelSchema *user_level_schema = NULL;
10717
  int64_t new_schema_version = OB_INVALID_VERSION;
10718

10719
  for (int64_t i = 0; OB_SUCC(ret) && i < user_levels.count(); ++i) {
10720

10721
    if (OB_ISNULL(user_level_schema = user_levels.at(i))) {
10722
      ret = OB_ERR_UNEXPECTED;
10723
      LOG_WARN("schema is NULL", K(ret));
10724
    }
10725

10726
    if (OB_SUCC(ret) && (user_level_schema->get_user_id() == user_id
10727
                         || user_level_schema->get_label_se_policy_id() == policy_id)) {
10728
      ObLabelSeUserLevelSchema schema;
10729
      if (OB_FAIL(schema.assign(*user_level_schema))) {
10730
        LOG_WARN("fail to assign ObLabelSeUserLevelSchema", KR(ret));
10731
      } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10732
        LOG_WARN("fail to gen new schema_version", K(ret));
10733
      } else {
10734
        schema.set_schema_version(new_schema_version);
10735
      }
10736

10737
      if (OB_SUCC(ret)) {
10738
        if (OB_FAIL(schema_sql_service->get_label_se_policy_sql_service()
10739
                           .apply_new_schema(schema, trans, OB_DDL_DROP_LABEL_SE_USER_LEVELS, ddl_stmt_str))) {
10740
          LOG_WARN("apply schema failed", K(ret));
10741
        }
10742
      }
10743
    }
10744
  }
10745
  return ret;
10746
}
10747

10748
int ObDDLOperator::handle_label_se_user_level_function(ObSchemaOperationType ddl_type,
10749
                                                       const ObString &ddl_stmt_str,
10750
                                                       const ObString &policy_name,
10751
                                                       ObSchemaGetterGuard &schema_guard,
10752
                                                       ObLabelSeUserLevelSchema &schema,
10753
                                                       ObMySQLTransaction &trans)
10754
{
10755
  int ret = OB_SUCCESS;
10756
  uint64_t tenant_id = schema.get_tenant_id();
10757
  ObSchemaService *schema_sql_service = NULL;
10758

10759
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10760
    ret = OB_ERR_SYS;
10761
    LOG_ERROR("schema_sql_service must not null", K(ret));
10762
  }
10763

10764
  if (OB_SUCC(ret)) {
10765
    int64_t new_schema_version = OB_INVALID_VERSION;
10766

10767
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10768
      LOG_WARN("fail to gen new schema_version", K(ret));
10769
    } else {
10770
      schema.set_schema_version(new_schema_version);
10771
    }
10772
  }
10773

10774
  uint64_t policy_id = OB_INVALID_ID;
10775

10776
  if (OB_SUCC(ret)) {
10777
    if (OB_FAIL(ObLabelSeResolver::resolve_policy_name(tenant_id,
10778
                                                       policy_name,
10779
                                                       schema_guard,
10780
                                                       policy_id))) {
10781
      LOG_WARN("fail to resovle policy name", K(ret));
10782
    }
10783
  }
10784

10785
  if (OB_SUCC(ret)) {
10786
    bool is_usera_exist = false;
10787
    if (OB_FAIL(schema_service_.check_user_exist(tenant_id, schema.get_user_id(), is_usera_exist))) {
10788
      LOG_WARN("fail to check schema exist", K(ret));
10789
    } else if (OB_UNLIKELY(!is_usera_exist)) {
10790
      ret = OB_ERR_USER_NOT_EXIST;
10791
      LOG_WARN("the schema exists, but the schema pointer is NULL", K(ret));
10792
    }
10793
  }
10794

10795
  if (OB_SUCC(ret)) {
10796
    const ObLabelSeUserLevelSchema *old_schema = NULL;
10797
    bool is_schema_exist = false;
10798

10799
    //check if the schema is already existed
10800
    if (OB_SUCC(ret)) {
10801
      if (OB_FAIL(schema_guard.get_label_se_user_level_by_id(tenant_id,
10802
                                                             schema.get_user_id(),
10803
                                                             policy_id,
10804
                                                             old_schema))) {
10805
        LOG_WARN("fail to check schema exist", K(ret));
10806
      } else {
10807
        is_schema_exist = (old_schema != NULL);
10808
      }
10809
    }
10810

10811
    if (OB_SUCC(ret)) {
10812
      schema.set_label_se_policy_id(policy_id);
10813

10814
      if (OB_DDL_CREATE_LABEL_SE_USER_LEVELS != ddl_type) {
10815
        ret = OB_INVALID_ARGUMENT;
10816
        LOG_WARN("invalid ddl type", K(ret), K(ddl_type));
10817
      } else {
10818
        if (!is_schema_exist) {
10819
          //new schema id
10820
          uint64_t label_se_user_level_id = OB_INVALID_ID;
10821

10822
          if (OB_FAIL(schema_sql_service->fetch_new_label_se_user_level_id(tenant_id, label_se_user_level_id))) {
10823
            LOG_WARN("fail to fetch new label se policy id", K(tenant_id), K(ret));
10824
          } else {
10825
            schema.set_label_se_user_level_id(label_se_user_level_id);
10826
          }
10827
        } else {
10828
          //use old schema id
10829
          ddl_type = OB_DDL_ALTER_LABEL_SE_USER_LEVELS;
10830
          schema.set_label_se_user_level_id(old_schema->get_label_se_user_level_id());
10831
          if (schema.get_maximum_level() < 0) {
10832
            schema.set_maximum_level(old_schema->get_maximum_level());
10833
          }
10834
          if (schema.get_minimum_level() < 0) {
10835
            schema.set_minimum_level(old_schema->get_minimum_level());
10836
          }
10837
          if (schema.get_default_level() < 0) {
10838
            schema.set_default_level(old_schema->get_default_level());
10839
          }
10840
          if (schema.get_row_level() < 0) {
10841
            schema.set_row_level(old_schema->get_row_level());
10842
          }
10843
        }
10844
      }
10845
    }
10846
  }
10847

10848
  if (OB_SUCC(ret)) {
10849
    if (OB_FAIL(schema_sql_service->get_label_se_policy_sql_service()
10850
                       .apply_new_schema(schema, trans, ddl_type, ddl_stmt_str))) {
10851
      LOG_WARN("create policy info failed", K(ret));
10852
    }
10853
  }
10854

10855
  LOG_DEBUG("ddl operator handle user level schema", K(schema));
10856
  return ret;
10857
}
10858

10859
int ObDDLOperator::handle_profile_function(
10860
    ObProfileSchema &schema,
10861
    ObMySQLTransaction &trans,
10862
    share::schema::ObSchemaOperationType ddl_type,
10863
    const ObString &ddl_stmt_str,
10864
    ObSchemaGetterGuard &schema_guard
10865
    )
10866
{
10867
  int ret = OB_SUCCESS;
10868
  uint64_t tenant_id = schema.get_tenant_id();
10869
  ObSchemaService *schema_sql_service = NULL;
10870
  if (OB_ISNULL(schema_sql_service = schema_service_.get_schema_service())) {
10871
    ret = OB_ERR_SYS;
10872
    LOG_ERROR("schema_sql_service must not null", K(ret));
10873
  }
10874
  if (OB_SUCC(ret)) {
10875
    int64_t new_schema_version = OB_INVALID_VERSION;
10876
    if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
10877
      LOG_WARN("fail to gen new schema_version", K(ret));
10878
    } else {
10879
      schema.set_schema_version(new_schema_version);
10880
    }
10881
  }
10882
  if (OB_SUCC(ret)) {
10883
    bool is_schema_exist = false;
10884
    const ObProfileSchema *old_schema = NULL;
10885
    //check if the schema is already existed
10886
    if (OB_SUCC(ret)) {
10887
      if (OB_FAIL(schema_guard.get_profile_schema_by_name(tenant_id,
10888
                                                          schema.get_profile_name_str(),
10889
                                                          old_schema))) {
10890
        LOG_WARN("fail to check schema exist", K(ret));
10891
      } else {
10892
        is_schema_exist = (old_schema != NULL);
10893
      }
10894
    }
10895
    //other stuff case by case
10896
    if (OB_SUCC(ret)) {
10897
      uint64_t profile_id = OB_INVALID_ID;
10898
      switch (ddl_type) {
10899
      case OB_DDL_CREATE_PROFILE:
10900
        if (OB_UNLIKELY(is_schema_exist)) {
10901
          ret = OB_ERR_PROFILE_STRING_ALREADY_EXISTS;
10902
          LOG_USER_ERROR(OB_ERR_PROFILE_STRING_ALREADY_EXISTS, schema.get_profile_name_str().length(), schema.get_profile_name_str().ptr());
10903
        } else if (is_oracle_inner_profile_id(schema.get_profile_id())) {
10904
          /*do nothing*/
10905
        } else if (OB_FAIL(schema_sql_service->fetch_new_profile_id(tenant_id, profile_id))) {
10906
          LOG_WARN("fail to fetch new profile id", K(tenant_id), K(ret));
10907
        } else {
10908
          schema.set_profile_id(profile_id);
10909
        }
10910
        break;
10911
      case OB_DDL_ALTER_PROFILE:
10912
      case OB_DDL_DROP_PROFILE:
10913
        if (OB_UNLIKELY(!is_schema_exist)) {
10914
          ret = OB_ERR_PROFILE_STRING_DOES_NOT_EXIST;
10915
          LOG_USER_ERROR(OB_ERR_PROFILE_STRING_DOES_NOT_EXIST, schema.get_profile_name_str().length(), schema.get_profile_name_str().ptr());
10916
        } else {
10917
          schema.set_profile_id(old_schema->get_profile_id());
10918
          if (schema.get_failed_login_attempts() == ObProfileSchema::INVALID_VALUE) {
10919
            schema.set_failed_login_attempts(old_schema->get_failed_login_attempts());
10920
          }
10921
          if (schema.get_password_lock_time() == ObProfileSchema::INVALID_VALUE) {
10922
            schema.set_password_lock_time(old_schema->get_password_lock_time());
10923
          }
10924
          if (schema.get_password_life_time() == ObProfileSchema::INVALID_VALUE) {
10925
            schema.set_password_life_time(old_schema->get_password_life_time());
10926
          }
10927
          if (schema.get_password_grace_time() == ObProfileSchema::INVALID_VALUE) {
10928
            schema.set_password_grace_time(old_schema->get_password_grace_time());
10929
          }
10930
        }
10931
        break;
10932
      default:
10933
        ret = OB_NOT_SUPPORTED;
10934
        LOG_WARN("unknown ddl type", K(ret), K(ddl_type));
10935
      }
10936
    }
10937
  }
10938

10939
  if (OB_SUCC(ret)) {
10940
    if (OB_FAIL(schema_sql_service->get_profile_sql_service()
10941
                       .apply_new_schema(schema, trans, ddl_type, ddl_stmt_str))) {
10942
      LOG_WARN("apply profile failed", K(ret));
10943
    }
10944
  }
10945

10946
  LOG_DEBUG("ddl operator", K(schema));
10947
  return ret;
10948
}
10949

10950
//----Functions for directory object----
10951
int ObDDLOperator::create_directory(const ObString &ddl_str,
10952
                                    const uint64_t user_id,
10953
                                    share::schema::ObDirectorySchema &schema,
10954
                                    common::ObMySQLTransaction &trans)
10955
{
10956
  int ret = OB_SUCCESS;
10957
  ObSchemaService *schema_service = schema_service_.get_schema_service();
10958
  const uint64_t tenant_id = schema.get_tenant_id();
10959
  uint64_t new_directory_id = OB_INVALID_ID;
10960
  int64_t schema_version = OB_INVALID_VERSION;
10961
  if (OB_ISNULL(schema_service)) {
10962
    ret = OB_ERR_SYS;
10963
    LOG_ERROR("schema_service should not be null", K(ret));
10964
  } else if (OB_FAIL(schema_service->fetch_new_directory_id(tenant_id, new_directory_id))) {
10965
    LOG_WARN("failed to fetch new_directory_id", K(tenant_id), K(ret));
10966
  } else if (FALSE_IT(schema.set_directory_id(new_directory_id))) {
10967
    // do nothing
10968
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, schema_version))) {
10969
    LOG_WARN("failed to gen new_schema_version", K(tenant_id), K(ret));
10970
  } else if (FALSE_IT(schema.set_schema_version(schema_version))) {
10971
    // do nothing
10972
  } else if (OB_FAIL(schema_service->get_directory_sql_service().apply_new_schema(
10973
      schema, trans, ObSchemaOperationType::OB_DDL_CREATE_DIRECTORY, ddl_str))) {
10974
    LOG_WARN("failed to create directory", K(schema.get_directory_name()), K(ret));
10975
  } else {
10976
    // after directory created, we should grant read/write/execute privilege to user
10977
    ObTablePrivSortKey table_priv_key;
10978
    table_priv_key.tenant_id_ = tenant_id;
10979
    table_priv_key.user_id_ = user_id;
10980

10981
    ObPrivSet priv_set;
10982
    priv_set = OB_PRIV_READ | OB_PRIV_WRITE | OB_PRIV_EXECUTE;
10983

10984
    ObObjPrivSortKey obj_priv_key;
10985
    obj_priv_key.tenant_id_ = tenant_id;
10986
    obj_priv_key.obj_id_ = new_directory_id;
10987
    obj_priv_key.obj_type_ = static_cast<uint64_t>(ObObjectType::DIRECTORY);
10988
    obj_priv_key.col_id_ = OB_COMPACT_COLUMN_INVALID_ID;
10989
    obj_priv_key.grantor_id_ = OB_ORA_SYS_USER_ID;
10990
    obj_priv_key.grantee_id_ = user_id;
10991

10992
    share::ObRawObjPrivArray priv_array;
10993
    priv_array.push_back(OBJ_PRIV_ID_READ);
10994
    priv_array.push_back(OBJ_PRIV_ID_WRITE);
10995
    priv_array.push_back(OBJ_PRIV_ID_EXECUTE);
10996
    if (OB_FAIL(this->grant_table(table_priv_key, priv_set, NULL, trans,
10997
        priv_array, 0, obj_priv_key))) {
10998
      LOG_WARN("fail to grant table", K(ret), K(table_priv_key), K(priv_set), K(obj_priv_key));
10999
    }
11000
  }
11001
  return ret;
11002
}
11003

11004
int ObDDLOperator::alter_directory(const ObString &ddl_str,
11005
                                   share::schema::ObDirectorySchema &schema,
11006
                                   common::ObMySQLTransaction &trans)
11007
{
11008
  int ret = OB_SUCCESS;
11009
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11010
  const uint64_t tenant_id = schema.get_tenant_id();
11011
  int64_t new_schema_version = OB_INVALID_VERSION;
11012
  if (OB_ISNULL(schema_service)) {
11013
    ret = OB_ERR_SYS;
11014
    LOG_ERROR("schema_service should not be null", K(ret));
11015
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11016
    LOG_WARN("failed to gen new schema_version", K(ret), K(tenant_id));
11017
  } else if (FALSE_IT(schema.set_schema_version(new_schema_version))) {
11018
    // do nothing
11019
  } else if (OB_FAIL(schema_service->get_directory_sql_service().apply_new_schema(
11020
      schema, trans, ObSchemaOperationType::OB_DDL_ALTER_DIRECTORY, ddl_str))) {
11021
    LOG_WARN("failed to alter directory", K(schema), K(ret));
11022
  }
11023
  return ret;
11024
}
11025

11026
int ObDDLOperator::drop_directory(const ObString &ddl_str,
11027
                                  share::schema::ObDirectorySchema &schema,
11028
                                  common::ObMySQLTransaction &trans)
11029
{
11030
  int ret = OB_SUCCESS;
11031
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11032
  const uint64_t tenant_id = schema.get_tenant_id();
11033
  const uint64_t directory_id = schema.get_directory_id();
11034
  const uint64_t directory_type = static_cast<uint64_t>(ObObjectType::DIRECTORY);
11035
  int64_t new_schema_version = OB_INVALID_VERSION;
11036
  if (OB_ISNULL(schema_service)) {
11037
    ret = OB_ERR_SYS;
11038
    LOG_ERROR("schema_service must not null", K(ret));
11039
  } else if (OB_FAIL(this->drop_obj_privs(tenant_id, directory_id, directory_type, trans))) {
11040
    LOG_WARN("failed to drop obj privs for directory", K(ret),
11041
        K(tenant_id), K(directory_id), K(directory_type));
11042
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11043
    LOG_WARN("failed to gen new schema_version", K(ret), K(tenant_id));
11044
  } else if (FALSE_IT(schema.set_schema_version(new_schema_version))) {
11045
    // do nothing
11046
  } else if (OB_FAIL(schema_service->get_directory_sql_service().apply_new_schema(
11047
      schema, trans, ObSchemaOperationType::OB_DDL_DROP_DIRECTORY, ddl_str))) {
11048
    LOG_WARN("failed to drop directory", K(schema), K(ret));
11049
  }
11050
  return ret;
11051
}
11052
//----End of functions for directory object----
11053

11054
//----Functions for rls object----
11055
int ObDDLOperator::create_rls_policy(ObRlsPolicySchema &schema,
11056
                                     ObMySQLTransaction &trans,
11057
                                     const ObString &ddl_stmt_str,
11058
                                     bool is_update_table_schema,
11059
                                     const ObTableSchema *table_schema)
11060
{
11061
  int ret = OB_SUCCESS;
11062
  uint64_t tenant_id = schema.get_tenant_id();
11063
  uint64_t new_rls_policy_id = OB_INVALID_ID;
11064
  int64_t new_schema_version = OB_INVALID_VERSION;
11065
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11066
  if (OB_ISNULL(schema_service)) {
11067
    ret = OB_ERR_SYS;
11068
    LOG_ERROR("schema_service must not null", K(ret));
11069
  } else if (OB_FAIL(schema_service->fetch_new_rls_policy_id(tenant_id, new_rls_policy_id))) {
11070
    LOG_WARN("failed to fetch new_rls_policy_id", K(tenant_id), K(ret));
11071
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11072
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11073
  } else {
11074
    schema.set_rls_policy_id(new_rls_policy_id);
11075
    if (OB_FAIL(schema.set_ids_cascade())) {
11076
      LOG_WARN("fail to set_ids_cascade", K(schema), K(ret));
11077
    } else if (OB_FAIL(schema_service->get_rls_sql_service().apply_new_schema(
11078
        schema, new_schema_version, trans, OB_DDL_CREATE_RLS_POLICY, ddl_stmt_str))) {
11079
      LOG_WARN("fail to create rls policy", K(schema), K(ret));
11080
    } else if (!is_update_table_schema) {
11081
      // do nothing
11082
    } else if (OB_ISNULL(table_schema)) {
11083
      ret = OB_ERR_UNEXPECTED;
11084
      LOG_WARN("table schema is null", K(ret));
11085
    } else if (OB_FAIL(update_rls_table_schema(*table_schema, OB_DDL_CREATE_RLS_POLICY, trans))) {
11086
      LOG_WARN("fail to update table schema", KR(ret));
11087
    }
11088
  }
11089
  return ret;
11090
}
11091

11092
int ObDDLOperator::drop_rls_policy(const ObRlsPolicySchema &schema,
11093
                                   ObMySQLTransaction &trans,
11094
                                   const ObString &ddl_stmt_str,
11095
                                   bool is_update_table_schema,
11096
                                   const ObTableSchema *table_schema)
11097
{
11098
  int ret = OB_SUCCESS;
11099
  uint64_t tenant_id = schema.get_tenant_id();
11100
  int64_t new_schema_version = OB_INVALID_VERSION;
11101
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11102
  if (OB_ISNULL(schema_service)) {
11103
    ret = OB_ERR_SYS;
11104
    LOG_ERROR("schema_service must not null", K(ret));
11105
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11106
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11107
  } else if (OB_FAIL(schema_service->get_rls_sql_service().apply_new_schema(
11108
      schema, new_schema_version, trans, OB_DDL_DROP_RLS_POLICY, ddl_stmt_str))) {
11109
    LOG_WARN("fail to drop rls policy", K(schema), K(ret));
11110
  } else if (!is_update_table_schema) {
11111
    // do nothing
11112
  } else if (OB_ISNULL(table_schema)) {
11113
    ret = OB_ERR_UNEXPECTED;
11114
    LOG_WARN("table schema is null", K(ret));
11115
  } else if (OB_FAIL(update_rls_table_schema(*table_schema, OB_DDL_DROP_RLS_POLICY, trans))) {
11116
    LOG_WARN("fail to update table schema", KR(ret));
11117
  }
11118
  return ret;
11119
}
11120

11121
int ObDDLOperator::alter_rls_policy(const ObRlsPolicySchema &schema,
11122
                                    ObMySQLTransaction &trans,
11123
                                    const ObString &ddl_stmt_str)
11124
{
11125
  int ret = OB_SUCCESS;
11126
  uint64_t tenant_id = schema.get_tenant_id();
11127
  int64_t new_schema_version = OB_INVALID_VERSION;
11128
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11129
  if (OB_ISNULL(schema_service)) {
11130
    ret = OB_ERR_SYS;
11131
    LOG_ERROR("schema_service must not null", K(ret));
11132
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11133
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11134
  } else if (OB_FAIL(schema_service->get_rls_sql_service().apply_new_schema(
11135
      schema, new_schema_version, trans, OB_DDL_ALTER_RLS_POLICY, ddl_stmt_str))) {
11136
    LOG_WARN("fail to alter rls policy", K(schema), K(ret));
11137
  } else if (OB_FAIL(schema_service->get_table_sql_service().update_data_table_schema_version(
11138
      trans, tenant_id, schema.get_table_id(), false/*in offline ddl white list*/))) {
11139
    LOG_WARN("fail to update table schema", KR(ret));
11140
  }
11141
  return ret;
11142
}
11143

11144
int ObDDLOperator::create_rls_group(ObRlsGroupSchema &schema,
11145
                                    ObMySQLTransaction &trans,
11146
                                    const ObString &ddl_stmt_str,
11147
                                    bool is_update_table_schema,
11148
                                    const ObTableSchema *table_schema)
11149
{
11150
  int ret = OB_SUCCESS;
11151
  uint64_t tenant_id = schema.get_tenant_id();
11152
  uint64_t new_rls_group_id = OB_INVALID_ID;
11153
  int64_t new_schema_version = OB_INVALID_VERSION;
11154
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11155
  if (OB_ISNULL(schema_service)) {
11156
    ret = OB_ERR_SYS;
11157
    LOG_ERROR("schema_service must not null", K(ret));
11158
  } else if (OB_FAIL(schema_service->fetch_new_rls_group_id(tenant_id, new_rls_group_id))) {
11159
    LOG_WARN("failed to fetch new_rls_group_id", K(tenant_id), K(ret));
11160
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11161
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11162
  } else {
11163
    schema.set_rls_group_id(new_rls_group_id);
11164
    if (OB_FAIL(schema_service->get_rls_sql_service().apply_new_schema(
11165
        schema, new_schema_version, trans, OB_DDL_CREATE_RLS_GROUP, ddl_stmt_str))) {
11166
      LOG_WARN("fail to create rls group", K(schema), K(ret));
11167
    } else if (!is_update_table_schema) {
11168
      // do nothing
11169
    } else if (OB_ISNULL(table_schema)) {
11170
      ret = OB_ERR_UNEXPECTED;
11171
      LOG_WARN("table schema is null", K(ret));
11172
    } else if (OB_FAIL(update_rls_table_schema(*table_schema, OB_DDL_CREATE_RLS_GROUP, trans))) {
11173
      LOG_WARN("fail to update table schema", KR(ret));
11174
    }
11175
  }
11176
  return ret;
11177
}
11178

11179
int ObDDLOperator::drop_rls_group(const ObRlsGroupSchema &schema,
11180
                                  ObMySQLTransaction &trans,
11181
                                  const ObString &ddl_stmt_str,
11182
                                  bool is_update_table_schema,
11183
                                  const ObTableSchema *table_schema)
11184
{
11185
  int ret = OB_SUCCESS;
11186
  uint64_t tenant_id = schema.get_tenant_id();
11187
  int64_t new_schema_version = OB_INVALID_VERSION;
11188
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11189
  if (OB_ISNULL(schema_service)) {
11190
    ret = OB_ERR_SYS;
11191
    LOG_ERROR("schema_service must not null", K(ret));
11192
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11193
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11194
  } else if (OB_FAIL(schema_service->get_rls_sql_service().apply_new_schema(
11195
      schema, new_schema_version, trans, OB_DDL_DROP_RLS_GROUP, ddl_stmt_str))) {
11196
    LOG_WARN("fail to drop rls group", K(schema), K(ret));
11197
  } else if (!is_update_table_schema) {
11198
    // do nothing
11199
  } else if (OB_ISNULL(table_schema)) {
11200
    ret = OB_ERR_UNEXPECTED;
11201
    LOG_WARN("table schema is null", K(ret));
11202
  } else if (OB_FAIL(update_rls_table_schema(*table_schema, OB_DDL_DROP_RLS_GROUP, trans))) {
11203
    LOG_WARN("fail to update table schema", KR(ret));
11204
  }
11205
  return ret;
11206
}
11207

11208
int ObDDLOperator::create_rls_context(ObRlsContextSchema &schema,
11209
                                      ObMySQLTransaction &trans,
11210
                                      const ObString &ddl_stmt_str,
11211
                                      bool is_update_table_schema,
11212
                                      const ObTableSchema *table_schema)
11213
{
11214
  int ret = OB_SUCCESS;
11215
  uint64_t tenant_id = schema.get_tenant_id();
11216
  uint64_t new_rls_context_id = OB_INVALID_ID;
11217
  int64_t new_schema_version = OB_INVALID_VERSION;
11218
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11219
  if (OB_ISNULL(schema_service)) {
11220
    ret = OB_ERR_SYS;
11221
    LOG_ERROR("schema_service must not null", K(ret));
11222
  } else if (OB_FAIL(schema_service->fetch_new_rls_context_id(tenant_id, new_rls_context_id))) {
11223
    LOG_WARN("failed to fetch new_rls_context_id", K(tenant_id), K(ret));
11224
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11225
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11226
  } else {
11227
    schema.set_rls_context_id(new_rls_context_id);
11228
    if (OB_FAIL(schema_service->get_rls_sql_service().apply_new_schema(
11229
        schema, new_schema_version, trans, OB_DDL_CREATE_RLS_CONTEXT, ddl_stmt_str))) {
11230
      LOG_WARN("fail to create rls context", K(schema), K(ret));
11231
    } else if (!is_update_table_schema) {
11232
      // do nothing
11233
    } else if (OB_ISNULL(table_schema)) {
11234
      ret = OB_ERR_UNEXPECTED;
11235
      LOG_WARN("table schema is null", K(ret));
11236
    } else if (OB_FAIL(update_rls_table_schema(*table_schema, OB_DDL_CREATE_RLS_CONTEXT, trans))) {
11237
      LOG_WARN("fail to update table schema", KR(ret));
11238
    }
11239
  }
11240
  return ret;
11241
}
11242

11243
int ObDDLOperator::drop_rls_context(const ObRlsContextSchema &schema,
11244
                                    ObMySQLTransaction &trans,
11245
                                    const ObString &ddl_stmt_str,
11246
                                    bool is_update_table_schema,
11247
                                    const ObTableSchema *table_schema)
11248
{
11249
  int ret = OB_SUCCESS;
11250
  uint64_t tenant_id = schema.get_tenant_id();
11251
  int64_t new_schema_version = OB_INVALID_VERSION;
11252
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11253
  if (OB_ISNULL(schema_service)) {
11254
    ret = OB_ERR_SYS;
11255
    LOG_ERROR("schema_service must not null", K(ret));
11256
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11257
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11258
  } else if (OB_FAIL(schema_service->get_rls_sql_service().apply_new_schema(
11259
      schema, new_schema_version, trans, OB_DDL_DROP_RLS_CONTEXT, ddl_stmt_str))) {
11260
    LOG_WARN("fail to drop rls context", K(schema), K(ret));
11261
  } else if (!is_update_table_schema) {
11262
    // do nothing
11263
  } else if (OB_ISNULL(table_schema)) {
11264
    ret = OB_ERR_UNEXPECTED;
11265
    LOG_WARN("table schema is null", K(ret));
11266
  } else if (OB_FAIL(update_rls_table_schema(*table_schema, OB_DDL_DROP_RLS_CONTEXT, trans))) {
11267
    LOG_WARN("fail to update table schema", KR(ret));
11268
  }
11269
  return ret;
11270
}
11271

11272
int ObDDLOperator::drop_rls_sec_column(const ObRlsPolicySchema &schema,
11273
                                       const ObRlsSecColumnSchema &column_schema,
11274
                                       ObMySQLTransaction &trans,
11275
                                       const ObString &ddl_stmt_str)
11276
{
11277
  int ret = OB_SUCCESS;
11278
  uint64_t tenant_id = schema.get_tenant_id();
11279
  int64_t new_schema_version = OB_INVALID_VERSION;
11280
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11281
  if (OB_ISNULL(schema_service)) {
11282
    ret = OB_ERR_SYS;
11283
    LOG_ERROR("schema_service must not null", K(ret));
11284
  } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11285
    LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11286
  } else if (OB_FAIL(schema_service->get_rls_sql_service().drop_rls_sec_column(
11287
      schema, column_schema, new_schema_version, trans, ddl_stmt_str))) {
11288
    LOG_WARN("fail to drop rls policy", K(schema), K(ret));
11289
  }
11290
  return ret;
11291
}
11292

11293
int ObDDLOperator::update_rls_table_schema(const ObTableSchema &table_schema,
11294
                                           const ObSchemaOperationType ddl_type,
11295
                                           ObMySQLTransaction &trans)
11296
{
11297
  int ret = OB_SUCCESS;
11298
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11299
  bool need_add_flag = false;
11300
  bool need_del_flag = false;
11301
  if (OB_ISNULL(schema_service)) {
11302
    ret = OB_ERR_SYS;
11303
    LOG_ERROR("schema_service must not null", K(ret));
11304
  } else {
11305
    switch(ddl_type) {
11306
    case OB_DDL_CREATE_RLS_POLICY:
11307
    case OB_DDL_CREATE_RLS_GROUP:
11308
    case OB_DDL_CREATE_RLS_CONTEXT:
11309
      if (!table_schema.has_table_flag(CASCADE_RLS_OBJECT_FLAG)) {
11310
        need_add_flag = true;
11311
      }
11312
      break;
11313
    case OB_DDL_DROP_RLS_POLICY:
11314
      if (!table_schema.get_rls_group_ids().empty() ||
11315
          !table_schema.get_rls_context_ids().empty()) {
11316
        // do nothing
11317
      } else if (1 == table_schema.get_rls_policy_ids().count()) {
11318
        need_del_flag = true;
11319
      }
11320
      break;
11321
    case OB_DDL_DROP_RLS_GROUP:
11322
      if (!table_schema.get_rls_policy_ids().empty() ||
11323
          !table_schema.get_rls_context_ids().empty()) {
11324
        // do nothing
11325
      } else if (1 == table_schema.get_rls_group_ids().count()) {
11326
        need_del_flag = true;
11327
      }
11328
      break;
11329
    case OB_DDL_DROP_RLS_CONTEXT:
11330
      if (!table_schema.get_rls_policy_ids().empty() ||
11331
          !table_schema.get_rls_group_ids().empty()) {
11332
        // do nothing
11333
      } else if (1 == table_schema.get_rls_context_ids().count()) {
11334
        need_del_flag = true;
11335
      }
11336
      break;
11337
    default:
11338
      ret = OB_ERR_UNEXPECTED;
11339
      LOG_WARN("unknown ddl type", KR(ret), K(ddl_type));
11340
    }
11341
  }
11342
  if (OB_FAIL(ret)) {
11343
  } else if (OB_UNLIKELY(need_add_flag && need_del_flag)) {
11344
    ret = OB_ERR_UNEXPECTED;
11345
    LOG_WARN("unexpeted statue", KR(ret), K(ddl_type), K(table_schema));
11346
  } else if (need_add_flag || need_del_flag) {
11347
    share::schema::ObTableSchema new_table_schema;
11348
    if (OB_FAIL(new_table_schema.assign(table_schema))) {
11349
      LOG_WARN("failed to assign schema", K(ret));
11350
    } else if (FALSE_IT(new_table_schema.add_or_del_table_flag(CASCADE_RLS_OBJECT_FLAG,
11351
                                                               need_add_flag))) {
11352
    } else if (OB_FAIL(update_table_attribute(new_table_schema, trans, OB_DDL_ALTER_TABLE))) {
11353
      LOG_WARN("failed to update table attribute", K(ret));
11354
    }
11355
  } else {
11356
    if (OB_FAIL(schema_service->get_table_sql_service().update_data_table_schema_version(
11357
            trans, table_schema.get_tenant_id(), table_schema.get_table_id(), false))) {
11358
      LOG_WARN("fail to update table schema", K(ret));
11359
    }
11360
  }
11361
  return ret;
11362
}
11363

11364
int ObDDLOperator::drop_rls_object_in_drop_table(const ObTableSchema &table_schema,
11365
                                                 ObMySQLTransaction &trans,
11366
                                                 ObSchemaGetterGuard &schema_guard)
11367
{
11368
  int ret = OB_SUCCESS;
11369
  uint64_t tenant_id = table_schema.get_tenant_id();
11370
  uint64_t table_id = table_schema.get_table_id();
11371
  ObString empty_str;
11372
  for (int64_t i = 0; OB_SUCC(ret) && i < table_schema.get_rls_policy_ids().count(); ++i) {
11373
    const ObRlsPolicySchema *policy_schema = NULL;
11374
    uint64_t policy_id = table_schema.get_rls_policy_ids().at(i);
11375
    OZ (schema_guard.get_rls_policy_schema_by_id(tenant_id, policy_id, policy_schema));
11376
    CK (OB_NOT_NULL(policy_schema));
11377
    OZ (drop_rls_policy(*policy_schema, trans, empty_str, false, NULL));
11378
  }
11379
  for (int64_t i = 0; OB_SUCC(ret) && i < table_schema.get_rls_group_ids().count(); ++i) {
11380
    const ObRlsGroupSchema *group_schema = NULL;
11381
    uint64_t group_id = table_schema.get_rls_group_ids().at(i);
11382
    OZ (schema_guard.get_rls_group_schema_by_id(tenant_id, group_id, group_schema));
11383
    CK (OB_NOT_NULL(group_schema));
11384
    OZ (drop_rls_group(*group_schema, trans, empty_str, false, NULL));
11385
  }
11386
  for (int64_t i = 0; OB_SUCC(ret) && i < table_schema.get_rls_context_ids().count(); ++i) {
11387
    const ObRlsContextSchema *context_schema = NULL;
11388
    uint64_t context_id = table_schema.get_rls_context_ids().at(i);
11389
    OZ (schema_guard.get_rls_context_schema_by_id(tenant_id, context_id, context_schema));
11390
    CK (OB_NOT_NULL(context_schema));
11391
    OZ (drop_rls_context(*context_schema, trans, empty_str, false, NULL));
11392
  }
11393
  return ret;
11394
}
11395

11396
//----End of functions for rls object----
11397

11398
int ObDDLOperator::init_tenant_profile(int64_t tenant_id,
11399
                                        const share::schema::ObSysVariableSchema &sys_variable,
11400
                                        common::ObMySQLTransaction &trans)
11401
{
11402
  int ret = OB_SUCCESS;
11403
  bool is_oracle_mode = false;
11404
  if (OB_FAIL(sys_variable.get_oracle_mode(is_oracle_mode))) {
11405
    LOG_WARN("failed to get oracle mode", K(ret), K(tenant_id));
11406
  } else if (!is_oracle_mode) {
11407
    /*do nothing*/
11408
  } else {
11409
    ObProfileSchema profile_schema;
11410
    profile_schema.set_tenant_id(tenant_id);
11411
    profile_schema.set_profile_id(OB_ORACLE_TENANT_INNER_PROFILE_ID);
11412
    profile_schema.set_password_lock_time(USECS_PER_DAY);
11413
    profile_schema.set_failed_login_attempts(ObProfileSchema::UNLIMITED_VALUE);
11414
    profile_schema.set_password_life_time(ObProfileSchema::UNLIMITED_VALUE);
11415
    profile_schema.set_password_grace_time(ObProfileSchema::UNLIMITED_VALUE);
11416
    profile_schema.set_password_verify_function("NULL");
11417
    profile_schema.set_profile_name("DEFAULT");
11418
    ObSchemaService *schema_service = schema_service_.get_schema_service();
11419
    int64_t new_schema_version = OB_INVALID_VERSION;
11420
    if (OB_ISNULL(schema_service)) {
11421
      ret = OB_ERR_UNEXPECTED;
11422
      LOG_WARN("get invalid schema service", K(ret));
11423
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11424
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11425
    } else if (FALSE_IT(profile_schema.set_schema_version(new_schema_version))) {
11426
    } else if (OB_FAIL(schema_service->get_profile_sql_service().apply_new_schema(
11427
          profile_schema, trans, ObSchemaOperationType::OB_DDL_CREATE_PROFILE, NULL))) {
11428
      LOG_WARN("create default profile failed", K(ret));
11429
    }
11430
  }
11431
  return ret;
11432
}
11433

11434
int ObDDLOperator::init_tenant_keystore(int64_t tenant_id,
11435
                                        const share::schema::ObSysVariableSchema &sys_variable,
11436
                                        common::ObMySQLTransaction &trans)
11437
{
11438
  int ret = OB_SUCCESS;
11439
  bool is_oracle_mode = false;
11440
  if (OB_FAIL(sys_variable.get_oracle_mode(is_oracle_mode))) {
11441
    LOG_WARN("failed to get oracle mode", K(ret), K(tenant_id));
11442
  } else if (is_oracle_mode) {
11443
    // nothing
11444
  } else {
11445
    ObSchemaService *schema_service = schema_service_.get_schema_service();
11446
    ObKeystoreSchema keystore_schema;
11447
    keystore_schema.set_keystore_id(OB_MYSQL_TENANT_INNER_KEYSTORE_ID);
11448
    keystore_schema.set_tenant_id(tenant_id);
11449
    keystore_schema.set_status(2);
11450
    keystore_schema.set_keystore_name("mysql_keystore");
11451
    int64_t new_schema_version = OB_INVALID_VERSION;
11452
    if (OB_ISNULL(schema_service)) {
11453
      ret = OB_ERR_UNEXPECTED;
11454
      LOG_WARN("get invalid schema service", K(ret));
11455
    } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
11456
      LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id));
11457
    } else if (FALSE_IT(keystore_schema.set_schema_version(new_schema_version))) {
11458
    } else if (OB_FAIL(schema_service->get_keystore_sql_service().create_keystore(
11459
          keystore_schema, trans, NULL))) {
11460
      LOG_WARN("create keystore failed", K(ret));
11461
    }
11462
  }
11463
  return ret;
11464
}
11465

11466
int ObDDLOperator::insert_dependency_infos(common::ObMySQLTransaction &trans,
11467
                                           ObIArray<ObDependencyInfo> &dep_infos,
11468
                                           uint64_t tenant_id,
11469
                                           uint64_t dep_obj_id,
11470
                                           uint64_t schema_version, uint64_t owner_id)
11471
{
11472
  int ret = OB_SUCCESS;
11473
  if (OB_INVALID_ID == owner_id
11474
   || OB_INVALID_ID == dep_obj_id
11475
   || OB_INVALID_ID == tenant_id
11476
   || OB_INVALID_SCHEMA_VERSION == schema_version) {
11477
    ret = OB_ERR_UNEXPECTED;
11478
    LOG_WARN("illegal schema version or owner id", K(ret), K(schema_version),
11479
                                                   K(owner_id), K(dep_obj_id));
11480
  } else {
11481
    for (int64_t i = 0 ; OB_SUCC(ret) && i < dep_infos.count(); ++i) {
11482
      ObDependencyInfo & dep = dep_infos.at(i);
11483
      dep.set_tenant_id(tenant_id);
11484
      dep.set_dep_obj_id(dep_obj_id);
11485
      dep.set_dep_obj_owner_id(owner_id);
11486
      dep.set_schema_version(schema_version);
11487
      OZ (dep.insert_schema_object_dependency(trans));
11488
    }
11489
  }
11490

11491
  return ret;
11492
}
11493

11494
int ObDDLOperator::update_table_status(const ObTableSchema &orig_table_schema,
11495
                                       const int64_t schema_version,
11496
                                       const ObObjectStatus new_status,
11497
                                       const bool update_object_status_ignore_version,
11498
                                       ObMySQLTransaction &trans)
11499
{
11500
  int ret = OB_SUCCESS;
11501
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11502
  uint64_t data_version = 0;
11503
  ObTableSchema new_schema;
11504
  const ObSchemaOperationType op = OB_DDL_ALTER_TABLE;
11505
  if (OB_ISNULL(schema_service)) {
11506
    ret = OB_ERR_UNEXPECTED;
11507
    LOG_WARN("schema_service is NULL", K(ret));
11508
  } else if (schema_version <= 0) {
11509
    ret = OB_INVALID_ARGUMENT;
11510
    LOG_WARN("schema_version is invalid", K(ret), K(schema_version));
11511
  } else if (!update_object_status_ignore_version && OB_FAIL(GET_MIN_DATA_VERSION(orig_table_schema.get_tenant_id(), data_version))) {
11512
    LOG_WARN("failed to get data version", K(ret));
11513
  } else if (!update_object_status_ignore_version && data_version < DATA_VERSION_4_1_0_0) {
11514
    ret = OB_NOT_SUPPORTED;
11515
    LOG_WARN("version and feature mismatch", K(ret));
11516
  } else if (OB_FAIL(new_schema.assign(orig_table_schema))) {
11517
    LOG_WARN("failed to assign table schema", K(ret));
11518
  } else if (FALSE_IT(new_schema.set_object_status(new_status))) {
11519
  } else if (FALSE_IT(new_schema.set_schema_version(schema_version))) {
11520
  } else if (new_schema.get_column_count() > 0
11521
             && FALSE_IT(new_schema.set_view_column_filled_flag(ObViewColumnFilledFlag::FILLED))) {
11522
    /*
11523
    *Except for drop view, there is no way to reduce the column count,
11524
    *and there is no need to consider the table mode of this view before
11525
    */
11526
  } else if (OB_FAIL(schema_service->get_table_sql_service().update_table_attribute(trans, new_schema, op, update_object_status_ignore_version) )) {
11527
    LOG_WARN("update table status failed", K(ret));
11528
  }
11529
  return ret;
11530
}
11531

11532
int ObDDLOperator::update_view_columns(const ObTableSchema &view_schema,
11533
                                        common::ObMySQLTransaction &trans)
11534
{
11535
  int ret = OB_SUCCESS;
11536
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11537
  uint64_t data_version = 0;
11538
  if (OB_ISNULL(schema_service)) {
11539
    ret = OB_ERR_UNEXPECTED;
11540
    LOG_WARN("schema_service is NULL", K(ret));
11541
  } else if (OB_FAIL(GET_MIN_DATA_VERSION(view_schema.get_tenant_id(), data_version))) {
11542
    LOG_WARN("failed to get data version", K(ret));
11543
  } else if (data_version < DATA_VERSION_4_1_0_0) {
11544
    ret = OB_NOT_SUPPORTED;
11545
    LOG_WARN("version and feature mismatch", K(ret));
11546
  } else if (OB_FAIL(schema_service->get_table_sql_service().update_view_columns(trans, view_schema))) {
11547
    LOG_WARN("failed to add columns", K(ret));
11548
  }
11549
  return ret;
11550
}
11551

11552
// only used in upgrading
11553
int ObDDLOperator::reset_view_status(common::ObMySQLTransaction &trans,
11554
                                     const uint64_t tenant_id,
11555
                                     const ObTableSchema *table)
11556
{
11557
  int ret = OB_SUCCESS;
11558
  ObObjectStatus new_status = ObObjectStatus::INVALID;
11559
  ObSchemaService *schema_service = schema_service_.get_schema_service();
11560
  int64_t schema_version = OB_INVALID_VERSION;
11561
  const bool update_object_status_ignore_version = true;
11562
  if (OB_ISNULL(schema_service)) {
11563
    ret = OB_ERR_UNEXPECTED;
11564
    LOG_WARN("schema_service is NULL", K(ret));
11565
  } else {
11566
    if (OB_ISNULL(table) || !table->is_view_table()) {
11567
      ret = OB_ERR_UNEXPECTED;
11568
      LOG_WARN("get wrong schema", K(ret), KP(table));
11569
    } else if (OB_FAIL(schema_service->gen_new_schema_version(tenant_id, schema_version, schema_version))) {
11570
      LOG_WARN("failed to gen new schema version", K(ret));
11571
    } else if (OB_FAIL(update_table_status(*table,
11572
                                            schema_version,
11573
                                            new_status,
11574
                                            update_object_status_ignore_version,
11575
                                            trans))) {
11576
      LOG_WARN("failed to update table status", K(ret));
11577
    }
11578
  }
11579
  return ret;
11580
}
11581

11582

11583
// only used in upgrading
11584
int ObDDLOperator::try_add_dep_info_for_synonym(const ObSimpleSynonymSchema *synonym_info,
11585
                                                common::ObMySQLTransaction &trans)
11586
{
11587
  int ret = OB_SUCCESS;
11588
  //add def obj info if exists
11589
  bool ref_exists = false;
11590
  ObObjectType ref_type = ObObjectType::INVALID;
11591
  uint64_t ref_obj_id = OB_INVALID_ID;
11592
  uint64_t ref_schema_version = share::OB_INVALID_SCHEMA_VERSION;
11593
  if (OB_ISNULL(synonym_info)) {
11594
    ret = OB_ERR_UNEXPECTED;
11595
    LOG_WARN("get unecpected synonym info", K(ret));
11596
  } else if (OB_FAIL(ObSQLUtils::find_synonym_ref_obj(synonym_info->get_object_database_id(),
11597
                                                      synonym_info->get_object_name_str(),
11598
                                                      synonym_info->get_tenant_id(),
11599
                                                      ref_exists,
11600
                                                      ref_obj_id,
11601
                                                      ref_type,
11602
                                                      ref_schema_version))) {
11603
    LOG_WARN("failed to find synonym ref obj", K(ret));
11604
  } else {
11605
    if (ref_exists) {
11606
      ObDependencyInfo dep;
11607
      dep.set_dep_obj_id(synonym_info->get_synonym_id());
11608
      dep.set_dep_obj_type(ObObjectType::SYNONYM);
11609
      dep.set_ref_obj_id(ref_obj_id);
11610
      dep.set_ref_obj_type(ref_type);
11611
      dep.set_dep_timestamp(-1);
11612
      dep.set_ref_timestamp(ref_schema_version);
11613
      dep.set_tenant_id(synonym_info->get_tenant_id());
11614
      if (OB_FAIL(dep.insert_schema_object_dependency(trans))) {
11615
        if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) {
11616
          ret = OB_SUCCESS;
11617
          LOG_TRACE("synonym have dep info before", K(*synonym_info));
11618
        }
11619
      }
11620
    }
11621
  }
11622
  return ret;
11623
}
11624

11625

11626
}//end namespace rootserver
11627
}//end namespace oceanbase
11628

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.