support json type

This commit is contained in:
xj0
2022-02-08 14:58:13 +08:00
committed by LINxiansheng
parent 4b25bac8d0
commit e5f59ea074
241 changed files with 46116 additions and 749 deletions

View File

@ -211,7 +211,26 @@ int OB_INLINE ObExprOperator::cast_operand_type(
cast_mode |= CM_COLUMN_CONVERT;
}
if (ob_is_string_or_lob_type(res_type.get_calc_type()) && res_type.is_zerofill()) {
bool is_bool = false;
ObItemType item_type = T_NULL;
if (lib::is_mysql_mode() && calc_type == ObJsonType && ob_obj_type_class(param_type) == ObIntTC) {
if (OB_FAIL(get_param_is_boolean(expr_ctx, res_obj, is_bool))) {
LOG_WARN("get src item type failed, bool may be cast as json int", K(res_obj), K(ret));
}
}
if (OB_FAIL(ret)) {
} else if (is_bool) {
const ObObj *tmp_res_obj = NULL;
EXPR_DEFINE_CAST_CTX(expr_ctx, cast_mode);
if (CS_TYPE_INVALID != calc_collation_type) {
cast_ctx.dest_collation_ = calc_collation_type;
} else if (share::is_mysql_mode()
&& CS_TYPE_INVALID != param_collation_type) {
cast_ctx.dest_collation_ = param_collation_type;
}
ret = ObObjCaster::bool_to_json(calc_type, cast_ctx, res_obj, res_obj, tmp_res_obj);
LOG_DEBUG("cast bool to json", K(cast_mode), K(calc_type), K(cast_ctx.dest_collation_), K(res_obj), K(ret));
} else if (ob_is_string_or_lob_type(res_type.get_calc_type()) && res_type.is_zerofill()) {
// For zerofilled string
ObZerofillInfo zf_info(true, res_type.get_length());
EXPR_DEFINE_CAST_CTX_ZF(expr_ctx, cast_mode, &zf_info);
@ -239,7 +258,9 @@ int OB_INLINE ObExprOperator::cast_operand_type(
} else {
cast_ctx.dest_collation_ = ObCharset::get_default_collation_oracle(CHARSET_UTF8MB4);
}
}
}
} else if (share::is_mysql_mode() && ob_is_json(calc_type)) {
cast_ctx.dest_collation_ = CS_TYPE_UTF8MB4_BIN;
}
ObObj res_obj_copy = res_obj;
cast_ctx.expect_obj_collation_ = cast_ctx.dest_collation_;
@ -474,6 +495,36 @@ int ObExprOperator::param_eval(common::ObExprCtx& expr_ctx, const common::ObObj&
return ret;
}
int ObExprOperator::get_param_type(common::ObExprCtx &expr_ctx,
const common::ObObj &param, ObItemType &param_type) const
{
int ret = OB_SUCCESS;
if (OB_ISNULL(expr_ctx.infix_expr_)) {
// do nothing for postfix expression
} else {
if (OB_FAIL(expr_ctx.infix_expr_->get_param_type(expr_ctx, param, param_type))) {
LOG_WARN("param eval failed", K(ret));
}
}
return ret;
}
int ObExprOperator::get_param_is_boolean(common::ObExprCtx &expr_ctx,
const common::ObObj &param, bool &is_boolean) const
{
int ret = OB_SUCCESS;
is_boolean = false;
if (OB_ISNULL(expr_ctx.infix_expr_)) {
// do nothing for postfix expression
} else {
if (OB_FAIL(expr_ctx.infix_expr_->get_param_is_boolean(expr_ctx, param,
is_boolean))) {
LOG_WARN("get param bool semantics failed", K(ret));
}
}
return ret;
}
bool ObExprOperator::is_valid_nls_param(const common::ObString& nls_param_str)
{
bool bret = false;
@ -721,7 +772,7 @@ int ObExprOperator::aggregate_string_type_and_charset_oracle(const ObBasicSessio
if (OB_SUCC(ret)) {
result.set_type_simple(result_type);
if (ob_is_large_text(result_type)) {
if (ob_is_large_text(result_type) || ob_is_json(result_type)) {
result.set_lob_inrow();
}
result.set_collation_type(result_charset);
@ -811,6 +862,8 @@ int ObExprOperator::is_same_kind_type_for_case(const ObExprResType& type1, const
match = ob_is_blob_locator(type2.get_type(), type2.get_collation_type());
} else if (ob_is_clob_locator(type1.get_type(), type1.get_collation_type())) {
match = ob_is_clob_locator(type2.get_type(), type2.get_collation_type());
} else if (ob_is_json(type1.get_type())) {
match = ob_is_json(type2.get_type());
}
}
return ret;
@ -903,6 +956,9 @@ int ObExprOperator::aggregate_result_type_for_merge(ObExprResType& type, const O
type.set_collation_level(CS_LEVEL_NUMERIC);
} else if (ob_is_interval_tc(res_type)) {
ret = aggregate_accuracy_for_merge(type, types, param_num);
} else if (ob_is_json(res_type)) {
type.set_collation_type(CS_TYPE_UTF8MB4_BIN);
type.set_collation_level(CS_LEVEL_IMPLICIT);
}
}
LOG_DEBUG("merged type is", K(type), K(is_oracle_mode));
@ -3116,136 +3172,12 @@ void ObStringExprOperator::calc_temporal_format_result_length(
ObObjType ObStringExprOperator::get_result_type_mysql(int64_t char_length) const
{
/*
drop table t1;
drop table t2;
create table t1 (
col_varchar varchar(1),
col_varbinary varbinary(1),
col_char char(1),
col_binary binary(1),
col_tinytext tinytext,
col_tinyblob tinyblob,
col_mediumtext mediumtext,
col_mediumblob mediumblob,
col_text text,
col_blob blob,
col_count bigint);
create table t2 as
select repeat('啊', 512),
repeat('a', 513),
repeat('啊', 21845),
repeat('a', 21846),
repeat(col_varchar, '512'),
repeat(col_varchar, '513'),
repeat(col_varchar, 65535),
repeat(col_varchar, 65536),
repeat(col_varbinary, '512'),
repeat(col_varbinary, '513'),
repeat(col_varbinary, 65535),
repeat(col_varbinary, 65536),
repeat(col_char, '512'),
repeat(col_char, '513'),
repeat(col_char, 65535),
repeat(col_char, 65536),
repeat(col_binary, '512'),
repeat(col_binary, '513'),
repeat(col_binary, 65535),
repeat(col_binary, 65536),
repeat(col_tinytext, 2),
repeat(col_tinytext, 3),
repeat(col_tinytext, 257),
repeat(col_tinytext, 258),
repeat(col_tinyblob, 2),
repeat(col_tinyblob, 3),
repeat(col_tinyblob, 257),
repeat(col_tinyblob, 258),
repeat(col_mediumtext, 1),
repeat(col_mediumblob, 1),
repeat(col_text, 1),
repeat(col_text, 2),
repeat(col_blob, 1),
repeat(col_blob, 2),
repeat('啊', col_count),
repeat('a', col_count),
repeat(col_varchar, col_count),
repeat(col_varbinary, col_count),
repeat(col_char, col_count),
repeat(col_binary, col_count),
repeat(col_tinytext, col_count),
repeat(col_tinyblob, col_count),
repeat(col_mediumtext, col_count),
repeat(col_mediumblob, col_count),
repeat(col_text, col_count),
repeat(col_blob, col_count)
from t1;
desc t2;
MySQL> desc t2;
+-----------------------------------+----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------------+----------------+------+-----+---------+-------+
| repeat('啊', 512) | varchar(512) | YES | | NULL | |
| repeat('a', 513) | text | YES | | NULL | |
| repeat('啊', 21845) | text | YES | | NULL | |
| repeat('a', 21846) | longtext | YES | | NULL | |
| repeat(col_varchar, '512') | varchar(512) | YES | | NULL | |
| repeat(col_varchar, '513') | text | YES | | NULL | |
| repeat(col_varchar, 65535) | text | YES | | NULL | |
| repeat(col_varchar, 65536) | longtext | YES | | NULL | |
| repeat(col_varbinary, '512') | varbinary(512) | YES | | NULL | |
| repeat(col_varbinary, '513') | blob | YES | | NULL | |
| repeat(col_varbinary, 65535) | blob | YES | | NULL | |
| repeat(col_varbinary, 65536) | longblob | YES | | NULL | |
| repeat(col_char, '512') | varchar(512) | YES | | NULL | |
| repeat(col_char, '513') | text | YES | | NULL | |
| repeat(col_char, 65535) | text | YES | | NULL | |
| repeat(col_char, 65536) | longtext | YES | | NULL | |
| repeat(col_binary, '512') | varbinary(512) | YES | | NULL | |
| repeat(col_binary, '513') | blob | YES | | NULL | |
| repeat(col_binary, 65535) | blob | YES | | NULL | |
| repeat(col_binary, 65536) | longblob | YES | | NULL | |
| repeat(col_tinytext, 2) | varchar(510) | YES | | NULL | |
| repeat(col_tinytext, 3) | text | YES | | NULL | |
| repeat(col_tinytext, 257) | text | YES | | NULL | |
| repeat(col_tinytext, 258) | longtext | YES | | NULL | |
| repeat(col_tinyblob, 2) | varbinary(510) | YES | | NULL | |
| repeat(col_tinyblob, 3) | blob | YES | | NULL | |
| repeat(col_tinyblob, 257) | blob | YES | | NULL | |
| repeat(col_tinyblob, 258) | longblob | YES | | NULL | |
| repeat(col_mediumtext, 1) | longtext | YES | | NULL | |
| repeat(col_mediumblob, 1) | longblob | YES | | NULL | |
| repeat(col_text, 1) | text | YES | | NULL | |
| repeat(col_text, 2) | longtext | YES | | NULL | |
| repeat(col_blob, 1) | blob | YES | | NULL | |
| repeat(col_blob, 2) | longblob | YES | | NULL | |
| repeat('啊', col_count) | longtext | YES | | NULL | |
| repeat('a', col_count) | longtext | YES | | NULL | |
| repeat(col_varchar, col_count) | longtext | YES | | NULL | |
| repeat(col_varbinary, col_count) | longblob | YES | | NULL | |
| repeat(col_char, col_count) | longtext | YES | | NULL | |
| repeat(col_binary, col_count) | longblob | YES | | NULL | |
| repeat(col_tinytext, col_count) | longtext | YES | | NULL | |
| repeat(col_tinyblob, col_count) | longblob | YES | | NULL | |
| repeat(col_mediumtext, col_count) | longtext | YES | | NULL | |
| repeat(col_mediumblob, col_count) | longblob | YES | | NULL | |
| repeat(col_text, col_count) | longtext | YES | | NULL | |
| repeat(col_blob, col_count) | longblob | YES | | NULL | |
+-----------------------------------+----------------+------+-----+---------+-------+
46 rows in set (0.00 sec)
* summarize the rules that mysql decide the result type of some string functions,
* which mainly depend on the MAX CHAR LENGTH of result:
* 1. less than or equal to 512: varchar, otherwise
* 2. less than or equal to 65535: text or blob, otherwise
* 3. longtext or longblob (including UNKNOWN length when count param is not const).
* do not care about the input data type, or whether the input is column or const.
*
* ATTENTION! we will ignore these exceptions:
* 1. repeat('啊', 21845) => text, repeat('a', 21846) => longtext. we can not
* understand the magic numbers 21845 and 21846.
* 2. repeat(col_mediumtext, 1) => longtext, repeat(col_mediumblob, 1) => longblob.
* text or blob is enough, see:
* repeat(col_text, 1) => text, repeat(col_blob, 1) => blob.
*/
ObObjType res_type = ObMaxType;
if (char_length <= MAX_CHAR_LENGTH_FOR_VARCAHR_RESULT) {
@ -3954,6 +3886,8 @@ int ObMinMaxExprOperator::calc_with_cast(ObObj& result, const ObObj* objs_stack,
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE);
if (ob_is_nstring_type(result_type.get_calc_type())) {
cast_ctx.dest_collation_ = expr_ctx.my_session_->get_nls_collation_nation();
} else if (share::is_mysql_mode() && ob_is_json(result_type.get_calc_type())) {
cast_ctx.dest_collation_ = CS_TYPE_UTF8MB4_BIN;
} else if (share::is_mysql_mode() && CS_TYPE_INVALID != result_type.get_collation_type()) {
cast_ctx.dest_collation_ = result_type.get_collation_type();
}