bugfix cherry-pick to opensource release
This commit is contained in:
parent
601c09e290
commit
1ec7b00f36
@ -947,6 +947,31 @@ int ObAggregateProcessor::init_one_group(const int64_t group_id)
|
||||
eval_ctx_,
|
||||
need_rewind))) {
|
||||
LOG_WARN("init GroupConcatExtraResult failed", K(ret));
|
||||
} else if (aggr_info.separator_expr_ != NULL) {
|
||||
ObDatum* separator_result = NULL;
|
||||
if (OB_UNLIKELY(!aggr_info.separator_expr_->obj_meta_.is_string_type())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("expr node is null", K(ret), KPC(aggr_info.separator_expr_));
|
||||
} else if (OB_FAIL(aggr_info.separator_expr_->eval(eval_ctx_, separator_result))) {
|
||||
LOG_WARN("eval failed", K(ret));
|
||||
} else {
|
||||
// parse separator in prepare
|
||||
int64_t pos = sizeof(ObDatum);
|
||||
int64_t len = pos + (separator_result->null_ ? 0 : separator_result->len_);
|
||||
char* buf = (char*)aggr_alloc_.alloc(len);
|
||||
if (OB_ISNULL(buf)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fall to alloc buff", K(len), K(ret));
|
||||
} else {
|
||||
ObDatum** separator_datum = const_cast<ObDatum**>(&result->get_separator_datum());
|
||||
*separator_datum = new (buf) ObDatum;
|
||||
if (OB_FAIL((*separator_datum)->deep_copy(*separator_result, buf, len, pos))) {
|
||||
LOG_WARN("failed to deep copy datum", K(ret), K(pos), K(len));
|
||||
} else {
|
||||
LOG_DEBUG("succ to calc separator", K(ret), KP(*separator_datum));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1299,31 +1324,6 @@ int ObAggregateProcessor::prepare_aggr_result(const ObChunkDatumStore::StoredRow
|
||||
LOG_WARN("fail to add row", K(ret));
|
||||
} else if (param_exprs != NULL && OB_FAIL(extra->add_row(*param_exprs, eval_ctx_))) {
|
||||
LOG_WARN("fail to add row", K(ret));
|
||||
} else if (aggr_info.separator_expr_ != NULL) {
|
||||
ObDatum* separator_result = NULL;
|
||||
if (OB_UNLIKELY(!aggr_info.separator_expr_->obj_meta_.is_string_type())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("expr node is null", K(ret), KPC(aggr_info.separator_expr_));
|
||||
} else if (OB_FAIL(aggr_info.separator_expr_->eval(eval_ctx_, separator_result))) {
|
||||
LOG_WARN("eval failed", K(ret));
|
||||
} else {
|
||||
// parse separator in prepare
|
||||
int64_t pos = sizeof(ObDatum);
|
||||
int64_t len = pos + (separator_result->null_ ? 0 : separator_result->len_);
|
||||
char* buf = (char*)aggr_alloc_.alloc(len);
|
||||
if (OB_ISNULL(buf)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fall to alloc buff", K(len), K(ret));
|
||||
} else {
|
||||
ObDatum** separator_datum = const_cast<ObDatum**>(&aggr_info.separator_datum_);
|
||||
*separator_datum = new (buf) ObDatum;
|
||||
if (OB_FAIL((*separator_datum)->deep_copy(*separator_result, buf, len, pos))) {
|
||||
LOG_WARN("failed to deep copy datum", K(ret), K(pos), K(len));
|
||||
} else {
|
||||
LOG_DEBUG("succ to calc separator", K(ret), KP(*separator_datum));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_DEBUG("succ to add row", K(stored_row), KPC(extra));
|
||||
}
|
||||
@ -1699,11 +1699,11 @@ int ObAggregateProcessor::collect_aggr_result(AggrCell& aggr_cell, const ObExpr*
|
||||
LOG_WARN("finish_add_row failed", KPC(extra), K(ret));
|
||||
} else {
|
||||
if (aggr_info.separator_expr_ != NULL) {
|
||||
if (OB_ISNULL(aggr_info.separator_datum_)) {
|
||||
if (OB_ISNULL(extra->get_separator_datum())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("seperator is nullptr", K(ret));
|
||||
} else {
|
||||
sep_str = aggr_info.separator_datum_->get_string();
|
||||
sep_str = extra->get_separator_datum()->get_string();
|
||||
}
|
||||
} else {
|
||||
if (share::is_oracle_mode()) {
|
||||
|
@ -46,7 +46,6 @@ public:
|
||||
sort_collations_(),
|
||||
sort_cmp_funcs_(),
|
||||
separator_expr_(NULL),
|
||||
separator_datum_(nullptr),
|
||||
linear_inter_expr_(NULL)
|
||||
{}
|
||||
virtual ~ObAggrInfo();
|
||||
@ -98,7 +97,6 @@ public:
|
||||
ObSortCollations sort_collations_;
|
||||
ObSortFuncs sort_cmp_funcs_;
|
||||
ObExpr* separator_expr_;
|
||||
ObDatum* separator_datum_;
|
||||
|
||||
// used for median/percentile_cont aggr
|
||||
ObExpr* linear_inter_expr_;
|
||||
@ -160,7 +158,7 @@ public:
|
||||
class GroupConcatExtraResult : public ExtraResult {
|
||||
public:
|
||||
explicit GroupConcatExtraResult(common::ObIAllocator& alloc)
|
||||
: ExtraResult(alloc), row_count_(0), iter_idx_(0), sort_op_(NULL)
|
||||
: ExtraResult(alloc), row_count_(0), iter_idx_(0), sort_op_(NULL), separator_datum_(NULL)
|
||||
{}
|
||||
virtual ~GroupConcatExtraResult();
|
||||
void reuse_self();
|
||||
@ -208,6 +206,7 @@ public:
|
||||
{
|
||||
return row_count_;
|
||||
}
|
||||
ObDatum *&get_separator_datum() { return separator_datum_; }
|
||||
DECLARE_VIRTUAL_TO_STRING;
|
||||
|
||||
private:
|
||||
@ -218,6 +217,7 @@ public:
|
||||
ObChunkDatumStore::Iterator row_store_iter_;
|
||||
|
||||
ObSortOpImpl* sort_op_;
|
||||
ObDatum *separator_datum_;
|
||||
};
|
||||
|
||||
class AggrCell {
|
||||
|
@ -760,6 +760,9 @@ int ObExprLike::like_varchar(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_d
|
||||
escape_val.assign_ptr("\\", 1);
|
||||
} else {
|
||||
escape_val = escape.get_string();
|
||||
if (escape_val.empty()) {
|
||||
escape_val.assign_ptr("\\", 1);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (do_optimization && like_id != OB_INVALID_ID && (!text_val.empty()) && (!pattern_val.empty())) {
|
||||
|
@ -29,7 +29,22 @@ ObExprLog::ObExprLog(ObIAllocator& alloc) : ObExprOperator(alloc, T_FUN_SYS_LOG,
|
||||
int ObExprLog::calc_result_type2(
|
||||
ObExprResType& type, ObExprResType& type1, ObExprResType& type2, ObExprTypeCtx& type_ctx) const
|
||||
{
|
||||
return calc_trig_function_result_type2(type, type1, type2, type_ctx);
|
||||
int ret = OB_SUCCESS;
|
||||
if (lib::is_mysql_mode()) {
|
||||
if (NOT_ROW_DIMENSION != row_dimension_) {
|
||||
ret = OB_ERR_INVALID_TYPE_FOR_OP; // arithmetic not support row
|
||||
} else if (ObMaxType == type1.get_type() || ObMaxType == type2.get_type()) {
|
||||
ret = OB_ERR_INVALID_TYPE_FOR_OP;
|
||||
} else {
|
||||
type.set_double();
|
||||
type1.set_calc_type(type.get_type());
|
||||
type2.set_calc_type(type.get_type());
|
||||
ObExprOperator::calc_result_flag2(type, type1, type2);
|
||||
}
|
||||
} else if (OB_FAIL(calc_trig_function_result_type2(type, type1, type2, type_ctx))) {
|
||||
LOG_WARN("failed to calc_trig_function_result_type2", K(ret));
|
||||
} else {/*do nothing*/}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprLog::calc_result2(ObObj& result, const ObObj& obj1, const ObObj& obj2, ObExprCtx& expr_ctx) const
|
||||
@ -55,12 +70,26 @@ int ObExprLog::calc_result2(ObObj& result, const ObObj& obj1, const ObObj& obj2,
|
||||
// binary_double, result type is double
|
||||
double double_base = obj1.get_double();
|
||||
double double_x = obj2.get_double();
|
||||
double result_double = std::log(double_x) / std::log(double_base);
|
||||
if (isinf(result_double) || isnan(result_double)) {
|
||||
ret = OB_OPERATE_OVERFLOW;
|
||||
if (lib::is_mysql_mode() && (double_base <= 0 || double_x <= 0)) {
|
||||
LOG_USER_WARN(OB_EER_INVALID_ARGUMENT_FOR_LOGARITHM);
|
||||
result.set_null();
|
||||
} else {
|
||||
result.set_double(result_double);
|
||||
double result_double = std::log(double_x) / std::log(double_base);
|
||||
if (isinf(result_double) || isnan(result_double)) {
|
||||
if (lib::is_mysql_mode()) {
|
||||
LOG_USER_WARN(OB_EER_INVALID_ARGUMENT_FOR_LOGARITHM);
|
||||
result.set_null();
|
||||
} else {
|
||||
ret = OB_OPERATE_OVERFLOW;
|
||||
}
|
||||
} else {
|
||||
result.set_double(result_double);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get invalid calc type, expected number/double", K(get_type_name(obj1.get_type())),
|
||||
K(get_type_name(obj2.get_type())), K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -74,8 +103,18 @@ int calc_log_expr_double(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& res_datum)
|
||||
LOG_WARN("eval arg failed", K(ret), K(expr));
|
||||
} else if (base->is_null() || x->is_null()) {
|
||||
res_datum.set_null();
|
||||
} else if (OB_FAIL(ObExprPow::safe_set_double(res_datum, std::log(x->get_double()) / std::log(base->get_double())))) {
|
||||
LOG_WARN("set double failed", K(ret), K(base->get_double()), K(x->get_double()));
|
||||
} else if (lib::is_mysql_mode() && (x->get_double() <= 0 || base->get_double() <= 0)) {
|
||||
LOG_USER_WARN(OB_EER_INVALID_ARGUMENT_FOR_LOGARITHM);
|
||||
res_datum.set_null();
|
||||
} else if (OB_FAIL(ObExprPow::safe_set_double(res_datum,
|
||||
std::log(x->get_double()) / std::log(base->get_double())))) {
|
||||
if (lib::is_mysql_mode() && OB_OPERATE_OVERFLOW == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
LOG_USER_WARN(OB_EER_INVALID_ARGUMENT_FOR_LOGARITHM);
|
||||
res_datum.set_null();
|
||||
} else {
|
||||
LOG_WARN("set double failed", K(ret), K(base->get_double()), K(x->get_double()));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -645,6 +645,7 @@ void ObExprOperatorFactory::register_expr_operators()
|
||||
REG_OP(ObExprAtan2);
|
||||
REG_OP(ObExprToOutfileRow);
|
||||
REG_OP(ObExprFormat);
|
||||
REG_OP(ObExprLog);
|
||||
// register oracle system function
|
||||
REG_OP_ORCL(ObExprSysConnectByPath);
|
||||
REG_OP_ORCL(ObExprTimestampNvl);
|
||||
|
@ -30,3 +30,4 @@ flex -Cfa -B -8 -o ../../../src/sql/parser/sql_parser_mysql_mode_lex.c ../../../
|
||||
sed "/Setup the input buffer state to scan the given bytes/,/}/{/int i/d}" -i sql_parser_mysql_mode_lex.c
|
||||
sed "/Setup the input buffer state to scan the given bytes/,/}/{/for ( i = 0; i < _yybytes_len; ++i )/d}" -i sql_parser_mysql_mode_lex.c
|
||||
sed "/Setup the input buffer state to scan the given bytes/,/}/{s/\tbuf\[i\] = yybytes\[i\]/memcpy(buf, yybytes, _yybytes_len)/g}" -i sql_parser_mysql_mode_lex.c
|
||||
sed "/YY_EXIT_FAILURE/,/}/{s/yyconst char\* msg , yyscan_t yyscanner/yyconst char* msg , yyscan_t yyscanner __attribute__((unused))/g}" -i sql_parser_mysql_mode_lex.c
|
@ -262,6 +262,7 @@ static const NonReservedKeyword Mysql_none_reserved_keywords[] = {{"access", ACC
|
||||
{"linestring", LINESTRING},
|
||||
{"list", LIST_},
|
||||
{"listagg", LISTAGG},
|
||||
{"ln", LN},
|
||||
{"local", LOCAL},
|
||||
{"locality", LOCALITY},
|
||||
{"location", LOCATION},
|
||||
@ -269,6 +270,7 @@ static const NonReservedKeyword Mysql_none_reserved_keywords[] = {{"access", ACC
|
||||
{"locks", LOCKS},
|
||||
{"logfile", LOGFILE},
|
||||
{"logonly_replica_num", LOGONLY_REPLICA_NUM},
|
||||
{"log", LOG},
|
||||
{"logs", LOGS},
|
||||
{"major", MAJOR},
|
||||
{"manual", MANUAL},
|
||||
|
@ -1085,6 +1085,7 @@ typedef enum ObItemType {
|
||||
|
||||
T_SFU_INT,
|
||||
T_SFU_DECIMAL,
|
||||
T_SFU_DOUBLE,
|
||||
T_FOR_UPDATE,
|
||||
T_DEFAULT_INT,
|
||||
T_DEFAULT_NULL,
|
||||
|
@ -54,8 +54,8 @@ bool ObParser::is_single_stmt(const ObString& stmt)
|
||||
|
||||
// In multi-stmt mode(delimiter #) eg: create t1; create t2; create t3
|
||||
// in the case of is_ret_first_stmt(false), queries will return the following stmts:
|
||||
// queries[0]: create t1; create t2; create t3;
|
||||
// queries[1]: create t2; create t3;
|
||||
// queries[0]: create t1;
|
||||
// queries[1]: create t2;
|
||||
// queries[2]: create t3;
|
||||
// in the case of is_ret_first_stmt(true) and it will return one element
|
||||
// queries[0]: create t1;
|
||||
@ -92,39 +92,45 @@ int ObParser::split_multiple_stmt(
|
||||
}
|
||||
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
while (remain > 0 && OB_SUCC(ret) && !parse_stat.parse_fail_) {
|
||||
bool need_continue = true;
|
||||
while (remain > 0 && OB_SUCC(ret) && !parse_stat.parse_fail_ && need_continue) {
|
||||
ObArenaAllocator allocator(CURRENT_CONTEXT.get_malloc_allocator());
|
||||
allocator.set_label("SplitMultiStmt");
|
||||
ObIAllocator* bak_allocator = allocator_;
|
||||
allocator_ = &allocator;
|
||||
ObString part(remain, stmt.ptr() + offset);
|
||||
if (OB_SUCC(tmp_ret = parse(part, parse_result, parse_mode))) {
|
||||
// length: length of the remainer statements
|
||||
// size: length of the single statement
|
||||
int64_t str_len = 0;
|
||||
//for save memory allocate in parser, we need try find the single stmt length in advance
|
||||
while (stmt[str_len + offset] != ';' && str_len < remain) {
|
||||
++ str_len;
|
||||
}
|
||||
str_len = str_len == remain ? str_len : str_len + 1;
|
||||
ObString part(str_len, stmt.ptr() + offset);
|
||||
ObString remain_part(remain, stmt.ptr() + offset);
|
||||
//first try parse part str, because it's have less length and need less memory
|
||||
if (OB_FAIL(tmp_ret = parse(part, parse_result, parse_mode))) {
|
||||
//if parser part str failed, then try parse all remain part, avoid parse many times:
|
||||
//bug: https://work.aone.alibaba-inc.com/issue/34642901
|
||||
tmp_ret = OB_SUCCESS;
|
||||
tmp_ret = parse(remain_part, parse_result, parse_mode);
|
||||
}
|
||||
if (OB_SUCC(tmp_ret)) {
|
||||
int32_t single_stmt_length = parse_result.end_col_;
|
||||
if ((!is_ret_first_stmt) && (';' == *(stmt.ptr() + offset + parse_result.end_col_ - 1))) {
|
||||
--single_stmt_length;
|
||||
}
|
||||
|
||||
if (is_ret_first_stmt) {
|
||||
ObString first_query(single_stmt_length, stmt.ptr());
|
||||
ret = queries.push_back(first_query);
|
||||
break; // only return the first stmt, so ignore the remaining stmts
|
||||
need_continue = false; // only return the first stmt, so ignore the remaining stmts
|
||||
} else {
|
||||
ObString query(single_stmt_length, static_cast<int32_t>(remain), stmt.ptr() + offset);
|
||||
ObString query(single_stmt_length,stmt.ptr() + offset);
|
||||
ret = queries.push_back(query);
|
||||
}
|
||||
remain -= parse_result.end_col_;
|
||||
offset += parse_result.end_col_;
|
||||
if (remain < 0 || offset > stmt.length()) {
|
||||
LOG_ERROR("split_multiple_stmt data error", K(remain), K(offset), K(stmt.length()), K(ret));
|
||||
LOG_ERROR("split_multiple_stmt data error",
|
||||
K(remain), K(offset), K(stmt.length()), K(ret));
|
||||
}
|
||||
} else {
|
||||
int32_t single_stmt_length = parse_result.end_col_;
|
||||
if (';' == *(stmt.ptr() + offset + parse_result.end_col_ - 1)) {
|
||||
--single_stmt_length;
|
||||
}
|
||||
ObString query(single_stmt_length, static_cast<int32_t>(remain), stmt.ptr() + offset);
|
||||
ObString query(static_cast<int32_t>(remain), stmt.ptr() + offset);
|
||||
ret = queries.push_back(query);
|
||||
if (OB_SUCCESS == ret) {
|
||||
parse_stat.parse_fail_ = true;
|
||||
|
@ -96,7 +96,8 @@
|
||||
%left AND AND_OP
|
||||
%left BETWEEN CASE WHEN THEN ELSE
|
||||
%nonassoc LOWER_THAN_COMP
|
||||
%left COMP_EQ COMP_NSEQ COMP_GE COMP_GT COMP_LE COMP_LT COMP_NE IS LIKE IN REGEXP
|
||||
%left COMP_EQ COM P_NSEQ COMP_GE COMP_GT COMP_LE COMP_LT COMP_NE IS LIKE IN REGEXP
|
||||
%nonassoc STRING_VALUE
|
||||
%right ESCAPE /*for conflict for escape*/
|
||||
%left '|'
|
||||
%left '&'
|
||||
@ -108,8 +109,9 @@
|
||||
%left CNNOP
|
||||
%left NEG '~'
|
||||
%nonassoc LOWER_PARENS
|
||||
//%nonassoc STRING_VALUE
|
||||
%left '(' ')'
|
||||
%nonassoc HIGHER_PARENS TRANSACTION/*for simple_expr conflict*/
|
||||
%nonassoc HIGHER_PARENS TRANSACTION /*for simple_expr conflict*/
|
||||
%left '.'
|
||||
%right NOT NOT2
|
||||
%right BINARY COLLATE
|
||||
@ -232,7 +234,7 @@ END_P SET_VAR DELIMITER
|
||||
|
||||
LAG LANGUAGE LAST LAST_VALUE LEAD LEADER LEAVES LESS LEAK LEAK_MOD LEAK_RATE LINESTRING LIST_
|
||||
LISTAGG LOCAL LOCALITY LOCATION LOCKED LOCKS LOGFILE LOGONLY_REPLICA_NUM LOGS LOCK_ LOGICAL_READS
|
||||
LEVEL
|
||||
LEVEL LN LOG
|
||||
|
||||
MAJOR MANUAL MASTER MASTER_AUTO_POSITION MASTER_CONNECT_RETRY MASTER_DELAY MASTER_HEARTBEAT_PERIOD
|
||||
MASTER_HOST MASTER_LOG_FILE MASTER_LOG_POS MASTER_PASSWORD MASTER_PORT MASTER_RETRY_COUNT
|
||||
@ -397,14 +399,14 @@ END_P SET_VAR DELIMITER
|
||||
%type <node> opt_index_name opt_key_or_index opt_index_options opt_primary opt_all
|
||||
%type <node> charset_key database_key charset_name charset_name_or_default collation_name databases_or_schemas trans_param_name trans_param_value
|
||||
%type <node> set_names_stmt set_charset_stmt
|
||||
%type <node> charset_introducer opt_charset_introducer complex_string_literal literal number_literal now_or_signed_literal signed_literal
|
||||
%type <node> charset_introducer complex_string_literal literal number_literal now_or_signed_literal signed_literal
|
||||
%type <node> create_tablegroup_stmt drop_tablegroup_stmt alter_tablegroup_stmt default_tablegroup
|
||||
%type <node> set_transaction_stmt transaction_characteristics transaction_access_mode isolation_level
|
||||
%type <node> lock_tables_stmt unlock_tables_stmt lock_type lock_table_list lock_table opt_local
|
||||
%type <node> purge_stmt
|
||||
%type <node> tenant_name_list opt_tenant_list tenant_list_tuple cache_type flush_scope opt_zone_list
|
||||
%type <node> into_opt into_clause field_opt field_term field_term_list line_opt line_term line_term_list into_var_list into_var
|
||||
%type <node> string_list text_string
|
||||
%type <node> string_list text_string string_val_list
|
||||
%type <node> balance_task_type opt_balance_task_type
|
||||
%type <node> list_expr list_partition_element list_partition_expr list_partition_list list_partition_option opt_list_partition_list opt_list_subpartition_list list_subpartition_list list_subpartition_element drop_partition_name_list
|
||||
%type <node> primary_zone_name locality_name change_tenant_name_or_tenant_id distribute_method opt_distribute_method
|
||||
@ -711,30 +713,25 @@ column_name
|
||||
}
|
||||
;
|
||||
|
||||
opt_charset_introducer:
|
||||
/*empty*/
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| charset_introducer
|
||||
{
|
||||
$$ = $1;
|
||||
};
|
||||
|
||||
/* literal string with */
|
||||
complex_string_literal:
|
||||
opt_charset_introducer STRING_VALUE
|
||||
STRING_VALUE %prec LOWER_THAN_COMP
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_VARCHAR, 2, NULL, $1);
|
||||
$$->str_value_ = $1->str_value_;
|
||||
$$->str_len_ = $1->str_len_;
|
||||
$$->raw_text_ = $1->raw_text_;
|
||||
$$->text_len_ = $1->text_len_;
|
||||
@$.first_column = @1.first_column;
|
||||
@$.last_column = @1.last_column;
|
||||
}
|
||||
| charset_introducer STRING_VALUE
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_VARCHAR, 2, $1, $2);
|
||||
$$->str_value_ = $2->str_value_;
|
||||
$$->str_len_ = $2->str_len_;
|
||||
$$->raw_text_ = $2->raw_text_;
|
||||
$$->text_len_ = $2->text_len_;
|
||||
if (NULL == $1)
|
||||
{
|
||||
@$.first_column = @2.first_column;
|
||||
@$.last_column = @2.last_column;
|
||||
}
|
||||
}
|
||||
| charset_introducer HEX_STRING_VALUE
|
||||
{
|
||||
@ -1013,7 +1010,19 @@ bit_expr IN in_expr
|
||||
//In the resolver, if only two children are found, the escape parameter will be set to '\'
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_LIKE, 2, $1, $3);
|
||||
}
|
||||
| bit_expr LIKE simple_expr ESCAPE simple_expr %prec LIKE
|
||||
| bit_expr LIKE STRING_VALUE string_val_list %prec LOWER_THAN_COMP
|
||||
{
|
||||
//在resolver时,如果发现只有两个children,会将escape 参数设置为‘\’
|
||||
ParseNode *str_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $3, $4);
|
||||
ParseNode *string_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, string_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_LIKE, 2, $1, concat_node);
|
||||
}
|
||||
| bit_expr LIKE simple_expr ESCAPE simple_expr %prec LIKE
|
||||
{
|
||||
// If escape is an empty string '', the default value'\' is used
|
||||
if (OB_UNLIKELY(T_VARCHAR == $5->type_ && 0 == $5->str_len_)) {
|
||||
@ -1026,12 +1035,74 @@ bit_expr IN in_expr
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_LIKE, 3, $1, $3, $5);
|
||||
}
|
||||
}
|
||||
| bit_expr LIKE STRING_VALUE string_val_list ESCAPE simple_expr %prec LIKE
|
||||
{
|
||||
// 如果escape 为空串 '', 则使用默认值'\'
|
||||
ParseNode *str_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $3, $4);
|
||||
ParseNode *string_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, string_list_node);
|
||||
if (OB_UNLIKELY(T_VARCHAR == $6->type_ && 0 == $6->str_len_)) {
|
||||
ParseNode *node = NULL;
|
||||
malloc_terminal_node(node, result->malloc_pool_, T_VARCHAR);
|
||||
node->str_value_ = "\\";
|
||||
node->str_len_ = 1;
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_LIKE, 3, $1, concat_node, node);
|
||||
} else {
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_LIKE, 3, $1, concat_node, $6);
|
||||
}
|
||||
}
|
||||
| bit_expr LIKE simple_expr ESCAPE STRING_VALUE string_val_list %prec LIKE
|
||||
{
|
||||
ParseNode *escape_node = NULL;
|
||||
malloc_non_terminal_node(escape_node, result->malloc_pool_, T_LINK_NODE, 2, $5, $6);
|
||||
ParseNode *escape_list_node = NULL;
|
||||
merge_nodes(escape_list_node, result, T_EXPR_LIST, escape_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, escape_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_LIKE, 3, $1, $3, concat_node);
|
||||
}
|
||||
| bit_expr LIKE STRING_VALUE string_val_list ESCAPE STRING_VALUE string_val_list %prec LIKE
|
||||
{
|
||||
ParseNode *str_node = NULL;
|
||||
ParseNode *escape_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $3, $4);
|
||||
malloc_non_terminal_node(escape_node, result->malloc_pool_, T_LINK_NODE, 2, $6, $7);
|
||||
ParseNode *string_list_node = NULL;
|
||||
ParseNode *escape_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
merge_nodes(escape_list_node, result, T_EXPR_LIST, escape_node);
|
||||
ParseNode *concat_node1 = NULL;
|
||||
ParseNode *concat_node2 = NULL;
|
||||
make_name_node(concat_node1, result->malloc_pool_, "concat");
|
||||
make_name_node(concat_node2, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node1, result->malloc_pool_, T_FUN_SYS, 2, concat_node1, string_list_node);
|
||||
malloc_non_terminal_node(concat_node2, result->malloc_pool_, T_FUN_SYS, 2, concat_node2, escape_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_LIKE, 3, $1, concat_node1, concat_node2);
|
||||
}
|
||||
| bit_expr not LIKE simple_expr
|
||||
{
|
||||
(void)($2);
|
||||
//In the resolver, if only two children are found, the escape parameter will be set to '\'
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_LIKE, 2, $1, $4);
|
||||
}
|
||||
| bit_expr not LIKE STRING_VALUE string_val_list %prec LOWER_THAN_COMP
|
||||
{
|
||||
(void)($2);
|
||||
//在resolver时,如果发现只有两个children,会将escape 参数设置为‘\’
|
||||
ParseNode *str_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $4, $5);
|
||||
ParseNode *string_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, string_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_LIKE, 2, $1, concat_node);
|
||||
}
|
||||
| bit_expr not LIKE simple_expr ESCAPE simple_expr %prec LIKE
|
||||
{
|
||||
(void)($2);
|
||||
@ -1046,19 +1117,104 @@ bit_expr IN in_expr
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_LIKE, 3, $1, $4, $6);
|
||||
}
|
||||
}
|
||||
| bit_expr not LIKE STRING_VALUE string_val_list ESCAPE simple_expr %prec LIKE
|
||||
{
|
||||
(void)($2);
|
||||
ParseNode *str_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $4, $5);
|
||||
ParseNode *string_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, string_list_node);
|
||||
// 如果escape 为空串 '', 则使用默认值'\'
|
||||
if (OB_UNLIKELY(T_VARCHAR == $7->type_ && 0 == $7->str_len_)) {
|
||||
ParseNode *node = NULL;
|
||||
malloc_terminal_node(node, result->malloc_pool_, T_VARCHAR);
|
||||
node->str_value_ = "\\";
|
||||
node->str_len_ = 1;
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_LIKE, 3, $1, concat_node, node);
|
||||
} else {
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_LIKE, 3, $1, concat_node, $7);
|
||||
}
|
||||
}
|
||||
| bit_expr not LIKE simple_expr ESCAPE STRING_VALUE string_val_list %prec LIKE
|
||||
{
|
||||
(void)($2);
|
||||
ParseNode *escape_node = NULL;
|
||||
malloc_non_terminal_node(escape_node, result->malloc_pool_, T_LINK_NODE, 2, $6, $7);
|
||||
ParseNode *escape_list_node = NULL;
|
||||
merge_nodes(escape_list_node, result, T_EXPR_LIST, escape_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, escape_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_LIKE, 3, $1, $4, concat_node);
|
||||
}
|
||||
| bit_expr not LIKE STRING_VALUE string_val_list ESCAPE STRING_VALUE string_val_list %prec LIKE
|
||||
{
|
||||
(void)($2);
|
||||
ParseNode *str_node = NULL;
|
||||
ParseNode *escape_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $4, $5);
|
||||
malloc_non_terminal_node(escape_node, result->malloc_pool_, T_LINK_NODE, 2, $7, $8);
|
||||
ParseNode *string_list_node = NULL;
|
||||
ParseNode *escape_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
merge_nodes(escape_list_node, result, T_EXPR_LIST, escape_node);
|
||||
ParseNode *concat_node1 = NULL;
|
||||
ParseNode *concat_node2 = NULL;
|
||||
make_name_node(concat_node1, result->malloc_pool_, "concat");
|
||||
make_name_node(concat_node2, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node1, result->malloc_pool_, T_FUN_SYS, 2, concat_node1, string_list_node);
|
||||
malloc_non_terminal_node(concat_node2, result->malloc_pool_, T_FUN_SYS, 2, concat_node2, escape_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_LIKE, 3, $1, concat_node1, concat_node2);
|
||||
}
|
||||
| bit_expr REGEXP bit_expr
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_REGEXP, 2, $1, $3);
|
||||
}
|
||||
| bit_expr REGEXP STRING_VALUE string_val_list %prec LOWER_THAN_COMP
|
||||
{
|
||||
ParseNode *str_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $3, $4);
|
||||
ParseNode *string_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, string_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_REGEXP, 2, $1, concat_node);
|
||||
}
|
||||
| bit_expr not REGEXP bit_expr
|
||||
{
|
||||
(void)($2);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_REGEXP, 2, $1, $4);
|
||||
}
|
||||
| bit_expr not REGEXP STRING_VALUE string_val_list %prec LOWER_THAN_COMP
|
||||
{
|
||||
(void)($2);
|
||||
ParseNode *str_node = NULL;
|
||||
malloc_non_terminal_node(str_node, result->malloc_pool_, T_LINK_NODE, 2, $4, $5);
|
||||
ParseNode *string_list_node = NULL;
|
||||
merge_nodes(string_list_node, result, T_EXPR_LIST, str_node);
|
||||
ParseNode *concat_node = NULL;
|
||||
make_name_node(concat_node, result->malloc_pool_, "concat");
|
||||
malloc_non_terminal_node(concat_node, result->malloc_pool_, T_FUN_SYS, 2, concat_node, string_list_node);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_OP_NOT_REGEXP, 2, $1, concat_node);
|
||||
}
|
||||
| bit_expr %prec LOWER_THAN_COMP
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
string_val_list:
|
||||
STRING_VALUE
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| string_val_list STRING_VALUE
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, $1, $2);
|
||||
};
|
||||
|
||||
bit_expr:
|
||||
bit_expr '|' bit_expr %prec '|'
|
||||
{
|
||||
@ -2231,6 +2387,47 @@ MOD '(' expr ',' expr ')'
|
||||
make_name_node($$, result->malloc_pool_, "char");
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_SYS, 2, $$, params_node);
|
||||
}
|
||||
| LOG '(' expr ',' expr ')'
|
||||
{
|
||||
ParseNode *params = NULL;
|
||||
malloc_non_terminal_node(params, result->malloc_pool_, T_EXPR_LIST, 2, $3, $5);
|
||||
make_name_node($$, result->malloc_pool_, "log");
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_SYS, 2, $$, params);
|
||||
}
|
||||
| LOG '(' expr ')'
|
||||
{
|
||||
ParseNode *param_node = NULL;
|
||||
malloc_terminal_node(param_node, result->malloc_pool_, T_SFU_DOUBLE);
|
||||
int64_t len = strlen("2.718281828459045");
|
||||
param_node->str_value_ = parse_strndup("2.718281828459045", len, result->malloc_pool_);
|
||||
if (OB_UNLIKELY(NULL == param_node->str_value_)) {
|
||||
yyerror(NULL, result, "No more space for mallocing string\n");
|
||||
YYABORT_NO_MEMORY;
|
||||
}
|
||||
param_node->str_len_ = len;
|
||||
ParseNode *param_list_node = NULL;
|
||||
malloc_non_terminal_node(param_list_node, result->malloc_pool_, T_LINK_NODE, 2, param_node, $3);
|
||||
merge_nodes(param_list_node, result, T_EXPR_LIST, param_list_node);
|
||||
make_name_node($$, result->malloc_pool_, "log");
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_SYS, 2, $$, param_list_node);
|
||||
}
|
||||
| LN '(' expr ')'
|
||||
{
|
||||
ParseNode *param_node = NULL;
|
||||
malloc_terminal_node(param_node, result->malloc_pool_, T_SFU_DOUBLE);
|
||||
int64_t len = strlen("2.718281828459045");
|
||||
param_node->str_value_ = parse_strndup("2.718281828459045", len, result->malloc_pool_);
|
||||
if (OB_UNLIKELY(NULL == param_node->str_value_)) {
|
||||
yyerror(NULL, result, "No more space for mallocing string\n");
|
||||
YYABORT_NO_MEMORY;
|
||||
}
|
||||
param_node->str_len_ = len;
|
||||
ParseNode *param_list_node = NULL;
|
||||
malloc_non_terminal_node(param_list_node, result->malloc_pool_, T_LINK_NODE, 2, param_node, $3);
|
||||
merge_nodes(param_list_node, result, T_EXPR_LIST, param_list_node);
|
||||
make_name_node($$, result->malloc_pool_, "log");
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_SYS, 2, $$, param_list_node);
|
||||
}
|
||||
| function_name '(' opt_expr_as_list ')'
|
||||
{
|
||||
if (NULL != $3)
|
||||
@ -12611,10 +12808,12 @@ ACCOUNT
|
||||
| LINESTRING
|
||||
| LIST_
|
||||
| LISTAGG
|
||||
| LN
|
||||
| LOCAL
|
||||
| LOCALITY
|
||||
| LOCKED
|
||||
| LOCKS
|
||||
| LOG
|
||||
| LOGFILE
|
||||
| LOGONLY_REPLICA_NUM
|
||||
| LOGS
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -269,7 +269,9 @@ bool ObSqlParameterization::is_tree_not_param(const ParseNode* tree)
|
||||
ret_bool = true;
|
||||
} else if (T_FUN_SYS_CUR_DATE == tree->type_) {
|
||||
ret_bool = true;
|
||||
} else if (T_SFU_INT == tree->type_ || T_SFU_DECIMAL == tree->type_) {
|
||||
} else if (T_SFU_INT == tree->type_ ||
|
||||
T_SFU_DECIMAL == tree->type_ ||
|
||||
T_SFU_DOUBLE == tree->type_) {
|
||||
ret_bool = true;
|
||||
} else if (T_CYCLE_NODE == tree->type_) {
|
||||
ret_bool = true;
|
||||
|
@ -250,6 +250,14 @@ int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode* node, ObRawExpr
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_SFU_DOUBLE: {
|
||||
ParseNode *tmp_node = const_cast<ParseNode *>(node);
|
||||
tmp_node->type_ = T_DOUBLE;
|
||||
if (OB_FAIL(process_datatype_or_questionmark(*tmp_node, expr))) {
|
||||
LOG_WARN("fail to process datetype or questionmark", K(ret), K(tmp_node));
|
||||
} else {/*do nothing*/}
|
||||
break;
|
||||
}
|
||||
case T_CAST_ARGUMENT: {
|
||||
ObConstRawExpr* c_expr = NULL;
|
||||
if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_INT, c_expr))) {
|
||||
|
@ -4152,6 +4152,8 @@ int ObQueryRange::get_like_range(
|
||||
}
|
||||
} else if (OB_FAIL(escape.get_string(escape_str))) {
|
||||
LOG_WARN("failed to get escape string", K(escape), K(ret));
|
||||
} else if (escape_str.empty()) {
|
||||
escape_str.assign_ptr("\\", 1);
|
||||
} else { /* do nothing */
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user