diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index eff202dcbb..0caf2c538d 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -2477,13 +2477,10 @@ int ObPLResolver::adjust_routine_param_type(ObPLDataType &type) } break; case ObIntervalTC: { if (data_type.get_meta_type().is_interval_ym()) { - data_type.set_scale(default_accuracy.get_scale()); + ObScale scale = ObIntervalScaleUtil::interval_ym_scale_to_ob_scale(9); + data_type.set_scale(scale); } else { - int8_t day_scale = ObIntervalScaleUtil::ob_scale_to_interval_ds_day_scale( - static_cast(default_accuracy.get_scale())); - int8_t fs_scale = ObIntervalScaleUtil::ob_scale_to_interval_ds_second_scale( - static_cast(default_accuracy.get_scale())); - ObScale scale = ObIntervalScaleUtil::interval_ds_scale_to_ob_scale(day_scale, fs_scale); + ObScale scale = ObIntervalScaleUtil::interval_ds_scale_to_ob_scale(9, 9); data_type.set_scale(scale); } } break; diff --git a/src/sql/code_generator/ob_expr_generator_impl.cpp b/src/sql/code_generator/ob_expr_generator_impl.cpp index d32eae39a4..387978453e 100644 --- a/src/sql/code_generator/ob_expr_generator_impl.cpp +++ b/src/sql/code_generator/ob_expr_generator_impl.cpp @@ -1481,6 +1481,7 @@ int ObExprGeneratorImpl::visit_pl_assoc_index_expr(ObOpRawExpr &expr, pl_assoc_index->set_row_dimension(ObExprOperator::NOT_ROW_DIMENSION); pl_assoc_index->set_out_of_range_set_err(assoc_index_expr.get_out_of_range_set_err()); pl_assoc_index->set_parent_expr_type(assoc_index_expr.get_parent_type()); + pl_assoc_index->set_is_index_by_varchar(assoc_index_expr.is_index_by_varchar()); } return ret; } diff --git a/src/sql/engine/expr/ob_expr_obj_access.cpp b/src/sql/engine/expr/ob_expr_obj_access.cpp index 4fe94c81cc..2d6f5604b0 100644 --- a/src/sql/engine/expr/ob_expr_obj_access.cpp +++ b/src/sql/engine/expr/ob_expr_obj_access.cpp @@ -127,7 +127,7 @@ int ObExprObjAccess::assign(const ObExprOperator &other) return ret; } -#define GET_VALID_INT64_PARAM(obj) \ +#define GET_VALID_INT64_PARAM(obj, skip_check_error) \ do { \ if (OB_SUCC(ret)) { \ int64_t param_value = 0; \ @@ -144,9 +144,13 @@ int ObExprObjAccess::assign(const ObExprOperator &other) } \ } \ } else if (obj.is_null()) { \ - ret = OB_ERR_NUMERIC_OR_VALUE_ERROR; \ - LOG_WARN("ORA-06502: PL/SQL: numeric or value error: NULL index table key value",\ + if (!skip_check_error) { \ + ret = OB_ERR_NUMERIC_OR_VALUE_ERROR; \ + LOG_WARN("ORA-06502: PL/SQL: numeric or value error: NULL index table key value",\ K(ret), K(obj), K(i)); \ + } else { \ + param_value = OB_INVALID_INDEX; \ + } \ } else { \ ret = OB_ERR_UNEXPECTED; \ LOG_WARN("obj param is invalid type", K(obj), K(i)); \ @@ -167,12 +171,12 @@ int ObExprObjAccess::ExtraInfo::init_param_array(const ParamStore ¶m_store, CK (param_idxs_.at(i) >= 0 && param_idxs_.at(i) < param_store.count()); if (OB_SUCC(ret)) { const ObObjParam &obj_param = param_store.at(param_idxs_.at(i)); - GET_VALID_INT64_PARAM(obj_param); + GET_VALID_INT64_PARAM(obj_param, false); } } for (int64_t i = 0; OB_SUCC(ret) && i < param_num; ++i) { const ObObj &obj = objs_stack[i]; - GET_VALID_INT64_PARAM(obj); + GET_VALID_INT64_PARAM(obj, (i == param_num - 1 && pl::ObCollectionType::NEXT_PROPERTY == property_type_)); } return ret; } diff --git a/src/sql/engine/expr/ob_expr_pl_associative_index.cpp b/src/sql/engine/expr/ob_expr_pl_associative_index.cpp index 7e73c4739d..f37d29f78c 100644 --- a/src/sql/engine/expr/ob_expr_pl_associative_index.cpp +++ b/src/sql/engine/expr/ob_expr_pl_associative_index.cpp @@ -23,7 +23,8 @@ namespace sql OB_SERIALIZE_MEMBER((ObExprPLAssocIndex, ObExprOperator), info_.for_write_, info_.out_of_range_set_err_, - info_.parent_expr_type_); + info_.parent_expr_type_, + info_.is_index_by_varchar_); ObExprPLAssocIndex::ObExprPLAssocIndex(ObIAllocator &alloc) : ObExprOperator(alloc, T_FUN_PL_ASSOCIATIVE_INDEX, N_PL_ASSOCIATIVE_INDEX, 2, VALID_FOR_GENERATED_COL, NOT_ROW_DIMENSION, @@ -85,6 +86,7 @@ int ObExprPLAssocIndex::cg_expr(ObExprCGCtx &op_cg_ctx, info.for_write_ = assoc_idx_expr.get_write(); info.out_of_range_set_err_ = assoc_idx_expr.get_out_of_range_set_err(); info.parent_expr_type_ = assoc_idx_expr.get_parent_type(); + info.is_index_by_varchar_ = assoc_idx_expr.is_index_by_varchar(); rt_expr.extra_ = info.v_; rt_expr.eval_func_ = &eval_assoc_idx; diff --git a/src/sql/engine/expr/ob_expr_pl_associative_index.h b/src/sql/engine/expr/ob_expr_pl_associative_index.h index 1c85fdc337..3c7ad0fa09 100644 --- a/src/sql/engine/expr/ob_expr_pl_associative_index.h +++ b/src/sql/engine/expr/ob_expr_pl_associative_index.h @@ -36,6 +36,7 @@ public: inline void set_write(bool for_write) { info_.for_write_ = for_write; } inline void set_out_of_range_set_err(bool v) { info_.out_of_range_set_err_ = v; } inline void set_parent_expr_type(pl::parent_expr_type type) { info_.parent_expr_type_ = type; } + inline void set_is_index_by_varchar(bool v) { info_.is_index_by_varchar_ = v; } VIRTUAL_TO_STRING_KV(N_EXPR_TYPE, get_type_name(type_), @@ -45,7 +46,8 @@ public: N_REAL_PARAM_NUM, real_param_num_, K_(info_.for_write), K_(info_.out_of_range_set_err), - K_(info_.parent_expr_type)); + K_(info_.parent_expr_type), + K_(info_.is_index_by_varchar)); virtual int cg_expr(ObExprCGCtx &op_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const override; @@ -55,17 +57,19 @@ private: Info() : for_write_(false), out_of_range_set_err_(true), - parent_expr_type_(pl::parent_expr_type::EXPR_UNKNOWN) + parent_expr_type_(pl::parent_expr_type::EXPR_UNKNOWN), + is_index_by_varchar_(false) { } - TO_STRING_KV(K(for_write_), K(out_of_range_set_err_), K(parent_expr_type_)); + TO_STRING_KV(K(for_write_), K(out_of_range_set_err_), K(parent_expr_type_), K(is_index_by_varchar_)); union { struct { bool for_write_; bool out_of_range_set_err_; pl::parent_expr_type parent_expr_type_; + bool is_index_by_varchar_; } __attribute__((packed)); uint64_t v_; }; diff --git a/src/sql/plan_cache/ob_plan_cache_value.cpp b/src/sql/plan_cache/ob_plan_cache_value.cpp index e9249aec3a..5f2ea4a1d0 100644 --- a/src/sql/plan_cache/ob_plan_cache_value.cpp +++ b/src/sql/plan_cache/ob_plan_cache_value.cpp @@ -1510,7 +1510,7 @@ int ObPlanCacheValue::match(ObPlanCacheCtx &pc_ctx, } else if (OB_ISNULL(ps_param)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ps_param)); - } else if (!not_param_var_[i].ps_param_.can_compare(*ps_param)) { + } else if (ps_param->is_pl_extend() || !not_param_var_[i].ps_param_.can_compare(*ps_param)) { is_same = false; LOG_WARN("can not compare", K(not_param_var_[i].ps_param_), K(*ps_param), K(i)); } else if (not_param_var_[i].ps_param_.is_string_type() diff --git a/src/sql/plan_cache/ob_sql_parameterization.cpp b/src/sql/plan_cache/ob_sql_parameterization.cpp index c7a9711dfc..484a03dd0e 100644 --- a/src/sql/plan_cache/ob_sql_parameterization.cpp +++ b/src/sql/plan_cache/ob_sql_parameterization.cpp @@ -1249,8 +1249,10 @@ int ObSqlParameterization::construct_not_param(const ObString &no_param_sql, int32_t &idx) { int ret = OB_SUCCESS; - CK (OB_NOT_NULL(pc_param)); - if (OB_SUCC(ret)) { + if (OB_ISNULL(pc_param)) { + ret = OB_INVALID_ARGUMENT; + SQL_PC_LOG(WARN, "invalid argument", K(ret)); + } else { int32_t len = (int32_t)pc_param->node_->pos_ - idx; if (len > buf_len - pos) { ret = OB_BUF_NOT_ENOUGH; @@ -1275,8 +1277,10 @@ int ObSqlParameterization::construct_neg_param(const ObString &no_param_sql, int32_t &idx) { int ret = OB_SUCCESS; - CK (OB_NOT_NULL(pc_param)); - if (OB_SUCC(ret)) { + if (OB_ISNULL(pc_param)) { + ret = OB_INVALID_ARGUMENT; + SQL_PC_LOG(WARN, "invalid argument", K(ret)); + } else { int32_t len = (int32_t)pc_param->node_->pos_ - idx; if (len > buf_len - pos) { ret = OB_BUF_NOT_ENOUGH; @@ -1300,8 +1304,10 @@ int ObSqlParameterization::construct_trans_neg_param(const ObString &no_param_sq int32_t &idx) { int ret = OB_SUCCESS; - CK (OB_NOT_NULL(pc_param)); - if (OB_SUCC(ret)) { + if (OB_ISNULL(pc_param)) { + ret = OB_INVALID_ARGUMENT; + SQL_PC_LOG(WARN, "invalid argument", K(ret)); + } else { int32_t len = (int32_t)pc_param->node_->pos_ - idx; if (len > buf_len - pos) { ret = OB_BUF_NOT_ENOUGH; diff --git a/src/sql/resolver/expr/ob_raw_expr.cpp b/src/sql/resolver/expr/ob_raw_expr.cpp index ed17fd7862..1e46e6f4f1 100644 --- a/src/sql/resolver/expr/ob_raw_expr.cpp +++ b/src/sql/resolver/expr/ob_raw_expr.cpp @@ -2555,6 +2555,7 @@ int ObPLAssocIndexRawExpr::assign(const ObRawExpr &other) for_write_ = tmp.for_write_; out_of_range_set_err_ = tmp.out_of_range_set_err_; parent_type_ = tmp.parent_type_; + is_index_by_varchar_ = tmp.is_index_by_varchar_; } } return ret; diff --git a/src/sql/resolver/expr/ob_raw_expr.h b/src/sql/resolver/expr/ob_raw_expr.h index 51bfa78416..33d6a4e06f 100644 --- a/src/sql/resolver/expr/ob_raw_expr.h +++ b/src/sql/resolver/expr/ob_raw_expr.h @@ -4084,9 +4084,11 @@ class ObPLAssocIndexRawExpr : public ObOpRawExpr { public: ObPLAssocIndexRawExpr(common::ObIAllocator &alloc) - : ObOpRawExpr(alloc), for_write_(false), + : ObOpRawExpr(alloc), + parent_type_(pl::parent_expr_type::EXPR_UNKNOWN), + for_write_(false), out_of_range_set_err_(true), - parent_type_(pl::parent_expr_type::EXPR_UNKNOWN) {} + is_index_by_varchar_(false) {} ObPLAssocIndexRawExpr() : ObOpRawExpr(), for_write_(false) {} virtual ~ObPLAssocIndexRawExpr() {} @@ -4095,6 +4097,8 @@ public: inline bool get_write() const { return for_write_; } inline bool get_out_of_range_set_err() const { return out_of_range_set_err_; } inline void set_out_of_range_set_err(bool is_set_err) { out_of_range_set_err_ = is_set_err; } + inline bool is_index_by_varchar() const { return is_index_by_varchar_; } + inline void set_is_index_by_varchar(bool index_by_varchar) { is_index_by_varchar_ = index_by_varchar; } inline void set_parent_type(pl::parent_expr_type type) { parent_type_ = type; } inline pl::parent_expr_type get_parent_type() const { return parent_type_; } VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_, @@ -4108,11 +4112,17 @@ public: private: DISALLOW_COPY_AND_ASSIGN(ObPLAssocIndexRawExpr); private: - bool for_write_; - // set ret to out of range or not. - bool out_of_range_set_err_; // hack, 0: parent expr is prior, 1 parent expr is pl::parent_expr_type parent_type_; + union { + uint64_t expr_flag_; + struct { + uint64_t for_write_ : 1; + uint64_t out_of_range_set_err_ : 1; // set ret to out of range or not. + uint64_t is_index_by_varchar_ : 1; // assoc type index type is varchar + uint64_t reserved_:61; + }; + }; }; class ObObjAccessRawExpr : public ObOpRawExpr diff --git a/src/sql/resolver/ob_resolver_utils.cpp b/src/sql/resolver/ob_resolver_utils.cpp index 582697f153..2b8b19c8f2 100644 --- a/src/sql/resolver/ob_resolver_utils.cpp +++ b/src/sql/resolver/ob_resolver_utils.cpp @@ -2570,7 +2570,7 @@ int ObResolverUtils::resolve_const(const ParseNode *node, OZ (parse_interval_precision(tmp_ptr, leading_precision, is_from_pl ? 9 : 2)); OZ (parse_interval_ds_type(to_pos + 1, part_end)); OZ (parse_interval_precision(to_pos + 1, second_precision, - DATE_UNIT_SECOND == part_end ? 6 : 0)); + is_from_pl ? 9 : (DATE_UNIT_SECOND == part_end ? 6 : 0))); } else { // interval 'xxx' day (x) char *comma_pos = strchr(tmp_ptr, ','); OZ (parse_interval_ds_type(tmp_ptr, part_begin)); @@ -2579,10 +2579,14 @@ int ObResolverUtils::resolve_const(const ParseNode *node, *comma_pos = ')'; OZ (parse_interval_precision(tmp_ptr, leading_precision, is_from_pl ? 9 : 2)); *comma_pos = '('; - OZ (parse_interval_precision(comma_pos, second_precision, 6)); + OZ (parse_interval_precision(comma_pos, second_precision, is_from_pl ? 9 : 6)); } else { OZ (parse_interval_precision(tmp_ptr, leading_precision, is_from_pl ? 9 : 2)); - second_precision = DATE_UNIT_SECOND == part_end ? 6 : 0; + if (OB_SUCC(ret) && is_from_pl) { + second_precision = 9; + } else { + second_precision = DATE_UNIT_SECOND == part_end ? 6 : 0; + } } } }