diff --git a/mittest/simple_server/CMakeLists.txt b/mittest/simple_server/CMakeLists.txt index 38ae7d307f..1fe872edb0 100644 --- a/mittest/simple_server/CMakeLists.txt +++ b/mittest/simple_server/CMakeLists.txt @@ -44,3 +44,4 @@ ob_unittest_observer(test_big_tx_data test_big_tx_data.cpp) ob_unittest_observer(test_fast_commit_report fast_commit_report.cpp) ob_unittest_observer(test_mvcc_gc test_mvcc_gc.cpp) ob_unittest_observer(test_ob_simple_rto test_ob_simple_rto.cpp) +ob_unittest_observer(test_all_virtual_proxy_partition_info_default_value test_all_virtual_proxy_partition_info_default_value.cpp) \ No newline at end of file diff --git a/mittest/simple_server/env/ob_simple_cluster_test_base.cpp b/mittest/simple_server/env/ob_simple_cluster_test_base.cpp index 75b0d92c79..90768fa2ec 100644 --- a/mittest/simple_server/env/ob_simple_cluster_test_base.cpp +++ b/mittest/simple_server/env/ob_simple_cluster_test_base.cpp @@ -186,7 +186,8 @@ int ObSimpleClusterTestBase::close() int ObSimpleClusterTestBase::create_tenant(const char *tenant_name, const char *memory_size, - const char *log_disk_size) + const char *log_disk_size, + const bool oracle_mode) { SERVER_LOG(INFO, "create tenant start"); int32_t log_level; @@ -241,7 +242,7 @@ int ObSimpleClusterTestBase::create_tenant(const char *tenant_name, { ObSqlString sql; if (OB_FAIL(ret)) { - } else if (OB_FAIL(sql.assign_fmt("create tenant %s replica_num = 1, primary_zone='zone1', resource_pool_list=('pool_ym_%s') set ob_tcp_invited_nodes='%%';", tenant_name, tenant_name))) { + } else if (OB_FAIL(sql.assign_fmt("create tenant %s replica_num = 1, primary_zone='zone1', resource_pool_list=('pool_ym_%s') set ob_tcp_invited_nodes='%%'%s", tenant_name, tenant_name, oracle_mode ? ", ob_compatibility_mode='oracle'" : ";"))) { SERVER_LOG(WARN, "create_tenant", K(ret)); } else if (OB_FAIL(sql_proxy.write(sql.ptr(), affected_rows))) { SERVER_LOG(WARN, "create_tenant", K(ret)); diff --git a/mittest/simple_server/env/ob_simple_cluster_test_base.h b/mittest/simple_server/env/ob_simple_cluster_test_base.h index bb322de772..64d3eaed59 100644 --- a/mittest/simple_server/env/ob_simple_cluster_test_base.h +++ b/mittest/simple_server/env/ob_simple_cluster_test_base.h @@ -42,7 +42,8 @@ public: int create_tenant(const char *tenant_name = "tt1", const char *memory_size = "2G", - const char *log_disk_size = "2G"); + const char *log_disk_size = "2G", + const bool oracle_mode = false); int delete_tenant(const char *tenant_name = "tt1"); int get_tenant_id(uint64_t &tenant_id, const char *tenant_name = "tt1"); int exec_write_sql_sys(const char *sql_str, int64_t &affected_rows); diff --git a/mittest/simple_server/env/ob_simple_server.cpp b/mittest/simple_server/env/ob_simple_server.cpp index 779735c23f..8d4b91255c 100644 --- a/mittest/simple_server/env/ob_simple_server.cpp +++ b/mittest/simple_server/env/ob_simple_server.cpp @@ -235,10 +235,11 @@ int ObSimpleServer::init_sql_proxy() return ret; } -int ObSimpleServer::init_sql_proxy2(const char *tenant_name, const char *db_name) +int ObSimpleServer::init_sql_proxy2(const char *tenant_name, const char *db_name, const bool oracle_mode) { int ret = OB_SUCCESS; - sql_conn_pool2_.set_db_param(("root@" + std::string(tenant_name)).c_str(), "", db_name); + std::string user = oracle_mode ? "sys@" : "root@"; + sql_conn_pool2_.set_db_param((user + std::string(tenant_name)).c_str(), "", db_name); common::ObAddr db_addr; db_addr.set_ip_addr(local_ip_.c_str(), mysql_port_); diff --git a/mittest/simple_server/env/ob_simple_server.h b/mittest/simple_server/env/ob_simple_server.h index 91008c868a..750c85f182 100644 --- a/mittest/simple_server/env/ob_simple_server.h +++ b/mittest/simple_server/env/ob_simple_server.h @@ -52,7 +52,7 @@ public: return addr; } - int init_sql_proxy2(const char *tenant_name = "tt1", const char *db_name="test"); + int init_sql_proxy2(const char *tenant_name = "tt1", const char *db_name="test", const bool oracle_mode = false); int init_sql_proxy_with_short_wait(); protected: int init_sql_proxy(); diff --git a/mittest/simple_server/test_all_virtual_proxy_partition_info_default_value.cpp b/mittest/simple_server/test_all_virtual_proxy_partition_info_default_value.cpp new file mode 100644 index 0000000000..4e26f1cd6d --- /dev/null +++ b/mittest/simple_server/test_all_virtual_proxy_partition_info_default_value.cpp @@ -0,0 +1,307 @@ +/** + * Copyright (c) 2022 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX SHARE + +#include +#include +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" +#include "lib/timezone/ob_time_convert.h" + +namespace oceanbase +{ +namespace share +{ +using namespace schema; +using namespace common; + +static const int64_t table_count = 6; +static const int64_t int_default_value = 1; +static const char *varchar_default_value = "aaa"; +static const float float_default_value = 1.01; +static const double double_default_value = 2.111345; +static const char *timestamp_default_value = "2022-10-12 11:56:00.0"; +static const char *datetime_default_value = "2022-10-12"; + +class TestProxyDefaultValue : public unittest::ObSimpleClusterTestBase +{ +public: + TestProxyDefaultValue() : unittest::ObSimpleClusterTestBase("test_proxy_default_value") {} +private: +}; + +TEST_F(TestProxyDefaultValue, test_mysql_common_data_types) +{ + int ret = OB_SUCCESS; + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("use oceanbase;")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + // create table + sql.reset(); + ret = sql.assign_fmt("create table t1(c1 int default %ld not null, c2 varchar(20) default '%s', " + "c3 float default %f not null, c4 double default %lf not null, c5 timestamp default '%s', " + "c6 datetime default '%s') partition by key(c1,c2,c3,c4,c5,c6)", + int_default_value, varchar_default_value, float_default_value, + double_default_value, timestamp_default_value, datetime_default_value); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + OB_LOG(INFO, "create_table succ"); + + sql.reset(); + ret = sql.assign_fmt("select part_key_default_value from __all_virtual_proxy_partition_info " + "where tenant_name = 'sys' and table_id = (select table_id from __all_virtual_table where table_name='t1')"); + ASSERT_EQ(OB_SUCCESS, ret); + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(result, OB_SYS_TENANT_ID, sql.ptr())); + ASSERT_TRUE(OB_NOT_NULL(result.get_result())); + sqlclient::ObMySQLResult &res = *result.get_result(); + int64_t index = 0; + + while (OB_SUCC(ret)) { + if (OB_SUCC(res.next())) { + ObString tmp_str; + ObObj row; + int64_t pos = 0; + ret = res.get_varchar("part_key_default_value", tmp_str); + ASSERT_EQ(OB_SUCCESS, ret); + ret = row.deserialize(tmp_str.ptr(), tmp_str.length(), pos); + ASSERT_EQ(OB_SUCCESS, ret); + LOG_INFO("default value", K(index), K(row)); + switch(index) { + case 0: { + bool equal = int_default_value == row.get_int(); + ASSERT_TRUE(equal); + break; + } + case 1: { + bool equal = (0 == row.get_string().compare(varchar_default_value)); + ASSERT_TRUE(equal); + break; + } + case 2: { + bool equal = row.get_float() == float_default_value; + ASSERT_TRUE(equal); + break; + } + case 3: { + bool equal = row.get_double() == double_default_value; + ASSERT_TRUE(equal); + break; + } + case 4: { + int64_t timestamp = 0; + ObTimeZoneInfo tz_info; + char buf[50] = {0}; + ObString str; + ObTimeConvertCtx cvrt_ctx(&tz_info, true); + strcpy(buf, "+8:00"); + str.assign(buf, static_cast(strlen(buf))); + tz_info.set_timezone(str); + ret = ObTimeConverter::str_to_datetime(ObString(timestamp_default_value), cvrt_ctx, timestamp); + ASSERT_EQ(OB_SUCCESS, ret); + bool equal = row.get_timestamp() == timestamp; + LOG_INFO("timestamp default value", K(row.get_timestamp()), K(timestamp)); + ASSERT_TRUE(equal); + break; + } + case 5: { + int64_t datetime = 0; + ObTimeZoneInfo tz_info; + char buf[50] = {0}; + ObString str; + ObTimeConvertCtx cvrt_ctx(&tz_info, true); + cvrt_ctx.oracle_nls_format_ = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_TZ_FORMAT; + strcpy(buf, "+00:00"); + str.assign(buf, static_cast(strlen(buf))); + tz_info.set_timezone(str); + ret = ObTimeConverter::str_to_datetime(ObString(datetime_default_value), cvrt_ctx, datetime); + ASSERT_EQ(OB_SUCCESS, ret); + bool equal = row.get_datetime() == datetime; + LOG_INFO("datetime default value", K(row.get_datetime()), K(datetime)); + ASSERT_TRUE(equal); + break; + } + default: FAIL(); + } + ++index; + } + } // end while + } +} + +TEST_F(TestProxyDefaultValue, test_oracle_common_data_types) +{ + int ret = OB_SUCCESS; + ASSERT_EQ(OB_SUCCESS, create_tenant("oracle", "2G", "2G", true)); + // sys tenant sql_proxy + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + int64_t affected_rows = 0; + sql.assign_fmt("alter tenant oracle set variables nls_date_format='YYYY-MM-DD HH24:MI:SS';"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + sql.reset(); + sql.assign_fmt("alter tenant oracle set variables nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF'"); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + //init oracle_sql_proxy + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2("oracle", "SYS", true)); + common::ObMySQLProxy &oracle_sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + sql.reset(); + ret = sql.assign_fmt("create table ot1(c1 number default %ld not null, c2 varchar2(20) default '%s', " + "c3 NVARCHAR2(10) default '%s' not null, c4 binary_double default %lf not null, c5 timestamp default '%s', " + "c6 date default '%s') partition by hash(c1,c2,c3,c4,c5,c6)", + int_default_value, varchar_default_value, varchar_default_value, + double_default_value, timestamp_default_value, datetime_default_value); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, oracle_sql_proxy.write(sql.ptr(), affected_rows)); + OB_LOG(INFO, "create_table succ"); + + // query in sys tenant + sql.reset(); + ret = sql.assign_fmt("select part_key_default_value from __all_virtual_proxy_partition_info " + "where tenant_name = 'oracle' and table_id = (select table_id from __all_virtual_table where table_name='ot1')"); + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(result, OB_SYS_TENANT_ID, sql.ptr())); + ASSERT_TRUE(OB_NOT_NULL(result.get_result())); + sqlclient::ObMySQLResult &res = *result.get_result(); + int64_t index = 0; + + while (OB_SUCC(ret)) { + if (OB_SUCC(res.next())) { + ObString tmp_str; + ObSqlString tmp_value; + ObObj row; + int64_t pos = 0; + ret = res.get_varchar("part_key_default_value", tmp_str); + ASSERT_EQ(OB_SUCCESS, ret); + ret = row.deserialize(tmp_str.ptr(), tmp_str.length(), pos); + ASSERT_EQ(OB_SUCCESS, ret); + LOG_INFO("default value", K(index), K(row)); + switch(index) { + case 0: { + ASSERT_EQ(OB_SUCCESS, tmp_value.assign_fmt("%ld", int_default_value)); + bool equal = (0 == row.get_string().compare(tmp_value.ptr())); + ASSERT_TRUE(equal); + break; + } + case 1: { + ASSERT_EQ(OB_SUCCESS, tmp_value.assign_fmt("'%s'", varchar_default_value)); + bool equal = (0 == row.get_string().compare(tmp_value.ptr())); + ASSERT_TRUE(equal); + break; + } + case 2: { + ASSERT_EQ(OB_SUCCESS, tmp_value.assign_fmt("'%s'", varchar_default_value)); + bool equal = (0 == row.get_string().compare(tmp_value.ptr())); + ASSERT_TRUE(equal); + break; + } + case 3: { + ASSERT_EQ(OB_SUCCESS, tmp_value.assign_fmt("%lf", double_default_value)); + bool equal = (0 == row.get_string().compare(tmp_value.ptr())); + ASSERT_TRUE(equal); + break; + } + case 4: { + ASSERT_EQ(OB_SUCCESS, tmp_value.assign_fmt("'%s'", timestamp_default_value)); + bool equal = (0 == row.get_string().compare(tmp_value.ptr())); + ASSERT_TRUE(equal); + break; + } + case 5: { + ASSERT_EQ(OB_SUCCESS, tmp_value.assign_fmt("'%s'", datetime_default_value)); + bool equal = (0 == row.get_string().compare(tmp_value.ptr())); + ASSERT_TRUE(equal); + break; + } + default: FAIL(); + } + ++index; + } + } // end while + } +} + +TEST_F(TestProxyDefaultValue, test_default_value_is_null) +{ + int ret = OB_SUCCESS; + // sys tenant sql_proxy + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + // oracle tenant sql_proxy + common::ObMySQLProxy &oracle_sql_proxy = get_curr_simple_server().get_sql_proxy2(); + + // create table + ObSqlString sql; + int64_t affected_rows = 0; + ret = sql.assign_fmt("create table t2 (c1 int default 1, c2 int, c3 int generated always as (c1 + 1) virtual) partition by key(c2, c3);"); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + sql.reset(); + ret = sql.assign_fmt("create table ot2 (c1 number default 1, c2 number, c3 number generated as (c1 + 1) virtual, c4 int generated by default as identity not null) partition by hash(c2, c3, c4);"); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, oracle_sql_proxy.write(sql.ptr(), affected_rows)); + + // query in sys tenant + sql.reset(); + ret = sql.assign_fmt("select part_key_default_value from __all_virtual_proxy_partition_info " + "where tenant_name = 'sys' and table_id = (select table_id from __all_virtual_table where table_name='t2')"); + ASSERT_EQ(OB_SUCCESS, ret); + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(result, OB_SYS_TENANT_ID, sql.ptr())); + ASSERT_TRUE(OB_NOT_NULL(result.get_result())); + sqlclient::ObMySQLResult &res = *result.get_result(); + int64_t index = 0; + while (OB_SUCC(ret)) { + if (OB_SUCC(res.next())) { + ObString tmp_str; + ret = res.get_varchar("part_key_default_value", tmp_str); + ASSERT_EQ(OB_ERR_NULL_VALUE, ret); + } + } + } + + sql.reset(); + ret = sql.assign_fmt("select part_key_default_value from __all_virtual_proxy_partition_info " + "where tenant_name = 'oracle' and table_id = (select table_id from __all_virtual_table where table_name='ot2')"); + ASSERT_EQ(OB_SUCCESS, ret); + SMART_VAR(ObMySQLProxy::MySQLResult, result1) { + ret = sql_proxy.read(result1, OB_SYS_TENANT_ID, sql.ptr()); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(OB_NOT_NULL(result1.get_result())); + sqlclient::ObMySQLResult &res = *result1.get_result(); + int64_t index = 0; + while (OB_SUCC(ret)) { + if (OB_SUCC(res.next())) { + ObString tmp_str; + ret = res.get_varchar("part_key_default_value", tmp_str); + ASSERT_EQ(OB_ERR_NULL_VALUE, ret); + } + } + } +} + +} // namespace share +} // namespace oceanbase + +int main(int argc, char **argv) +{ + unittest::init_log_and_gtest(argc, argv); + OB_LOGGER.set_log_level("INFO"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.cpp b/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.cpp index 66b444441e..9aaa2fe71f 100644 --- a/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.cpp @@ -467,9 +467,9 @@ int ObAllVirtualProxyPartitionInfo::fill_row_(const ObTableSchema &table_schema) break; } case PART_KEY_SCALE: { - cells[i].set_int(static_cast(accuracy.get_scale())); - break; - } + cells[i].set_int(static_cast(accuracy.get_scale())); + break; + } case SPARE1: {// int, unused cells[i].set_int(0); break; @@ -497,6 +497,34 @@ int ObAllVirtualProxyPartitionInfo::fill_row_(const ObTableSchema &table_schema) cells[i].set_collation_type(coll_type); break; } + case PART_KEY_DEFAULT_VALUE: { + if (column_schema->is_generated_column() + || column_schema->is_identity_column() + || column_schema->get_cur_default_value().is_null()) { + cells[i].set_null(); + } else { + char *buf = NULL; + const ObObj &obj = column_schema->get_cur_default_value(); + const int64_t buf_len = obj.get_serialize_size(); + int64_t pos = 0; + if (OB_ISNULL(allocator_)) { + ret = OB_NOT_INIT; + LOG_WARN("data member doesn't init", KR(ret)); + } else if (OB_ISNULL(buf = static_cast(allocator_->alloc(buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("alloc tmp_buf fail", KR(ret)); + } else if (OB_FAIL(obj.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize", KR(ret)); + } else if (OB_UNLIKELY(pos > buf_len) || pos < 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get buf", K(pos), K(buf_len), KR(ret)); + } else { + cur_row_.cells_[i].set_lob_value(ObLongTextType, buf, static_cast(pos)); + } + } + cells[i].set_collation_type(coll_type); + break; + } default: { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid column id", K(i), KR(ret)); diff --git a/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.h b/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.h index 7ebdc9ed2e..800a1a8150 100644 --- a/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.h +++ b/src/observer/virtual_table/ob_all_virtual_proxy_partition_info.h @@ -85,6 +85,7 @@ class ObAllVirtualProxyPartitionInfo : public ObAllVirtualProxyBaseIterator SPARE4, SPARE5, SPARE6, + PART_KEY_DEFAULT_VALUE, }; public: diff --git a/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp b/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp index 9bd303ee31..11b480ecd9 100644 --- a/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp +++ b/src/share/inner_table/ob_inner_table_schema.11051_11100.cpp @@ -1544,6 +1544,21 @@ int ObInnerTableSchema::all_virtual_proxy_partition_info_schema(ObTableSchema &t false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("part_key_default_value", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_HASH); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp b/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp index 2184f95bd4..51d818bda2 100644 --- a/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.15201_15250.cpp @@ -8301,6 +8301,21 @@ int ObInnerTableSchema::all_virtual_proxy_partition_info_ora_schema(ObTableSchem false, //is_nullable false); //is_autoincrement } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("PART_KEY_DEFAULT_VALUE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } table_schema.set_index_using_type(USING_HASH); table_schema.set_row_store_type(ENCODING_ROW_STORE); table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); diff --git a/src/share/inner_table/ob_inner_table_schema_def.py b/src/share/inner_table/ob_inner_table_schema_def.py index 200f1ca8db..a45e39823c 100644 --- a/src/share/inner_table/ob_inner_table_schema_def.py +++ b/src/share/inner_table/ob_inner_table_schema_def.py @@ -7160,6 +7160,7 @@ def_table_schema( ('spare4', 'varchar:OB_MAX_PARTITION_EXPR_LENGTH'), ('spare5', 'varchar:OB_MAX_PARTITION_EXPR_LENGTH'), ('spare6', 'varchar:OB_MAX_PARTITION_EXPR_LENGTH'), + ('part_key_default_value', 'longtext'), ], )