support json type
This commit is contained in:
@ -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 ¶m, ObItemType ¶m_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 ¶m, 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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user