ob_equal_analysis.cpp 18.4 KB
Newer Older
O
oceanbase-admin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 * Copyright (c) 2021 OceanBase
 * OceanBase CE is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#define USING_LOG_PREFIX SQL_RESV
#include "sql/rewrite/ob_equal_analysis.h"
#include "sql/engine/expr/ob_expr_operator.h"
#include "common/ob_smart_call.h"
W
wangzelin.wzl 已提交
17 18
namespace oceanbase
{
O
oceanbase-admin 已提交
19
using namespace common;
W
wangzelin.wzl 已提交
20 21
namespace sql
{
O
oceanbase-admin 已提交
22
ObEqualAnalysis::ObEqualAnalysis()
W
wangzelin.wzl 已提交
23 24 25 26 27 28
    : equal_set_alloc_(ObModIds::OB_SQL_OPTIMIZER_EQUAL_SETS),
      column_set_(),
      equal_sets_()
{

}
O
oceanbase-admin 已提交
29 30 31 32

int ObEqualAnalysis::init()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
33 34
  if (OB_FAIL(column_set_.create(128, ObModIds::OB_SQL_OPTIMIZER_EQUAL_SETS,
                                 ObModIds::OB_SQL_OPTIMIZER_EQUAL_SETS))) {
O
oceanbase-admin 已提交
35
    LOG_WARN("failed to create hash map", K(ret));
W
wangzelin.wzl 已提交
36
  } else { /*do nothing*/ }
O
oceanbase-admin 已提交
37 38 39 40 41 42 43 44 45 46
  return ret;
}

ObEqualAnalysis::~ObEqualAnalysis()
{
  reset();
}

void ObEqualAnalysis::reset()
{
W
wangzelin.wzl 已提交
47
  //The data structure has only the clear interface
O
oceanbase-admin 已提交
48
  column_set_.reuse();
W
wangzelin.wzl 已提交
49
  DLIST_REMOVE_ALL_NORET(p, equal_sets_) {
O
oceanbase-admin 已提交
50 51 52 53 54 55 56
    if (p != NULL) {
      p->~ObEqualSet();
      equal_set_alloc_.free(p);
      p = NULL;
    }
  }
  equal_sets_.reset();
W
wangzelin.wzl 已提交
57
  //the allocator is not equal analysis enjoy alone, so can't reset allocator at here
O
oceanbase-admin 已提交
58 59
}

X
xianyu-w 已提交
60
int ObEqualAnalysis::get_or_add_expr_idx(const ObRawExpr *expr, int64_t &expr_idx)
O
oceanbase-admin 已提交
61
{
X
xianyu-w 已提交
62 63
  int ret = OB_SUCCESS;
  expr_idx = -1;
O
oceanbase-admin 已提交
64 65
  EqualSetKey key;
  key.expr_ = expr;
X
xianyu-w 已提交
66
  if (OB_SUCC(column_set_.get_refactored(key, expr_idx))) {
O
oceanbase-admin 已提交
67 68 69 70 71 72
    /*do nothing*/
  } else if (OB_HASH_NOT_EXIST != ret) {
    LOG_WARN("failed to get from hash map", K(ret), K(expr_idx));
  } else {
    ret = OB_SUCCESS;
    expr_idx = column_set_.size();
X
xianyu-w 已提交
73
    if (OB_FAIL(column_set_.set_refactored(key, expr_idx))) {
O
oceanbase-admin 已提交
74 75 76 77
      expr_idx = -1;
      LOG_WARN("set expr index to column set failed", K(ret), K(expr_idx));
    }
  }
X
xianyu-w 已提交
78 79 80 81 82
  if (OB_SUCC(ret) && expr_idx < 0) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected idx", K(ret));
  }
  return ret;
O
oceanbase-admin 已提交
83 84
}

W
wangzelin.wzl 已提交
85
int ObEqualAnalysis::feed_where_expr(const ObRawExpr *expr)
O
oceanbase-admin 已提交
86 87
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
88 89 90 91
  if (OB_ISNULL(expr) ||
      (T_OP_EQ == expr->get_expr_type() &&
       (OB_ISNULL(expr->get_param_expr(0))
        || OB_ISNULL(expr->get_param_expr(1))))) {
O
oceanbase-admin 已提交
92 93
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("expr is null", K(ret));
W
wangzelin.wzl 已提交
94
  } else if (T_OP_EQ == expr->get_expr_type()) {
O
oceanbase-admin 已提交
95
    /// only add pred like `c1 = c2`
W
wangzelin.wzl 已提交
96
    const ObOpRawExpr *eq_expr = static_cast<const ObOpRawExpr *>(expr);
O
oceanbase-admin 已提交
97 98 99 100 101 102 103 104 105 106 107
    if (OB_FAIL(add_equal_cond(*eq_expr))) {
      LOG_WARN("add equal condition failed", K(ret));
    } else {
      LOG_PRINT_EXPR(DEBUG, "accept expr for equal set", expr);
    }
  } else {
    LOG_PRINT_EXPR(DEBUG, "unaccept expr for equal set", expr);
  }
  return ret;
}

W
wangzelin.wzl 已提交
108
int ObEqualAnalysis::feed_equal_sets(const EqualSets &input_equal_sets)
O
oceanbase-admin 已提交
109 110 111
{
  int ret = OB_SUCCESS;
  for (int64_t i = 0; OB_SUCC(ret) && i < input_equal_sets.count(); ++i) {
W
wangzelin.wzl 已提交
112 113 114
    const EqualSet *eset = input_equal_sets.at(i);
    ObExprEqualSet *equal_set = NULL;
    //create new equal set
O
oceanbase-admin 已提交
115 116 117 118 119 120 121 122 123
    if (OB_ISNULL(eset)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get null equal set", K(ret));
    } else if (OB_ISNULL(equal_set = new_equal_set())) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_ERROR("create new equal set failed", K(ret));
    }
    for (int64_t j = 0; OB_SUCC(ret) && j < eset->count(); ++j) {
      int64_t expr_idx = 0;
W
wangzelin.wzl 已提交
124
      const ObRawExpr *expr;
O
oceanbase-admin 已提交
125 126 127
      if (OB_ISNULL(expr = eset->at(j))) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("expr is null", K(ret));
X
xianyu-w 已提交
128
      } else if (OB_FAIL(get_or_add_expr_idx(expr, expr_idx))) {
O
oceanbase-admin 已提交
129
        LOG_WARN("get or add expr idx failed", K(ret));
W
wangzelin.wzl 已提交
130
      }  else if (OB_FAIL(equal_set->add_expr(expr_idx, true, expr))) {
O
oceanbase-admin 已提交
131 132 133 134 135 136 137
        LOG_WARN("add expr to equal set failed", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
138
int ObEqualAnalysis::add_equal_cond(const ObOpRawExpr &expr)
O
oceanbase-admin 已提交
139 140
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
141
  ObExprEqualSet *equal_set = NULL;
O
oceanbase-admin 已提交
142 143 144
  int64_t l_expr_idx = 0;
  int64_t r_expr_idx = 0;

W
wangzelin.wzl 已提交
145 146 147
  if (OB_UNLIKELY(expr.get_expr_type() != T_OP_EQ)
      || OB_ISNULL(expr.get_param_expr(0))
      || OB_ISNULL(expr.get_param_expr(1))) {
O
oceanbase-admin 已提交
148 149
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is invalid", K(expr));
X
xianyu-w 已提交
150 151 152 153
  } else if (OB_FAIL(get_or_add_expr_idx(expr.get_param_expr(0), l_expr_idx))) {
    LOG_WARN("get or add left expr idx failed", K(ret));
  } else if (OB_FAIL(get_or_add_expr_idx(expr.get_param_expr(1), r_expr_idx))) {
    LOG_WARN("get or add right expr idx failed", K(ret));
O
oceanbase-admin 已提交
154
  } else if (l_expr_idx != r_expr_idx) {
W
wangzelin.wzl 已提交
155
    //左右两边是完全相等的表达式,例如c1=c1, sum(c1)=sum(c1),属于恒true范围,不具有传递关系,所以不加入集合中
O
oceanbase-admin 已提交
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    if (OB_FAIL(find_equal_set(l_expr_idx, expr.get_param_expr(1), equal_set))) {
      LOG_WARN("find equal set failed", K(ret), K(l_expr_idx), K(*expr.get_param_expr(1)));
    } else if (equal_set != NULL) {
      if (!equal_set->has_expr(r_expr_idx)) {
        if (OB_FAIL(equal_set->add_expr(r_expr_idx, true, expr.get_param_expr(1)))) {
          LOG_WARN("add expr to equal set failed", K(ret));
        }
      }
    } else if (OB_FAIL(find_equal_set(r_expr_idx, expr.get_param_expr(0), equal_set))) {
      LOG_WARN("find equal set failed", K(ret), K(r_expr_idx), K(*expr.get_param_expr(0)));
    } else if (equal_set != NULL) {
      if (!equal_set->has_expr(l_expr_idx)) {
        if (OB_FAIL(equal_set->add_expr(l_expr_idx, true, expr.get_param_expr(0)))) {
          LOG_WARN("add expr to equal set failed", K(ret));
        }
      }
    }
    if (OB_SUCC(ret) && NULL == equal_set) {
W
wangzelin.wzl 已提交
174
      //create new equal set
O
oceanbase-admin 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187
      if (OB_ISNULL(equal_set = new_equal_set())) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_ERROR("create new equal set failed", K(ret));
      } else if (OB_FAIL(equal_set->add_expr(l_expr_idx, true, expr.get_param_expr(0)))) {
        LOG_WARN("add expr to equal set failed", K(ret));
      } else if (OB_FAIL(equal_set->add_expr(r_expr_idx, true, expr.get_param_expr(1)))) {
        LOG_WARN("add expr to equal set failed", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
188
int ObEqualAnalysis::get_equal_sets(ObIAllocator *alloc, EqualSets &equal_sets) const
O
oceanbase-admin 已提交
189 190
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
191 192
  ObSEArray<ObRawExpr *, 8> raw_equal_set;
  DLIST_FOREACH(equal_set, equal_sets_) {
O
oceanbase-admin 已提交
193 194
    raw_equal_set.reuse();
    for (ObExprEqualSet::ColumnIterator iter = equal_set->column_begin();
W
wangzelin.wzl 已提交
195 196 197
        OB_SUCC(ret) && iter != equal_set->column_end(); ++iter) {
      if (OB_FAIL(raw_equal_set.push_back(
                    const_cast<ObRawExpr*>(iter.get_expr_info())))) {
O
oceanbase-admin 已提交
198 199 200 201
        LOG_WARN("push back equal expr info failed", K(ret));
      }
    }
    if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
202 203
      if (OB_FAIL(ObRawExprSetUtils::add_expr_set(
                    alloc, raw_equal_set, equal_sets))) {
O
oceanbase-admin 已提交
204 205 206 207 208 209 210
        LOG_WARN("failed to add expr set", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
211
ObExprEqualSet *ObEqualAnalysis::new_equal_set()
O
oceanbase-admin 已提交
212
{
W
wangzelin.wzl 已提交
213 214
  void *ptr = NULL;
  ObExprEqualSet *equal_set = NULL;
O
oceanbase-admin 已提交
215
  if (NULL != (ptr = equal_set_alloc_.alloc(sizeof(ObExprEqualSet)))) {
W
wangzelin.wzl 已提交
216
    equal_set = new(ptr) ObExprEqualSet();
O
oceanbase-admin 已提交
217 218 219 220 221 222 223 224 225 226
    if (!equal_sets_.add_last(equal_set)) {
      LOG_WARN("add equal set failed");
      equal_set->~ObEqualSet();
      equal_set_alloc_.free(equal_set);
      equal_set = NULL;
    }
  }
  return equal_set;
}

W
wangzelin.wzl 已提交
227
int ObEqualAnalysis::find_equal_set(int64_t expr_idx, const ObRawExpr *new_expr, ObExprEqualSet *&equal_set_ret)
O
oceanbase-admin 已提交
228 229
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
230 231
  const ObRawExpr* const *same_expr = NULL;
  DLIST_FOREACH(equal_set, equal_sets_) {
O
oceanbase-admin 已提交
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
    if (OB_ISNULL(equal_set)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_ERROR("equal set is null");
    } else if ((same_expr = equal_set->get_expr(expr_idx)) != NULL) {
      bool can_be = false;
      if (OB_FAIL(expr_can_be_add_to_equal_set(*equal_set, *same_expr, new_expr, can_be))) {
        LOG_WARN("check expr whether can be add to equal set failed", K(ret));
      } else if (can_be) {
        equal_set_ret = equal_set;
        break;
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
248 249 250 251 252
//检查equal set中的元素和要加入equal set中的元素的compare type是否都一致
int ObEqualAnalysis::expr_can_be_add_to_equal_set(const ObExprEqualSet &equal_set,
                                                  const ObRawExpr *same_expr,
                                                  const ObRawExpr *new_expr,
                                                  bool &can_be) const
O
oceanbase-admin 已提交
253 254 255
{
  can_be = true;
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
256
  //equal set中的元素至少是两个表达式
O
oceanbase-admin 已提交
257 258 259 260 261
  if (equal_set.get_column_num() <= 1 || OB_ISNULL(same_expr) || OB_ISNULL(new_expr)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_ERROR("arguments are invalid", K(equal_set.get_column_num()), K(same_expr), K(new_expr));
  } else {
    for (ObExprEqualSet::ColumnIterator iter = equal_set.column_begin();
W
wangzelin.wzl 已提交
262 263
        OB_SUCC(ret) && can_be && iter != equal_set.column_end(); ++iter) {
      const ObRawExpr *cur_expr = iter.get_expr_info();
O
oceanbase-admin 已提交
264 265 266 267
      if (OB_ISNULL(cur_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_ERROR("expr is null in equal set");
      } else if (cur_expr == same_expr) {
W
wangzelin.wzl 已提交
268
        //do nothing
O
oceanbase-admin 已提交
269 270 271 272 273 274 275 276
      } else if (OB_FAIL(check_type_equivalent(*cur_expr, *same_expr, *new_expr, can_be))) {
        LOG_WARN("failed to check type equivalent", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
277 278 279 280 281
//检查两个equal set是否能够被合并成一个equal set
//能够被合并的规则是,两个equal set有相同的表达式,并且不相同的表达式的元素都在另一个equal set中的compare type都相同
int ObEqualAnalysis::check_whether_can_be_merged(const ObExprEqualSet &equal_set,
                                                 const ObExprEqualSet &another_set,
                                                 bool &can_be) const
O
oceanbase-admin 已提交
282 283 284
{
  can_be = true;
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
285
  const ObRawExpr* const *same_expr = NULL;
O
oceanbase-admin 已提交
286 287 288 289
  if (!equal_set.intersect_equal_set(another_set)) {
    can_be = false;
  } else {
    for (ObExprEqualSet::ColumnIterator iter = another_set.column_begin();
W
wangzelin.wzl 已提交
290
        OB_ISNULL(same_expr) && iter != another_set.column_end(); ++iter) {
O
oceanbase-admin 已提交
291 292 293 294
      same_expr = equal_set.get_expr(iter.get_expr_idx());
    }
  }
  for (ObExprEqualSet::ColumnIterator iter = another_set.column_begin();
W
wangzelin.wzl 已提交
295
      OB_SUCC(ret) && can_be && iter != another_set.column_end(); ++iter) {
O
oceanbase-admin 已提交
296 297 298 299 300 301 302 303 304 305 306 307 308
    if (iter.get_expr_info() != *same_expr) {
      if (OB_FAIL(expr_can_be_add_to_equal_set(equal_set, *same_expr, iter.get_expr_info(), can_be))) {
        LOG_WARN("check expr whether can be add to equal set failed", K(ret));
      }
    }
  }
  return ret;
}

int ObEqualAnalysis::finish_feed()
{
  int ret = OB_SUCCESS;
  // merge intersected sets
W
wangzelin.wzl 已提交
309 310 311
  ObExprEqualSet *another_set = NULL;
  DLIST_FOREACH(equal_set, equal_sets_) {
    if (OB_ISNULL(equal_set)) {
O
oceanbase-admin 已提交
312
      ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
313 314 315 316 317
      LOG_WARN("equal set is null", K(equal_set));
    } else {
      another_set = equal_set->get_next();
    }
    while (OB_SUCC(ret) && equal_sets_.get_header() != another_set) {
O
oceanbase-admin 已提交
318
      bool can_be = false;
W
wangzelin.wzl 已提交
319 320 321 322 323 324
      if (OB_ISNULL(another_set)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("equal set is null", K(another_set));
      } else if (OB_FAIL(check_whether_can_be_merged(*equal_set, 
                                                     *another_set, 
                                                     can_be))) {
O
oceanbase-admin 已提交
325
        LOG_WARN("check whether can be merged failed", K(ret));
W
wangzelin.wzl 已提交
326 327 328
      } else if (!can_be) {
        another_set = another_set->get_next();
      } else {
O
oceanbase-admin 已提交
329 330
        // merge another_set into equal_set
        for (ObExprEqualSet::ColumnIterator it = another_set->column_begin();
W
wangzelin.wzl 已提交
331
            OB_SUCC(ret) && it != another_set->column_end(); ++it) {
O
oceanbase-admin 已提交
332 333 334 335 336 337 338
          if (!equal_set->has_expr(it.get_expr_idx())) {
            if (OB_FAIL(equal_set->add_expr(it.get_expr_idx(), it.get_flag(), it.get_expr_info()))) {
              LOG_WARN("add expr to equal set failed", K(ret));
            }
          }
        }
        if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
339
          ObExprEqualSet *tmp = another_set->get_next();
O
oceanbase-admin 已提交
340 341
          equal_sets_.remove(another_set);
          equal_set_alloc_.free(another_set);
W
wangzelin.wzl 已提交
342
          another_set = tmp;
O
oceanbase-admin 已提交
343 344 345 346 347 348 349 350
        }
      }
    }
  }
  return ret;
}

int ObEqualAnalysis::check_type_equivalent(
W
wangzelin.wzl 已提交
351 352
    const ObRawExpr &cur_expr, const ObRawExpr &same_expr,
    const ObRawExpr &new_expr, bool &can_be)
O
oceanbase-admin 已提交
353 354 355 356 357 358 359 360
{
  int ret = OB_SUCCESS;
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to check stack overflow", K(ret), K(is_stack_overflow));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("too deep recursive", K(ret), K(is_stack_overflow));
W
wangzelin.wzl 已提交
361 362 363 364 365
  } else if (T_OP_ROW == cur_expr.get_expr_type()
             && T_OP_ROW == new_expr.get_expr_type()
             && T_OP_ROW == same_expr.get_expr_type()) {
    if (cur_expr.get_param_count() != same_expr.get_param_count()
        || same_expr.get_param_count() != new_expr.get_param_count()) {
O
oceanbase-admin 已提交
366 367 368
      can_be = false;
    } else {
      for (int64_t i = 0; OB_SUCC(ret) && can_be && i < cur_expr.get_param_count(); i++) {
W
wangzelin.wzl 已提交
369 370 371 372 373 374
        const ObRawExpr *c_cur = NULL;
        const ObRawExpr *c_same = NULL;
        const ObRawExpr *c_new = NULL;
        if (OB_ISNULL(c_cur = cur_expr.get_param_expr(i))
            || OB_ISNULL(c_same = same_expr.get_param_expr(i))
            || OB_ISNULL(c_new = new_expr.get_param_expr(i))) {
O
oceanbase-admin 已提交
375 376 377 378 379 380 381
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("NULL expr", K(ret), K(c_cur), K(c_same), K(c_new));
        } else if (OB_FAIL(SMART_CALL(check_type_equivalent(*c_cur, *c_same, *c_new, can_be)))) {
          LOG_WARN("failed to check type in row");
        }
      }
    }
W
wangzelin.wzl 已提交
382 383 384
  } else if (T_OP_ROW != cur_expr.get_expr_type()
             && T_OP_ROW != new_expr.get_expr_type()
             && T_OP_ROW != same_expr.get_expr_type()) {
O
oceanbase-admin 已提交
385
    if (OB_FAIL(ObRelationalExprOperator::is_equivalent(
W
wangzelin.wzl 已提交
386 387 388
                cur_expr.get_result_type(),
                same_expr.get_result_type(),
                new_expr.get_result_type(), can_be))) {
O
oceanbase-admin 已提交
389 390 391 392 393 394 395 396
      LOG_WARN("check is equivalent failed", K(ret));
    }
  } else {
    can_be = false;
  }
  return ret;
}

W
wangzelin.wzl 已提交
397 398 399
int ObEqualAnalysis::compute_equal_set(ObIAllocator *allocator,
                                       const ObIArray<ObRawExpr *> &eset_conditions,
                                       EqualSets &equal_sets)
O
oceanbase-admin 已提交
400 401 402 403 404 405 406 407 408 409 410 411 412
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(allocator)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("allocator is null", K(ret));
  } else if (eset_conditions.count() > 0) {
    ObEqualAnalysis ana;
    if (OB_FAIL(ana.init())) {
      LOG_WARN("failed to init equal analysis", K(ret));
    }
    for (int64_t i = 0; OB_SUCC(ret) && i < eset_conditions.count(); ++i) {
      if (OB_FAIL(ana.feed_where_expr(eset_conditions.at(i)))) {
        LOG_WARN("failed to feed where expr", K(ret));
W
wangzelin.wzl 已提交
413
      } else { /*do nothing*/ }
O
oceanbase-admin 已提交
414 415 416 417 418 419 420 421 422 423 424 425
    }
    if (OB_SUCC(ret)) {
      if (OB_FAIL(ana.finish_feed())) {
        LOG_WARN("finish feed failed", K(ret));
      } else if (OB_FAIL(ana.get_equal_sets(allocator, equal_sets))) {
        LOG_WARN("get equal sets failed", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
426 427 428 429
int ObEqualAnalysis::compute_equal_set(ObIAllocator *allocator,
                                       const ObIArray<ObRawExpr *> &eset_conditions,
                                       const EqualSets &input_equal_sets,
                                       EqualSets &output_equal_sets)
O
oceanbase-admin 已提交
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(allocator)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("allocator is null", K(ret));
  } else if (eset_conditions.count() > 0) {
    ObEqualAnalysis ana;
    if (OB_FAIL(ana.init())) {
      LOG_WARN("failed to init equal analysis", K(ret));
    } else if (OB_FAIL(ana.feed_equal_sets(input_equal_sets))) {
      LOG_WARN("failed to feed input equal sets", K(ret));
    }
    for (int64_t i = 0; OB_SUCC(ret) && i < eset_conditions.count(); ++i) {
      if (OB_FAIL(ana.feed_where_expr(eset_conditions.at(i)))) {
        LOG_WARN("failed to feed where expr", K(ret));
W
wangzelin.wzl 已提交
445
      } else { /*do nothing*/ }
O
oceanbase-admin 已提交
446 447 448 449 450 451 452 453 454 455 456 457 458 459
    }
    if (OB_SUCC(ret)) {
      if (OB_FAIL(ana.finish_feed())) {
        LOG_WARN("finish feed failed", K(ret));
      } else if (OB_FAIL(ana.get_equal_sets(allocator, output_equal_sets))) {
        LOG_WARN("get equal sets failed", K(ret));
      }
    }
  } else if (OB_FAIL(output_equal_sets.assign(input_equal_sets))) {
    LOG_WARN("failed to assign equal sets", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
int ObEqualAnalysis::compute_equal_set(ObIAllocator *allocator,
                                       ObRawExpr *eset_condition,
                                       const EqualSets &input_equal_sets,
                                       EqualSets &output_equal_sets)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(allocator)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("allocator is null", K(ret));
  } else {
    ObEqualAnalysis ana;
    if (OB_FAIL(ana.init())) {
      LOG_WARN("failed to init equal analysis", K(ret));
    } else if (OB_FAIL(ana.feed_equal_sets(input_equal_sets))) {
      LOG_WARN("failed to feed input equal sets", K(ret));
    } else if (OB_FAIL(ana.feed_where_expr(eset_condition))) {
      LOG_WARN("failed to feed where expr", K(ret));
    } else if (OB_FAIL(ana.finish_feed())) {
      LOG_WARN("finish feed failed", K(ret));
    } else if (OB_FAIL(ana.get_equal_sets(allocator, output_equal_sets))) {
      LOG_WARN("get equal sets failed", K(ret));
    }
  }
  return ret;
}

int ObEqualAnalysis::merge_equal_set(ObIAllocator *allocator,
                                    const EqualSets &left_equal_sets,
                                    const EqualSets &right_equal_sets,
                                    EqualSets &output_equal_sets)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(allocator)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("allocator is null", K(ret));
  } else {
    ObEqualAnalysis ana;
    if (OB_FAIL(ana.init())) {
      LOG_WARN("failed to init equal analysis", K(ret));
    } else if (OB_FAIL(ana.feed_equal_sets(left_equal_sets))) {
      LOG_WARN("failed to feed input equal sets", K(ret));
    } else if (OB_FAIL(ana.feed_equal_sets(right_equal_sets))) {
      LOG_WARN("failed to feed where expr", K(ret));
    } else if (OB_FAIL(ana.finish_feed())) {
      LOG_WARN("finish feed failed", K(ret));
    } else if (OB_FAIL(ana.get_equal_sets(allocator, output_equal_sets))) {
      LOG_WARN("get equal sets failed", K(ret));
    }
  }
  return ret;
}

O
oceanbase-admin 已提交
512 513
}  // namespace sql
}  // namespace oceanbase