有关op族算子到spec族算子转换的疑问

例如,在ObLogLimit → ObLimitSpec的转换过程中有以下代码:

int ObStaticEngineCG::generate_spec(ObLogLimit &op, ObLimitSpec &spec, const bool in_root_job)
{
int ret = OB_SUCCESS;
UNUSED(in_root_job);
spec.calc_found_rows_ = op.get_is_calc_found_rows();
spec.is_top_limit_ = op.is_top_limit();
spec.is_fetch_with_ties_ = op.is_fetch_with_ties();
if (NULL != op.get_limit_expr()) {
CK(op.get_limit_expr()->get_result_type().is_integer_type());
OZ(generate_rt_expr(*op.get_limit_expr(), spec.limit_expr_));
OZ(mark_expr_self_produced(op.get_limit_expr()));
}
if (NULL != op.get_offset_expr()) {
CK(op.get_offset_expr()->get_result_type().is_integer_type());
OZ(generate_rt_expr(*op.get_offset_expr(), spec.offset_expr_));
OZ(mark_expr_self_produced(op.get_offset_expr()));
}
if (NULL != op.get_percent_expr()) {
CK(op.get_percent_expr()->get_result_type().is_double());
OZ(generate_rt_expr(*op.get_percent_expr(), spec.percent_expr_));
OZ(mark_expr_self_produced(op.get_percent_expr()));
}
if (OB_SUCC(ret) && op.is_fetch_with_ties()) {
OZ(spec.sort_columns_.init(op.get_ties_ordering().count()));
FOREACH_CNT_X(it, op.get_ties_ordering(), OB_SUCC(ret)) {
CK(NULL != it->expr_);
ObExpr *e = NULL;
OZ(generate_rt_expr(*it->expr_, e));
OZ(mark_expr_self_produced(it->expr_));
OZ(spec.sort_columns_.push_back(e));
}
}
return ret;
}

所做的事情是将ObLogLimit算子中的 ObRawExpr 转换为 ObExpr
配合志丰老师的相关源码解析文章,我的理解是:
Operator族算子 → ObSpec族算子 是将表达式转换为效率更高的ObExpr,这也是ObSpec族算子和Operator族算子的区别。
请问:除了这种区别还有其他的区别吗?求内核大佬解惑。

补充一下:将ObSpec理解为算子是否正确?