diff --git a/src/sql/engine/expr/ob_expr_json_value.cpp b/src/sql/engine/expr/ob_expr_json_value.cpp index e627754008..b0c56039e1 100644 --- a/src/sql/engine/expr/ob_expr_json_value.cpp +++ b/src/sql/engine/expr/ob_expr_json_value.cpp @@ -1516,7 +1516,11 @@ int ObExprJsonValue::cast_to_res(common::ObIAllocator *allocator, ret = cast_to_otimstamp(j_base, session, accuracy, dst_type, val, is_type_cast); } if (!try_set_error_val(expr, ctx, res, ret, error_type, error_val, mismatch_val, mismatch_type, is_type_cast, accuracy, dst_type)) { - res.set_otimestamp_tiny(val); + if (dst_type == ObTimestampTZType) { + res.set_otimestamp_tz(val); + } else { + res.set_otimestamp_tiny(val); + } } break; } diff --git a/src/sql/parser/ob_fast_parser.cpp b/src/sql/parser/ob_fast_parser.cpp index 4a0aecce0a..800993f19c 100644 --- a/src/sql/parser/ob_fast_parser.cpp +++ b/src/sql/parser/ob_fast_parser.cpp @@ -2587,6 +2587,8 @@ int ObFastParserOracle::process_identifier(bool is_number_begin) int ObFastParserOracle::parse_next_token() { int ret = OB_SUCCESS; + char last_ch; + last_ch = '0'; while (OB_SUCC(ret) && !raw_sql_.is_search_end()) { process_leading_space(); char ch = raw_sql_.char_at(raw_sql_.cur_pos_); @@ -2659,7 +2661,7 @@ int ObFastParserOracle::parse_next_token() break; } case ':': { - if (-1 != is_first_identifier_flags(raw_sql_.cur_pos_ + 1) || is_digit(raw_sql_.peek())) { + if ((-1 != is_first_identifier_flags(raw_sql_.cur_pos_ + 1) || is_digit(raw_sql_.peek())) && last_ch != '\'') { raw_sql_.scan(); OZ (process_ps_statement()); } else { @@ -2701,6 +2703,7 @@ int ObFastParserOracle::parse_next_token() break; } } // end switch + last_ch = ch; OX (process_token()); } // end while if (OB_SUCC(ret)) { diff --git a/src/sql/parser/sql_parser_base.h b/src/sql/parser/sql_parser_base.h index 65d9b4c139..f0e15df8ca 100644 --- a/src/sql/parser/sql_parser_base.h +++ b/src/sql/parser/sql_parser_base.h @@ -526,6 +526,69 @@ do { #define malloc_time_node_s(malloc_pool, type) malloc_time_node(malloc_pool, type, '\''); #define malloc_time_node_d(malloc_pool, type) malloc_time_node(malloc_pool, type, '\"'); +// special case json object ( key :ident/intnum) +#define malloc_object_key_node(malloc_pool) \ +do { \ + ParseNode *key_node = NULL; \ + malloc_new_node(key_node, malloc_pool, T_CHAR, 0); \ + char *begin_k = strchr(yytext, '\''); \ + check_value(begin_k); \ + char *end_k = strchr(begin_k + 1, '\''); \ + check_value(end_k); \ + char *dest = NULL; \ + size_t len = end_k - begin_k - 1; \ + dest = parse_strndup(begin_k + 1, len, malloc_pool); \ + check_malloc(dest); \ + key_node->str_value_ = dest; \ + key_node->str_len_ = len; \ + char *raw_dest = NULL; \ + raw_dest = parse_strndup(begin_k + 1, len, malloc_pool); \ + check_malloc(raw_dest); \ + key_node->str_value_ = raw_dest; \ + key_node->str_len_ = len; \ + ParseNode *object_node = NULL; \ + malloc_new_node(object_node, malloc_pool, T_LINK_NODE, 2); \ + object_node->children_[0] = key_node; \ + check_value(yylval); \ + yylval->node = object_node; \ +} while (0); + +#define malloc_key_colon_ident_value_node(malloc_pool) \ +do { \ + malloc_object_key_node(malloc_pool); \ + ParseNode *value_node = NULL; \ + malloc_new_node(value_node, malloc_pool, T_IDENT, 0); \ + char *begin_v = strchr(yytext, ':'); \ + check_value(begin_v); \ + size_t end_v = strlen(begin_v); \ + size_t len_v = end_v - 1; \ + char *dest_v = NULL; \ + dest_v = parse_strndup(begin_v + 1, len_v, malloc_pool); \ + check_malloc(dest_v); \ + value_node->str_len_ = len_v; \ + value_node->str_value_ = dest_v; \ + yylval->node->children_[1] = value_node; \ + check_value(yylval); \ +} while (0); + +#define malloc_key_colon_intnum_value_node(malloc_pool) \ +do { \ + malloc_object_key_node(malloc_pool); \ + ParseNode *value_node = NULL; \ + malloc_new_node(value_node, malloc_pool, T_INT, 0); \ + char *begin_v = strchr(yytext, ':'); \ + check_value(begin_v); \ + size_t end_v = strlen(begin_v); \ + size_t len_v = end_v - 1; \ + char *dest_v = NULL; \ + dest_v = parse_strndup(begin_v + 1, len_v, malloc_pool); \ + check_malloc(dest_v); \ + value_node->str_len_ = len_v; \ + value_node->str_value_ = dest_v; \ + yylval->node->children_[1] = value_node; \ + check_value(yylval); \ +} while (0); + #define check_value(val_ptr) \ do { \ if (OB_UNLIKELY(NULL == val_ptr)) \