ob_query_range.cpp 382.4 KB
Newer Older
O
oceanbase-admin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/**
 * 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_REWRITE
#include "lib/timezone/ob_time_convert.h"
#include "lib/container/ob_array_serialization.h"
O
obdev 已提交
16 17
#include "lib/geo/ob_geo_utils.h"
#include "lib/rc/ob_rc.h"
O
oceanbase-admin 已提交
18 19 20 21 22 23
#include "sql/resolver/dml/ob_dml_stmt.h"
#include "sql/rewrite/ob_query_range.h"
#include "sql/engine/expr/ob_expr_result_type_util.h"
#include "sql/engine/expr/ob_expr_like.h"
#include "common/ob_smart_call.h"
#include "sql/optimizer/ob_optimizer_util.h"
24
#include "observer/omt/ob_tenant_srs.h"
O
obdev 已提交
25
#include "sql/engine/expr/ob_geo_expr_utils.h"
O
obdev 已提交
26
#include "sql/engine//expr/ob_datum_cast.h"
O
oceanbase-admin 已提交
27

W
wangzelin.wzl 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
//if cnd is true get full range key part which is always true
//else, get empty key part which is always false

#define GET_ALWAYS_TRUE_OR_FALSE(cnd, out_key_part) \
    do { \
      if (OB_SUCC(ret)) { \
        query_range_ctx_->cur_expr_is_precise_ = false; \
        if (OB_ISNULL(table_graph_.key_part_head_)) { \
          ret = OB_ERR_NULL_VALUE; \
          LOG_WARN("Can not find key_part");  \
        } else if (cnd) { \
          if (OB_FAIL(alloc_full_key_part(out_key_part))) { \
            LOG_WARN("alloc_full_key_part failed", K(ret)); \
          } else { \
            out_key_part->id_ = table_graph_.key_part_head_->id_;  \
            out_key_part->pos_ = table_graph_.key_part_head_->pos_;  \
          } \
        } else { \
          if (OB_FAIL(alloc_empty_key_part(out_key_part))) { \
            LOG_WARN("alloc_empty_key_part failed", K(ret)); \
          } else if (OB_ISNULL(out_key_part)) { \
            ret = OB_ALLOCATE_MEMORY_FAILED; \
            LOG_ERROR("out_key_part is null.", K(ret)); \
          } else { \
            out_key_part->id_ = table_graph_.key_part_head_->id_;  \
            out_key_part->pos_ = table_graph_.key_part_head_->pos_;  \
          } \
        } \
      } \
    } while(0)

namespace oceanbase
{
O
oceanbase-admin 已提交
61 62
using namespace common;
using namespace share::schema;
W
wangzelin.wzl 已提交
63 64
namespace sql
{
O
oceanbase-admin 已提交
65 66
ObQueryRange::ObQueryRange()
    : state_(NEED_INIT),
O
obdev 已提交
67
      range_size_(0),
O
oceanbase-admin 已提交
68 69
      column_count_(0),
      contain_row_(false),
O
obdev 已提交
70
      contain_in_(false),
O
obdev 已提交
71
      contain_geo_filters_(false),
O
oceanbase-admin 已提交
72 73
      inner_allocator_(ObModIds::OB_SQL_QUERY_RANGE),
      allocator_(inner_allocator_),
O
obdev 已提交
74 75
      bucket_allocator_wrapper_(allocator_),
      map_alloc_(OB_MALLOC_NORMAL_BLOCK_SIZE, bucket_allocator_wrapper_),
O
oceanbase-admin 已提交
76 77 78
      query_range_ctx_(NULL),
      key_part_store_(allocator_),
      range_exprs_(allocator_),
79
      ss_range_exprs_(allocator_),
O
obdev 已提交
80
      mbr_filters_(allocator_),
O
obdev 已提交
81
      has_exec_param_(false),
W
wangzelin.wzl 已提交
82 83
      is_equal_and_(false),
      equal_offs_(allocator_),
84 85 86
      expr_final_infos_(allocator_),
      mem_used_(allocator_.used()),
      is_reach_mem_limit_(false)
W
wangzelin.wzl 已提交
87 88
{
}
O
oceanbase-admin 已提交
89

W
wangzelin.wzl 已提交
90
ObQueryRange::ObQueryRange(ObIAllocator &alloc)
O
oceanbase-admin 已提交
91
    : state_(NEED_INIT),
O
obdev 已提交
92
      range_size_(0),
O
oceanbase-admin 已提交
93 94
      column_count_(0),
      contain_row_(false),
O
obdev 已提交
95
      contain_in_(false),
O
obdev 已提交
96
      contain_geo_filters_(false),
O
oceanbase-admin 已提交
97 98
      inner_allocator_(ObModIds::OB_SQL_QUERY_RANGE),
      allocator_(alloc),
O
obdev 已提交
99 100
      bucket_allocator_wrapper_(allocator_),
      map_alloc_(OB_MALLOC_NORMAL_BLOCK_SIZE, bucket_allocator_wrapper_),
O
oceanbase-admin 已提交
101 102 103
      query_range_ctx_(NULL),
      key_part_store_(allocator_),
      range_exprs_(allocator_),
104
      ss_range_exprs_(allocator_),
O
obdev 已提交
105
      mbr_filters_(allocator_),
O
obdev 已提交
106
      has_exec_param_(false),
W
wangzelin.wzl 已提交
107 108
      is_equal_and_(false),
      equal_offs_(allocator_),
109 110 111
      expr_final_infos_(allocator_),
      mem_used_(allocator_.used()),
      is_reach_mem_limit_(false)
W
wangzelin.wzl 已提交
112 113
{
}
O
oceanbase-admin 已提交
114 115 116 117 118 119

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

W
wangzelin.wzl 已提交
120
ObQueryRange &ObQueryRange::operator=(const ObQueryRange &other)
O
oceanbase-admin 已提交
121 122 123 124 125 126 127 128 129 130
{
  if (this != &other) {
    reset();
    deep_copy(other);
  }
  return *this;
}

void ObQueryRange::reset()
{
W
wangzelin.wzl 已提交
131
  DLIST_FOREACH_NORET(node, key_part_store_.get_obj_list()) {
O
oceanbase-admin 已提交
132 133 134 135
    if (node != NULL && node->get_obj() != NULL) {
      node->get_obj()->~ObKeyPart();
    }
  }
W
wangzelin.wzl 已提交
136
  key_part_store_.destroy();
O
oceanbase-admin 已提交
137 138
  query_range_ctx_ = NULL;
  state_ = NEED_INIT;
O
obdev 已提交
139
  range_size_ = 0;
O
oceanbase-admin 已提交
140 141
  column_count_ = 0;
  contain_row_ = false;
O
obdev 已提交
142
  contain_in_ = false;
O
obdev 已提交
143 144
  mbr_filters_.reset(),
  contain_geo_filters_ = false;
O
oceanbase-admin 已提交
145 146
  table_graph_.reset();
  range_exprs_.reset();
147
  ss_range_exprs_.reset();
O
oceanbase-admin 已提交
148
  inner_allocator_.reset();
O
obdev 已提交
149
  has_exec_param_ = false;
W
wangzelin.wzl 已提交
150 151 152
  is_equal_and_ = false;
  equal_offs_.reset();
  expr_final_infos_.reset();
O
obdev 已提交
153
  columnId_map_.destroy();
154 155
  is_reach_mem_limit_ = false;
  mem_used_ = 0;
O
oceanbase-admin 已提交
156 157
}

W
wangzelin.wzl 已提交
158 159 160 161 162 163
int ObQueryRange::init_query_range_ctx(ObIAllocator &allocator,
                                       const ColumnIArray &range_columns,
                                       ObExecContext *exec_ctx,
                                       ExprConstrantArray *expr_constraints,
                                       const ParamsIArray *params,
                                       const bool phy_rowid_for_table_loc,
164 165
                                       const bool ignore_calc_failure,
                                       const bool use_in_optimization)
O
oceanbase-admin 已提交
166 167
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
168
  void *ptr = NULL;
O
oceanbase-admin 已提交
169
  uint64_t table_id = OB_INVALID_ID;
O
obdev 已提交
170
  if (OB_UNLIKELY(range_columns.count() <= 0)) {
O
oceanbase-admin 已提交
171
    ret = OB_INVALID_ARGUMENT;
O
obdev 已提交
172
    LOG_WARN("range column array is empty", K(ret));
O
oceanbase-admin 已提交
173 174
  } else if (OB_ISNULL(ptr = allocator.alloc(sizeof(ObQueryRangeCtx)))) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
O
obdev 已提交
175
    LOG_ERROR("alloc query range context failed", K(ret));
176 177 178
  } else if (OB_ISNULL(exec_ctx) || OB_ISNULL(exec_ctx->get_my_session())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(exec_ctx));
O
oceanbase-admin 已提交
179
  } else {
W
wangzelin.wzl 已提交
180 181 182
    query_range_ctx_ = new(ptr) ObQueryRangeCtx(exec_ctx, expr_constraints, params);
    query_range_ctx_->phy_rowid_for_table_loc_ = phy_rowid_for_table_loc;
    query_range_ctx_->ignore_calc_failure_ = ignore_calc_failure;
183
    query_range_ctx_->range_optimizer_max_mem_size_ = exec_ctx->get_my_session()->get_range_optimizer_max_mem_size();
184 185 186
    if (0 == query_range_ctx_->range_optimizer_max_mem_size_) {
      query_range_ctx_->range_optimizer_max_mem_size_ = INT64_MAX;
    }
187
    query_range_ctx_->use_in_optimization_ = use_in_optimization;
O
oceanbase-admin 已提交
188 189
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < range_columns.count(); ++i) {
W
wangzelin.wzl 已提交
190
    const ColumnItem &col = range_columns.at(i);
O
oceanbase-admin 已提交
191 192
    if (OB_UNLIKELY(col.is_invalid())) {
      ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
193
      LOG_WARN("get invalid table id", K(ret), K(table_id), K(range_columns.at(0).expr_));
O
oceanbase-admin 已提交
194 195
    } else {
      ObKeyPartId key_part_id(col.table_id_, col.column_id_);
W
wangzelin.wzl 已提交
196
      const ObExprResType *expr_res_type = col.get_column_type();
197
      void *ptr = NULL;
O
oceanbase-admin 已提交
198 199 200
      if (OB_ISNULL(expr_res_type)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("expr result type is null", K(ret));
201 202
      } else if (OB_ISNULL(ptr = allocator.alloc(sizeof(ObKeyPartPos)))) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
K
Klawz 已提交
203
        LOG_WARN("failed to allocate memory for ObKeyPartPos", K(ret));
O
oceanbase-admin 已提交
204 205 206 207 208 209
      } else {
        ObExprResType tmp_expr_type = *expr_res_type;
        if (tmp_expr_type.is_lob_locator()) {
          tmp_expr_type.set_type(ObLongTextType);
        }
        table_id = (i > 0 ? table_id : col.table_id_);
210
        ObKeyPartPos *key_part_pos = new(ptr) ObKeyPartPos(i, tmp_expr_type);
O
oceanbase-admin 已提交
211

O
obdev 已提交
212
        if (OB_UNLIKELY(table_id != col.table_id_)) { // table_id of range columns must be same
O
oceanbase-admin 已提交
213 214
          ret = OB_INVALID_ARGUMENT;
          LOG_WARN("range columns must have the same table id", K(table_id), K_(col.table_id));
215
        } else if (OB_FAIL(key_part_pos->set_enum_set_values(allocator_, col.expr_->get_enum_set_values()))) {
O
obdev 已提交
216
          LOG_WARN("fail to set values", K(ret), K(key_part_pos));
O
oceanbase-admin 已提交
217 218
        } else if (OB_FAIL(query_range_ctx_->key_part_map_.set_refactored(key_part_id, key_part_pos))) {
          LOG_WARN("set key part map failed", K(ret), K(key_part_id));
219 220
        } else if (OB_FAIL(query_range_ctx_->key_part_pos_array_.push_back(key_part_pos))) {
          LOG_WARN("failed to push back key part pos", K(ret));
O
oceanbase-admin 已提交
221 222 223 224 225 226 227 228 229
        }
      }
    }
  }
  if (OB_SUCC(ret)) {
    // Add the default range of the index and remember the count of the rowkeys.
    // Just to handle the full range case
    // E.g.
    //       select * from t where true;
W
wangzelin.wzl 已提交
230
    ObKeyPart *full_key_part = NULL;
O
oceanbase-admin 已提交
231 232 233 234 235 236
    if (OB_FAIL(alloc_full_key_part(full_key_part))) {
      LOG_WARN("alloc_full_key_part failed", K(ret));
    } else if (OB_ISNULL(full_key_part)) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_ERROR("full_key_part is null.", K(ret));
    } else {
O
obdev 已提交
237
      ObExprResType col_type(allocator_);
O
oceanbase-admin 已提交
238
      full_key_part->id_ = ObKeyPartId(table_id, OB_INVALID_ID);
O
obdev 已提交
239
      full_key_part->pos_.column_type_ = col_type;
O
oceanbase-admin 已提交
240 241 242 243 244 245 246 247 248 249
      table_graph_.key_part_head_ = full_key_part;
      column_count_ = range_columns.count();
    }
  }
  if (OB_SUCCESS != ret && NULL != query_range_ctx_) {
    destroy_query_range_ctx(allocator);
  }
  return ret;
}

W
wangzelin.wzl 已提交
250
void ObQueryRange::destroy_query_range_ctx(ObIAllocator &ctx_allocator)
O
oceanbase-admin 已提交
251 252
{
  if (NULL != query_range_ctx_) {
253 254 255 256 257 258
    for (int64_t i = 0; i < query_range_ctx_->key_part_pos_array_.count(); ++i) {
      if (NULL != query_range_ctx_->key_part_pos_array_.at(i)) {
        query_range_ctx_->key_part_pos_array_.at(i)->~ObKeyPartPos();
        ctx_allocator.free(query_range_ctx_->key_part_pos_array_.at(i));
      }
    }
O
oceanbase-admin 已提交
259 260 261 262 263 264
    query_range_ctx_->~ObQueryRangeCtx();
    ctx_allocator.free(query_range_ctx_);
    query_range_ctx_ = NULL;
  }
}

W
wangzelin.wzl 已提交
265 266 267 268 269
int ObQueryRange::preliminary_extract_query_range(const ColumnIArray &range_columns,
                                                  const ObRawExpr *expr_root,
                                                  const ObDataTypeCastParams &dtc_params,
                                                  ObExecContext *exec_ctx,
                                                  ExprConstrantArray *expr_constraints /* = NULL */,
270 271
                                                  const ParamsIArray *params /* = NULL */,
                                                  const bool use_in_optimization /* = false */)
O
oceanbase-admin 已提交
272 273 274
{
  int ret = OB_SUCCESS;
  ObArenaAllocator ctx_allocator(ObModIds::OB_QUERY_RANGE_CTX);
275 276
  if (OB_FAIL(init_query_range_ctx(ctx_allocator, range_columns, exec_ctx, expr_constraints, params,
                                   false, true, use_in_optimization))) {
O
oceanbase-admin 已提交
277 278 279 280 281
    LOG_WARN("init query range context failed", K(ret));
  } else if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("query_range_ctx_ is not inited.", K(ret));
  } else {
O
obdev 已提交
282
    query_range_ctx_->need_final_extract_ = false;
283
    query_range_ctx_->only_one_expr_ = true;
W
wangzelin.wzl 已提交
284
    ObKeyPart *root = NULL;
O
oceanbase-admin 已提交
285 286 287 288
    if (OB_UNLIKELY(NULL == expr_root)) {
      //(MIN, MAX), whole range
      GET_ALWAYS_TRUE_OR_FALSE(true, root);
    } else {
289
      if (OB_FAIL(preliminary_extract(expr_root, root, dtc_params, T_OP_IN == expr_root->get_expr_type()))) {
O
oceanbase-admin 已提交
290 291 292 293
        LOG_WARN("gen table range failed", K(ret));
      } else if (query_range_ctx_->cur_expr_is_precise_ && root != NULL) {
        // for simple in_expr
        int64_t max_pos = -1;
O
obdev 已提交
294
        int64_t cur_pos = 0;
O
oceanbase-admin 已提交
295
        bool is_strict_equal = true;
O
obdev 已提交
296
        if (OB_FAIL(is_strict_equal_graph(root, cur_pos, max_pos, is_strict_equal))) {
O
oceanbase-admin 已提交
297 298 299 300
          LOG_WARN("is strict equal graph failed", K(ret));
        } else if (is_strict_equal) {
          ObRangeExprItem expr_item;
          expr_item.cur_expr_ = expr_root;
W
wangzelin.wzl 已提交
301
          for (const ObKeyPart *cur_and = root; OB_SUCC(ret) && cur_and != NULL; cur_and = cur_and->and_next_) {
O
obdev 已提交
302 303
            if (OB_FAIL(add_expr_offsets(expr_item.cur_pos_, cur_and))) {
              LOG_WARN("failed to add expr pos", K(ret));
O
oceanbase-admin 已提交
304 305 306 307 308 309
            }
          }
          if (OB_SUCC(ret) && OB_FAIL(query_range_ctx_->precise_range_exprs_.push_back(expr_item))) {
            LOG_WARN("store precise range exprs failed", K(ret));
          }
        } else if (NULL == root->and_next_ && is_general_graph(*root)) {
W
wangzelin.wzl 已提交
310 311 312 313
          //因为optimizer去filter只能够在顶端去,而且去filter的目标是合取范式
          //标准的合取范式例如(c1>1 or c1<0) and c2=1这样的表达式在resolver必须拆分成多个表达式
          //如果没有拆分,这样的表达式也不能被去掉,因为去表达式每次都是一个完整的表达式
          //这个表达式包含了多个键,要么全部去掉,要么都不去掉,显然全部去掉是不对的
O
oceanbase-admin 已提交
314 315
          ObRangeExprItem expr_item;
          expr_item.cur_expr_ = expr_root;
O
obdev 已提交
316 317
          if (OB_FAIL(add_expr_offsets(expr_item.cur_pos_, root))) {
            LOG_WARN("failed to add expr pos", K(ret));
O
oceanbase-admin 已提交
318 319 320 321 322 323
          } else if (OB_FAIL(query_range_ctx_->precise_range_exprs_.push_back(expr_item))) {
            LOG_WARN("store precise range exprs failed", K(ret));
          }
        }
      }
    }
Z
zs0 已提交
324
    if (OB_SUCC(ret) && NULL != root) {
O
obdev 已提交
325
      ObSqlBitSet<> key_offsets;
326
      if (OB_FAIL(refine_large_range_graph(root, use_in_optimization))) {
Z
zs0 已提交
327
        LOG_WARN("failed to refine large range graph", K(ret));
328 329
      } else if (OB_FAIL(check_graph_type(*root))) {
        LOG_WARN("check graph type failed", K(ret));
W
wangzelin.wzl 已提交
330
      } else if (OB_FAIL(generate_expr_final_info())) {
O
obdev 已提交
331
        LOG_WARN("failed to generate final exprs", K(ret));
O
oceanbase-admin 已提交
332 333 334 335
      }
    }
  }
  if (OB_SUCC(ret)) {
O
obdev 已提交
336
    if (query_range_ctx_->need_final_extract_) {
O
oceanbase-admin 已提交
337 338 339 340 341 342 343 344 345
      state_ = NEED_PREPARE_PARAMS;
    } else {
      state_ = CAN_READ;
    }
  }
  destroy_query_range_ctx(ctx_allocator);
  return ret;
}

O
obdev 已提交
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
int ObQueryRange::extract_valid_exprs(const ExprIArray &root_exprs, ObIArray<ObRawExpr *> &candi_exprs)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("query range not inited", K(ret));
  } else {
    ObSEArray<int64_t, 16> offsets;
    for (int64_t i = 0; OB_SUCC(ret) && i < root_exprs.count(); ++i) {
      bool is_valid_expr = false;
      bool tmp_need_extract_const = false;
      if (OB_FAIL(check_cur_expr(root_exprs.at(i), offsets,
                                 tmp_need_extract_const, is_valid_expr))) {
        LOG_WARN("failed to check current expr", K(ret));
      } else if (tmp_need_extract_const || is_valid_expr) {
        if (OB_FAIL(candi_exprs.push_back(root_exprs.at(i)))) {
          LOG_WARN("failed to push back candidate exprs", K(ret));
        }
      }
    }
    if (OB_SUCC(ret)) {
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
      if (offsets.count() != 0 || !query_range_ctx_->row_in_offsets_.empty()) {
        ObSEArray<int64_t, 4> common_offsets;
        if (OB_FAIL(ObOptimizerUtil::intersect(query_range_ctx_->row_in_offsets_, offsets, common_offsets))) {
          LOG_WARN("failed to intersect common offsets", K(ret));
        } else if (!common_offsets.empty()) {
          // (c1,c2) in () and c1 .. is not allowed to use in optimization
          query_range_ctx_->use_in_optimization_ = false;
        }
        if (OB_FAIL(ret)) {
        } else if (OB_FAIL(append_array_no_dup(offsets, query_range_ctx_->row_in_offsets_))) {
          LOG_WARN("failed to append array no dup", K(ret));
        } else {
          int64_t postfix_offset = -1;
          std::sort(offsets.begin(), offsets.end());
          int64_t idx = 0;
          for (; idx < offsets.count(); ++idx) {
            if (postfix_offset != -1) {
              if (offsets.at(idx) != postfix_offset + 1) {
                break;
              } else {
                postfix_offset = offsets.at(idx);
                query_range_ctx_->max_valid_offset_ = postfix_offset;
              }
            } else if (idx != offsets.at(idx)) {
O
obdev 已提交
391 392
              postfix_offset = offsets.at(idx);
              query_range_ctx_->max_valid_offset_ = postfix_offset;
393 394
            } else {
              query_range_ctx_->max_valid_offset_ = idx;
O
obdev 已提交
395 396 397 398
            }
          }
        }
      }
399 400
      LOG_TRACE("succeed to check need extract range",
            K(candi_exprs), K(offsets), K(query_range_ctx_->row_in_offsets_), K(query_range_ctx_->max_valid_offset_));
O
obdev 已提交
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
    }
  }
  return ret;
}

int ObQueryRange::check_cur_expr(const ObRawExpr *cur_expr, ObIArray<int64_t> &offsets,
                                 bool &need_extract_const, bool &is_valid_expr)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(cur_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else if (cur_expr->is_const_expr()) {
    need_extract_const = true;
  } else {
    const ObOpRawExpr *op_expr = static_cast<const ObOpRawExpr *>(cur_expr);
    ObItemType cmp_type = cur_expr->get_expr_type();
    if (T_OP_OR == cmp_type || T_OP_AND == cmp_type) {
      for (int64_t i = 0; OB_SUCC(ret) && i < op_expr->get_param_count(); ++i) {
        if (OB_ISNULL(op_expr->get_param_expr(i))) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get unexpected null", K(ret));
        } else if (OB_FAIL(check_cur_expr(op_expr->get_param_expr(i), offsets,
                                          need_extract_const, is_valid_expr))) {
          LOG_WARN("failed to check and or", K(ret));
        }
      }
    } else if (cur_expr->is_spatial_expr()) {
      is_valid_expr = true;
    } else if (IS_BASIC_CMP_OP(cmp_type) || T_OP_NE == cmp_type ||
               T_OP_IS == cmp_type || T_OP_IN == cmp_type || T_OP_NOT_IN == cmp_type) {
      const ObRawExpr *l_expr = op_expr->get_param_expr(0);
      const ObRawExpr *r_expr = op_expr->get_param_expr(1);
      if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret), K(l_expr), K(r_expr));
      } else if ((T_OP_LIKE == cmp_type) &&
          (OB_UNLIKELY(3 != op_expr->get_param_count()) || OB_ISNULL(op_expr->get_param_expr(2)))) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get invalid arguments", K(ret), K(cmp_type), K(*op_expr));
      } else if (T_OP_ROW == l_expr->get_expr_type()) {
        if (OB_FAIL(extract_row_info(l_expr, r_expr,
                                     cmp_type, offsets,
                                     need_extract_const,
                                     is_valid_expr))) {
          LOG_WARN("failed to extract row info", K(ret));
        }
      } else {
        if (OB_FAIL(extract_basic_info(l_expr, r_expr,
                                       cmp_type, offsets,
                                       need_extract_const,
                                       is_valid_expr))) {
          LOG_WARN("failed to extract basic info", K(ret));
        }
      }
    } else if (T_OP_BTW == cmp_type || T_OP_NOT_BTW == cmp_type) {
      if (OB_UNLIKELY(3 != op_expr->get_param_count())) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get invalid argument", K(ret));
      } else {
        for (int64_t i = 0; OB_SUCC(ret) && i < op_expr->get_param_count(); ++i) {
          const ObRawExpr *param = op_expr->get_param_expr(i);
          if (OB_ISNULL(param)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("get unexpected null", K(ret));
          } else if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(param, param))) {
            LOG_WARN("failed to get expr without lossless cast", K(ret));
          } else if (param->is_column_ref_expr()) {
            const ObColumnRefRawExpr *col_expr = static_cast<const ObColumnRefRawExpr *>(param);
            ObKeyPartId id(col_expr->get_table_id(), col_expr->get_column_id());
471
            ObKeyPartPos *pos = nullptr;
O
obdev 已提交
472 473 474 475 476
            bool b_key_part;
            if (OB_FAIL(is_key_part(id, pos, b_key_part))) {
              LOG_WARN("failed to get key part", K(ret));
            } else if (b_key_part) {
              is_valid_expr = true;
477 478 479 480 481 482
              if (OB_ISNULL(pos)) {
                ret = OB_ERR_UNEXPECTED;
                LOG_WARN("get null key pos");
              } else if (OB_FAIL(add_var_to_array_no_dup(offsets, pos->offset_))) {
                LOG_WARN("failed to add var to array no dup");
              }
O
obdev 已提交
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 512 513 514
            }
          }
        }
      }
    }
  }
  return ret;
}

int ObQueryRange::extract_basic_info(const ObRawExpr *l_expr,
                                    const ObRawExpr *r_expr,
                                    const ObItemType &cmp_type,
                                    ObIArray<int64_t> &offsets,
                                    bool &need_extract_const,
                                    bool &is_valid_expr)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(l_expr), K(r_expr));
  } else if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(l_expr, l_expr))) {
    LOG_WARN("failed to get expr without lossless cast", K(ret));
  } else if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(r_expr, r_expr))) {
    LOG_WARN("failed to get expr without lossless cast", K(ret));
  } else if (l_expr->is_const_expr() && r_expr->is_const_expr()) {
    need_extract_const = true;
  } else if (l_expr->has_flag(IS_COLUMN) && r_expr->has_flag(IS_COLUMN)) {
    // always true
  } else if (T_OP_IN == cmp_type || T_OP_NOT_IN == cmp_type) {
    if (l_expr->is_column_ref_expr()) {
      const ObColumnRefRawExpr *col_expr = static_cast<const ObColumnRefRawExpr *>(l_expr);
      ObKeyPartId key_part_id(col_expr->get_table_id(), col_expr->get_column_id());
515
      ObKeyPartPos *key_part_pos = nullptr;
O
obdev 已提交
516 517 518 519 520
      bool b_key_part = false;
      if (OB_FAIL(is_key_part(key_part_id, key_part_pos, b_key_part))) {
        LOG_WARN("failed to get key part", K(ret));
      } else if (!b_key_part) {
        // do nothing
521 522 523 524
      } else if (OB_ISNULL(key_part_pos)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get null key part pos");
      } else if (OB_FAIL(add_var_to_array_no_dup(offsets, key_part_pos->offset_))) {
O
obdev 已提交
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
        LOG_WARN("failed to add key part offset", K(ret));
      } else {
        is_valid_expr = true;
      }
    } else if (l_expr->has_flag(IS_ROWID)) {
      ObSEArray<const ObColumnRefRawExpr *, 4> pk_column_items;
      bool is_physical_rowid = false;
      uint64_t part_column_id = common::OB_INVALID_ID;
      uint64_t table_id = common::OB_INVALID_ID;
      if (OB_FAIL(get_extract_rowid_range_infos(l_expr,
                                                pk_column_items,
                                                is_physical_rowid,
                                                table_id,
                                                part_column_id))) {
        LOG_WARN("failed to get extract rowid range infos");
      } else if (OB_FAIL(check_can_extract_rowid(pk_column_items,
                                                 is_physical_rowid,
                                                 table_id,
                                                 part_column_id,
                                                 offsets,
                                                 is_valid_expr))) {
        LOG_WARN("failed to check can extract rowid range", K(ret));
      }
    }
  } else if ((l_expr->has_flag(IS_COLUMN) && r_expr->is_const_expr())
        || (l_expr->is_const_expr() && r_expr->has_flag(IS_COLUMN))) {
    const ObColumnRefRawExpr *col_expr = NULL;
    const ObRawExpr *const_expr = NULL;
    bool b_is_key_part = false;
    if (l_expr->has_flag(IS_COLUMN)) {
      col_expr = static_cast<const ObColumnRefRawExpr *>(l_expr);
      const_expr = r_expr;
    } else if (r_expr->has_flag(IS_COLUMN)) {
      col_expr = static_cast<const ObColumnRefRawExpr *>(r_expr);
      const_expr = l_expr;
    }
    ObKeyPartId key_part_id(col_expr->get_table_id(), col_expr->get_column_id());
562
    ObKeyPartPos *key_part_pos = nullptr;
O
obdev 已提交
563 564 565 566
    if (OB_FAIL(is_key_part(key_part_id, key_part_pos, b_is_key_part))) {
      LOG_WARN("failed to check is key part", K(ret));
    } else if (!b_is_key_part || OB_UNLIKELY(!const_expr->is_const_expr())) {
      // always true
567 568 569 570
    } else if (OB_ISNULL(key_part_pos)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get null key part pos");
    } else if (OB_FAIL(add_var_to_array_no_dup(offsets, key_part_pos->offset_))) {
O
obdev 已提交
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
      LOG_WARN("failed to add key part offset", K(ret));
    } else {
      is_valid_expr = true;
    }
  } else if (((l_expr->has_flag(IS_ROWID) && r_expr->is_const_expr())
        || (r_expr->has_flag(IS_ROWID) && l_expr->is_const_expr())) && T_OP_LIKE != cmp_type) {
    ObSEArray<const ObColumnRefRawExpr *, 4> pk_column_items;
    bool is_physical_rowid = false;
    uint64_t part_column_id = common::OB_INVALID_ID;
    uint64_t table_id = common::OB_INVALID_ID;

    const ObRawExpr *calc_urowid_expr = NULL;
    if (OB_UNLIKELY(r_expr->has_flag(IS_ROWID))) {
      calc_urowid_expr = r_expr;
    } else if (l_expr->has_flag(IS_ROWID)) {
      calc_urowid_expr = l_expr;
    }
    if (OB_FAIL(get_extract_rowid_range_infos(calc_urowid_expr,
                                              pk_column_items,
                                              is_physical_rowid,
                                              table_id,
                                              part_column_id))) {
      LOG_WARN("failed to get extract rowid range infos");
    } else if (OB_FAIL(check_can_extract_rowid(pk_column_items,
                                               is_physical_rowid,
                                               table_id,
                                               part_column_id,
                                               offsets,
                                               is_valid_expr))) {
      LOG_WARN("failed to check can extract rowid range", K(ret));
    }
  }
  return ret;
}

int ObQueryRange::check_can_extract_rowid(const ObIArray<const ObColumnRefRawExpr *> &pk_column_items,
                                          const bool is_physical_rowid,
                                          const uint64_t table_id,
                                          const uint64_t part_column_id,
                                          ObIArray<int64_t> &offsets,
                                          bool &is_valid_expr)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("get invalid query range ctx", K(ret));
  } else {
    for (int64_t i = 0; OB_SUCC(ret) && i < pk_column_items.count(); ++i) {
      const ObColumnRefRawExpr *col_expr = pk_column_items.at(i);
      bool b_key_part = false;
      bool cur_valid = false;
      if (OB_ISNULL(col_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret));
      } else {
        ObKeyPartId key_part_id(col_expr->get_table_id(), col_expr->get_column_id());
627
        ObKeyPartPos *key_part_pos = nullptr;
O
obdev 已提交
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
        if (OB_FAIL(is_key_part(key_part_id, key_part_pos, b_key_part))) {
          LOG_WARN("failed to get key part", K(ret));
        } else if (b_key_part) {
          cur_valid = true;
        } else if (is_physical_rowid &&
                  query_range_ctx_->phy_rowid_for_table_loc_ &&
                  part_column_id != common::OB_INVALID_ID) {
          key_part_id.table_id_ = table_id;
          key_part_id.column_id_ = part_column_id;
          if (OB_FAIL(is_key_part(key_part_id, key_part_pos, b_key_part))) {
            LOG_WARN("failed to get key part", K(ret));
          } else {
            cur_valid = b_key_part;
          }
        }
        if (OB_SUCC(ret) && cur_valid) {
          is_valid_expr = true;
645 646 647 648 649 650
          if (OB_ISNULL(key_part_pos)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("get null key part pos");
          } else if (OB_FAIL(add_var_to_array_no_dup(offsets, key_part_pos->offset_))) {
            LOG_WARN("failed to add var to array no dup", K(ret));
          }
O
obdev 已提交
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
        }
      }
    }
  }
  return ret;
}

int ObQueryRange::extract_row_info(const ObRawExpr *l_expr,
                                    const ObRawExpr *r_expr,
                                    const ObItemType &cmp_type,
                                    ObIArray<int64_t> &offsets,
                                    bool &need_extract_const,
                                    bool &is_valid_expr)
{
  int ret = OB_SUCCESS;
666
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr) || OB_ISNULL(query_range_ctx_)) {
O
obdev 已提交
667
    ret = OB_ERR_UNEXPECTED;
668
    LOG_WARN("get unexpected null", K(ret), K(l_expr), K(r_expr), K(query_range_ctx_));
O
obdev 已提交
669 670 671 672 673 674 675 676 677 678 679
  } else if (lib::is_oracle_mode()) {
    if (T_OP_ROW == r_expr->get_expr_type() &&
        1 == r_expr->get_param_count() &&
        T_OP_ROW == r_expr->get_param_expr(0)->get_expr_type()) {
      r_expr = r_expr->get_param_expr(0);
    }
  }
  if (OB_SUCC(ret)) {
    const ObOpRawExpr *l_row = static_cast<const ObOpRawExpr *>(l_expr);
    const ObOpRawExpr *r_row = static_cast<const ObOpRawExpr *>(r_expr);
    if (T_OP_IN == cmp_type || T_OP_NOT_IN == cmp_type) {
680 681
      ObSEArray<int64_t, 4> common_offsets;
      ObSEArray<int64_t, 4> tmp_offsets;
O
obdev 已提交
682 683 684 685 686 687 688 689
      for (int64_t i = 0; OB_SUCC(ret) && i < l_row->get_param_count(); ++i) {
        const ObRawExpr *r_param = r_row->get_param_expr(0);
        if (OB_ISNULL(r_param) || OB_UNLIKELY(l_row->get_param_count() != r_param->get_param_count())) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get unexpected null", K(ret));
        } else if (OB_FAIL(extract_basic_info(l_row->get_param_expr(i),
                                              r_param->get_param_expr(i),
                                              cmp_type,
690
                                              tmp_offsets,
O
obdev 已提交
691 692 693 694 695 696
                                              need_extract_const,
                                              is_valid_expr))) {
          LOG_WARN("failed to extract single offset", K(ret),
                    K(i), K(l_row), K(r_row), K(cmp_type));
        }
      }
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
      if (OB_FAIL(ret)) {
      } else if (T_OP_NOT_IN == cmp_type) {
        if (OB_FAIL(append_array_no_dup(offsets, tmp_offsets))) {
          LOG_WARN("failed to append array no dup", K(ret));
        }
      } else if (query_range_ctx_->use_in_optimization_ && !query_range_ctx_->row_in_offsets_.empty()) {
        if (OB_FAIL(ObOptimizerUtil::intersect(query_range_ctx_->row_in_offsets_,
                                               tmp_offsets,
                                               common_offsets))) {
          LOG_WARN("failed to intersect offsets", K(ret));
        } else if (!common_offsets.empty()) {
          // (c1,c2) in and (c1,c3) in can not use in optimization
          query_range_ctx_->use_in_optimization_ = false;
        }
      }
      if (OB_SUCC(ret) && T_OP_IN == cmp_type &&
          OB_FAIL(append_array_no_dup(query_range_ctx_->row_in_offsets_, tmp_offsets))) {
        LOG_WARN("failed to append row_in offsets", K(ret));
      }
O
obdev 已提交
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
    } else {
      for (int64_t i = 0; OB_SUCC(ret) && i < r_row->get_param_count(); ++i) {
        if (OB_FAIL(extract_basic_info(l_row->get_param_expr(i),
                                        r_row->get_param_expr(i),
                                        cmp_type,
                                        offsets,
                                        need_extract_const,
                                        is_valid_expr))) {
          LOG_WARN("failed to extract single offset", K(ret),
                    K(i), K(l_row), K(r_row), K(cmp_type));
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
733 734 735 736 737 738 739
int ObQueryRange::preliminary_extract_query_range(const ColumnIArray &range_columns,
                                                  const ExprIArray &root_exprs,
                                                  const ObDataTypeCastParams &dtc_params,
                                                  ObExecContext *exec_ctx,
                                                  ExprConstrantArray *expr_constraints /* = NULL */,
                                                  const ParamsIArray *params /* = NULL */,
                                                  const bool phy_rowid_for_table_loc /* = false*/,
740 741
                                                  const bool ignore_calc_failure /* = true*/,
                                                  const bool use_in_optimization /* = false */)
O
oceanbase-admin 已提交
742 743 744
{
  int ret = OB_SUCCESS;
  ObKeyPartList and_ranges;
W
wangzelin.wzl 已提交
745
  ObKeyPart *temp_result = NULL;
O
obdev 已提交
746
  has_exec_param_ = false;
O
obdev 已提交
747 748
  ObKeyPartList geo_ranges;
  bool has_geo_expr = false;
749
  SQL_REWRITE_LOG(DEBUG, "preliminary extract", K(range_columns), K(root_exprs), K(use_in_optimization));
O
obdev 已提交
750
  ObSEArray<ObRawExpr *, 16> candi_exprs;
O
oceanbase-admin 已提交
751
  ObArenaAllocator ctx_allocator(ObModIds::OB_QUERY_RANGE_CTX);
W
wangzelin.wzl 已提交
752 753
  if (OB_FAIL(init_query_range_ctx(ctx_allocator, range_columns, exec_ctx,
                                   expr_constraints, params, phy_rowid_for_table_loc,
754
                                   ignore_calc_failure, use_in_optimization))) {
O
oceanbase-admin 已提交
755 756 757 758
    LOG_WARN("init query range context failed", K(ret));
  } else if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("query_range_ctx_ is not inited.", K(ret));
O
obdev 已提交
759 760 761 762 763 764 765 766
  } else if (OB_FAIL(extract_valid_exprs(root_exprs, candi_exprs))) {
    LOG_WARN("failed to extract candidate range exprs", K(ret));
  } else if (candi_exprs.empty()) {
    GET_ALWAYS_TRUE_OR_FALSE(true, temp_result);
    if (OB_SUCC(ret) && !and_ranges.add_last(temp_result)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("add key part range failed", K(ret));
    }
O
oceanbase-admin 已提交
767
  } else {
768
    query_range_ctx_->only_one_expr_ = candi_exprs.count() == 1;
O
obdev 已提交
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
    for (int64_t i = 0; OB_SUCC(ret) && i < candi_exprs.count(); ++i) {
      const ObRawExpr *cur_expr = candi_exprs.at(i);
      if (OB_ISNULL(cur_expr)) {
        // continue
      } else if (OB_FAIL(preliminary_extract(cur_expr, temp_result, dtc_params,
                                             T_OP_IN == cur_expr->get_expr_type()))) {
        LOG_WARN("Generate table range failed", K(ret));
      } else if (NULL == temp_result) {
        // ignore the condition from which we can not extract query range
      } else if (cur_expr->has_flag(CNT_DYNAMIC_PARAM) &&
                  OB_FALSE_IT(has_exec_param_ = true)) {
      } else if (is_contain_geo_filters()) {
        // or connect with spatial filters for functional correctness
        has_geo_expr = true;
        if (OB_FAIL(add_or_item(geo_ranges, temp_result))) {
          LOG_WARN("Link geo keypart failed", K(ret));
        }
      } else if (!and_ranges.add_last(temp_result)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("Add key part range failed", K(ret));
      } else if (query_range_ctx_->cur_expr_is_precise_) {
        if (is_strict_in_graph(temp_result)) {
          ObRangeExprItem expr_item;
          expr_item.cur_expr_ = cur_expr;
          for (const ObKeyPart *cur_and = temp_result; OB_SUCC(ret) && cur_and != NULL;
                                                       cur_and = cur_and->and_next_) {
            if (OB_FAIL(add_expr_offsets(expr_item.cur_pos_, cur_and))) {
              LOG_WARN("failed to add expr pos", K(ret));
O
obdev 已提交
797
            }
O
obdev 已提交
798 799 800 801 802 803 804 805 806 807 808 809
          }
          if (OB_SUCC(ret) &&
              OB_FAIL(query_range_ctx_->precise_range_exprs_.push_back(expr_item))) {
            LOG_WARN("store precise range exprs failed", K(ret));
          }
        } else if (NULL == temp_result->and_next_ && is_general_graph(*temp_result)) {
          ObRangeExprItem expr_item;
          expr_item.cur_expr_ = cur_expr;
          for (const ObKeyPart *cur_or = temp_result; OB_SUCC(ret) && cur_or != NULL;
                                                      cur_or = cur_or->or_next_) {
            if (OB_FAIL(add_expr_offsets(expr_item.cur_pos_, cur_or))) {
              LOG_WARN("failed to add expr pos", K(ret));
O
oceanbase-admin 已提交
810 811
            }
          }
O
obdev 已提交
812 813 814 815
          if (OB_SUCC(ret) &&
              OB_FAIL(query_range_ctx_->precise_range_exprs_.push_back(expr_item))) {
            LOG_WARN("store precise range exprs failed", K(ret));
          }
O
oceanbase-admin 已提交
816
        }
W
wangzelin.wzl 已提交
817
      } // for each where condition
O
oceanbase-admin 已提交
818 819 820
    }
  }
  if (OB_SUCC(ret)) {
O
obdev 已提交
821 822 823 824 825 826 827 828 829 830 831
    if (has_geo_expr) {
      ObKeyPart *geo_results = NULL;
      if (OB_FAIL(or_range_graph(geo_ranges, NULL, geo_results, dtc_params))) {
        LOG_WARN("or range graph failed", K(ret));
      } else if (!and_ranges.add_last(geo_results)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("add key part range failed", K(ret));
      }
    }
    if (OB_FAIL(ret)) {
    } else if (OB_FAIL(and_range_graph(and_ranges, temp_result))) {
O
oceanbase-admin 已提交
832
      LOG_WARN("And query range failed", K(ret));
833
    } else if (OB_FAIL(refine_large_range_graph(temp_result, use_in_optimization))) {
Z
zs0 已提交
834
      LOG_WARN("failed to refine large range graph", K(ret));
835 836
    } else if (OB_FAIL(check_graph_type(*temp_result))) {
      LOG_WARN("check graph type failed", K(ret));
837
    } else if (!is_reach_mem_limit_ && OB_FAIL(generate_expr_final_info())) {
W
wangzelin.wzl 已提交
838
      LOG_WARN("failed to generate final exprs");
O
oceanbase-admin 已提交
839 840
    }
  }
841

O
oceanbase-admin 已提交
842
  if (OB_SUCC(ret)) {
O
obdev 已提交
843
    if (query_range_ctx_->need_final_extract_) {
O
oceanbase-admin 已提交
844 845 846
      state_ = NEED_PREPARE_PARAMS;
    } else {
      state_ = CAN_READ;
847 848 849 850 851 852 853 854 855 856
      // If query range need final extract, final stage will perform FINAL_EXTRACT() to merge
      // duplicate range. If final extract doesn't needed, or_range_graph is needed here to
      // merge duplicate range.
      ObKeyPartList or_array;
      if (!or_array.add_last(temp_result)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("Add query graph to list failed", K(ret));
      } else if (OB_FAIL(or_range_graph(or_array, exec_ctx, temp_result, dtc_params))) {
        LOG_WARN("Do OR of range graph failed", K(ret));
      }
O
oceanbase-admin 已提交
857 858
    }
  }
W
wangzelin.wzl 已提交
859 860 861 862
  destroy_query_range_ctx(ctx_allocator);
  return ret;
}

O
obdev 已提交
863
int ObQueryRange::add_expr_offsets(ObIArray<int64_t> &cur_pos, const ObKeyPart *cur_key)
W
wangzelin.wzl 已提交
864 865
{
  int ret = OB_SUCCESS;
O
obdev 已提交
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
  if (OB_ISNULL(cur_key)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else if (cur_key->is_in_key()) {
    if (OB_FAIL(append_array_no_dup(cur_pos, cur_key->in_keypart_->offsets_))) {
      LOG_WARN("failed to append offset", K(ret));
    }
  } else if (OB_FAIL(add_var_to_array_no_dup(cur_pos, cur_key->pos_.offset_))) {
    LOG_WARN("push back key index failed", K(ret));
  }
  return ret;
}

int ObQueryRange::remove_useless_range_graph(ObKeyPart *key_part, ObSqlBitSet<> &valid_offsets)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(key_part)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("keypart is null", K(ret), K(key_part));
  } else if (key_part->is_always_true() || key_part->is_always_false()) {
    // do nothing
  } else {
    ObKeyPart *cur = key_part;
    while (cur != NULL && OB_SUCC(ret)) {
C
chaser-ch 已提交
890
      if (OB_FAIL(set_valid_offsets(cur, &valid_offsets))) {
O
obdev 已提交
891 892 893 894 895 896 897 898 899 900 901 902 903 904
        LOG_WARN("failed to set valid offsets", K(ret));
      }
      int64_t max_valid_offset = get_max_valid_offset(valid_offsets);
      ObKeyPart *cur_key = cur;
      while (OB_SUCC(ret) && cur_key != NULL) {
        ObKeyPart *and_next = cur_key->and_next_;
        if (is_and_next_useless(cur_key, and_next, max_valid_offset)) {
          LOG_TRACE("remove useless keypart",
                K(*cur_key), K(*and_next), K(max_valid_offset));
          ObKeyPart *tmp = cur_key;
          while (NULL != tmp && and_next == tmp->and_next_) {
            tmp->and_next_ = NULL;
            tmp = tmp->or_next_;
          }
W
wangzelin.wzl 已提交
905
        }
O
obdev 已提交
906 907 908 909 910 911
        cur_key = cur_key->and_next_;
      }
      if (OB_FAIL(ret) || cur == NULL) {
        // do nothing
      } else if (OB_FAIL(remove_and_next_offset(cur, valid_offsets))) {
        LOG_WARN("failed to remove and next offsets", K(ret));
W
wangzelin.wzl 已提交
912
      } else {
O
obdev 已提交
913
        cur = cur->or_next_;
W
wangzelin.wzl 已提交
914
      }
O
oceanbase-admin 已提交
915 916 917 918 919
    }
  }
  return ret;
}

O
obdev 已提交
920
bool ObQueryRange::is_and_next_useless(ObKeyPart *cur_key, ObKeyPart *and_next, const int64_t max_valid_offset)
W
wangzelin.wzl 已提交
921 922
{
  bool is_useless = false;
O
obdev 已提交
923 924 925 926 927 928 929 930 931 932 933
  if (and_next != NULL && cur_key != NULL) {
    int64_t and_next_offset = and_next->is_in_key() ?
                              and_next->in_keypart_->get_min_offset() :
                              and_next->pos_.offset_;
    if (max_valid_offset != -1 && and_next_offset > max_valid_offset) {
      is_useless = true;
      for (ObKeyPart *tmp = cur_key; is_useless && NULL != tmp &&
                                     and_next == tmp->and_next_; tmp = tmp->or_next_) {
        // c3 can be extracted for predicates like c1 > 1 and c3 op/in X
        is_useless = tmp->is_equal_condition();
      }
W
wangzelin.wzl 已提交
934 935 936 937 938
    }
  }
  return is_useless;
}

Z
zs0 已提交
939
// if the range size is large then RANGE_MAX_SIZE, remove some ranges according to pos_.offset_
940
int ObQueryRange::refine_large_range_graph(ObKeyPart *&key_part, bool use_in_optimization)
Z
zs0 已提交
941 942 943 944 945 946 947 948 949
{
  int ret = OB_SUCCESS;
  ObSEArray<ObKeyPart*, 8> pre_key_parts;
  ObSEArray<ObKeyPart*, 8> key_parts;
  ObSEArray<uint64_t, 8> or_count;
  ObSEArray<ObKeyPart*, 8> next_key_parts;
  ObSEArray<uint64_t, 8> next_or_count;
  uint64_t cur_range_size = 1;
  bool need_refine = false;
950
  int64_t max_range_size = use_in_optimization ? MAX_RANGE_SIZE_NEW : MAX_RANGE_SIZE_OLD;
Z
zs0 已提交
951 952 953 954 955 956 957 958 959 960 961 962 963
  if (OB_ISNULL(key_part)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("keypart is null", K(ret), K(key_part));
  } else if (OB_FAIL(key_parts.push_back(key_part)) ||
             OB_FAIL(next_key_parts.push_back(key_part))) {
    LOG_WARN("failed to push back", K(ret));
  } else if (OB_FAIL(or_count.push_back(1))) {
    LOG_WARN("failed to push back", K(ret));
  }
  while (OB_SUCC(ret) && !next_key_parts.empty() && !need_refine) {
    if (OB_FAIL(compute_range_size(key_parts, or_count, next_key_parts, next_or_count,
                                   cur_range_size))) {
      LOG_WARN("failed to compute range size", K(ret));
964
    } else if (cur_range_size > max_range_size) {
Z
zs0 已提交
965 966 967 968 969 970 971 972 973
      need_refine = true;
    } else if (OB_FAIL(pre_key_parts.assign(key_parts))) {
      LOG_WARN("failed to assign array", K(ret), K(key_parts));
    } else if (OB_FAIL(key_parts.assign(next_key_parts))) {
      LOG_WARN("failed to assign array", K(ret), K(next_key_parts));
    } else if (OB_FAIL(or_count.assign(next_or_count))) {
      LOG_WARN("failed to assign array", K(ret), K(next_or_count));
    } else { /* do nothing */ }
  }
974
  range_size_ = need_refine ? max_range_size :
O
obdev 已提交
975
                cur_range_size < RANGE_BUCKET_SIZE ? RANGE_BUCKET_SIZE : cur_range_size;
Z
zs0 已提交
976
  if (OB_SUCC(ret) && need_refine) {
O
obdev 已提交
977
    ObKeyPart *first_keypart = NULL;
Z
zs0 已提交
978 979 980 981 982 983 984
    if (pre_key_parts.empty()) {
      // first or_next_ list size is large than RANGE_MAX_SIZE, create a full key part
      ObKeyPart *new_key = NULL;
      if (OB_FAIL(alloc_full_key_part(new_key))) {
        LOG_WARN("alloc full key part failed", K(ret));
      } else if (OB_ISNULL(new_key)) {
        ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
985
        LOG_WARN("keypart is null", K(ret));
Z
zs0 已提交
986 987 988 989 990
      } else if (OB_FAIL(remove_precise_range_expr(0))) {
        LOG_WARN("remove precise range expr failed", K(ret));
      } else {
        new_key->id_ = key_part->id_;
        key_part = new_key;
K
Klawz 已提交
991
        LOG_TRACE("refine large query range with full key", K(cur_range_size));
Z
zs0 已提交
992
      }
O
obdev 已提交
993
    } else if (OB_ISNULL(first_keypart = pre_key_parts.at(0))) {
Z
zs0 已提交
994 995 996
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get unexpected input", K(ret), K(pre_key_parts));
    } else {
O
obdev 已提交
997 998 999 1000 1001 1002 1003
      int64_t redundant_offset = first_keypart->is_in_key() ?
                                 first_keypart->in_keypart_->get_min_offset() + 1 :
                                 first_keypart->pos_.offset_ + 1;
      if (OB_FAIL(remove_precise_range_expr(redundant_offset))) {
        LOG_WARN("remove precise range expr failed", K(ret));
      } else {
        // remove key part after pre key parts
K
Klawz 已提交
1004
        LOG_TRACE("refine large query range remove some key parts",
O
obdev 已提交
1005 1006 1007 1008 1009 1010 1011
                  K(cur_range_size), K(redundant_offset));
        ObKeyPart *cur = NULL;;
        ObKeyPart *and_next = NULL;
        for (int64_t i = 0; OB_SUCC(ret) && i < pre_key_parts.count(); ++i) {
          cur = pre_key_parts.at(i);
          while (NULL != cur) {
            if (NULL == cur->and_next_) {
Z
zs0 已提交
1012
              cur = cur->or_next_;
O
obdev 已提交
1013 1014 1015 1016 1017 1018
            } else {
              and_next = cur->and_next_;
              while (NULL != cur && cur->and_next_ == and_next) {
                cur->and_next_ = NULL;
                cur = cur->or_next_;
              }
Z
zs0 已提交
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
            }
          }
        }
      }
    }
  }
  return ret;
}

int ObQueryRange::compute_range_size(const ObIArray<ObKeyPart*> &key_parts,
                                     const ObIArray<uint64_t> &or_count,
                                     ObIArray<ObKeyPart*> &next_key_parts,
                                     ObIArray<uint64_t> &next_or_count,
                                     uint64_t &range_size)
{
  int ret = OB_SUCCESS;
  next_key_parts.reuse();
  next_or_count.reuse();
  ObKeyPart *pre = NULL;
  ObKeyPart *cur = NULL;
  uint64_t count = 0;
  if (OB_UNLIKELY(key_parts.empty()) || OB_UNLIKELY(key_parts.count() != or_count.count())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected input", K(ret), K(key_parts.count()), K(or_count.count()));
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < key_parts.count(); ++i) {
    if (OB_ISNULL(pre = key_parts.at(i))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get unexpected null", K(ret), K(i), K(key_parts.at(i)));
    } else {
      range_size -= or_count.at(i);
      cur = pre->or_next_;
O
obdev 已提交
1051
      count = pre->is_in_key() ? pre->in_keypart_->get_param_val_cnt() : 1;
Z
zs0 已提交
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
    }
    while (OB_SUCC(ret) && NULL != pre) {
      if (NULL != cur && cur->and_next_ == pre->and_next_) {
        cur = cur->or_next_;
        ++count;
      } else if (NULL != pre->and_next_ &&
                 OB_FAIL(next_key_parts.push_back(pre->and_next_))) {
        LOG_WARN("failed to push back", K(ret));
      } else if (NULL != pre->and_next_ &&
                 OB_FAIL(next_or_count.push_back(or_count.at(i) * count))) {
        LOG_WARN("failed to push back", K(ret));
      } else {
        range_size += or_count.at(i) * count;
        pre = cur;
        cur = NULL != cur ? cur->or_next_ : NULL;
O
obdev 已提交
1067
        count = (NULL != pre && pre->is_in_key()) ? pre->in_keypart_->get_param_val_cnt() : 1;
Z
zs0 已提交
1068 1069 1070 1071 1072 1073 1074
      }
    }
  }
  return ret;
}

int ObQueryRange::is_get(bool &is_range_get) const
O
oceanbase-admin 已提交
1075 1076 1077 1078
{
  return is_get(column_count_, is_range_get);
}

W
wangzelin.wzl 已提交
1079 1080
int ObQueryRange::is_get(int64_t column_count,
                         bool &is_range_get) const
O
oceanbase-admin 已提交
1081 1082 1083
{
  int ret = OB_SUCCESS;
  is_range_get = true;
O
obdev 已提交
1084 1085
  ObSqlBitSet<> valid_offsets;
  ObKeyPart *key_head = table_graph_.key_part_head_;
O
oceanbase-admin 已提交
1086 1087
  if (table_graph_.is_precise_get_) {
    // return true
O
obdev 已提交
1088 1089
  } else if (OB_UNLIKELY(NULL == key_head) ||
             key_head->is_always_true() || key_head->is_always_false()) {
O
oceanbase-admin 已提交
1090
    is_range_get = false;
C
chaser-ch 已提交
1091
  } else if (OB_FAIL(set_valid_offsets(key_head, &valid_offsets))) {
O
obdev 已提交
1092 1093 1094 1095
    LOG_WARN("failed to set valid offsets", K(ret));
  } else if (OB_FAIL(check_is_get(*key_head,
                                  column_count, is_range_get,
                                  valid_offsets))) {
O
oceanbase-admin 已提交
1096 1097 1098 1099 1100
    LOG_WARN("failed to check is get", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
1101 1102
int ObQueryRange::check_is_get(ObKeyPart &key_part,
                               const int64_t column_count,
O
obdev 已提交
1103 1104
                               bool &bret,
                               ObSqlBitSet<> &valid_offsets) const
O
oceanbase-admin 已提交
1105 1106
{
  int ret = OB_SUCCESS;
O
obdev 已提交
1107
  if (bret == true) {
1108
    for (ObKeyPart *cur_part = &key_part; OB_SUCC(ret) && bret && cur_part != NULL; cur_part = cur_part->or_next_) {
C
chaser-ch 已提交
1109
      if (cur_part != &key_part && OB_FAIL(set_valid_offsets(cur_part, &valid_offsets))) {
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
        LOG_WARN("failed to set valid offsets", K(ret));
      } else if (valid_offsets.num_members() != column_count) {
        bret = false;
      } else if (cur_part->is_in_key()) {
        if (NULL != cur_part->and_next_) {
          ret = SMART_CALL(check_is_get(*cur_part->and_next_,
                                        column_count,
                                        bret,
                                        valid_offsets));
        }
      } else if (!cur_part->is_equal_condition()) {
        bret = false;
      } else if (NULL != cur_part->and_next_) {
        ret = SMART_CALL(check_is_get(*cur_part->and_next_,
O
obdev 已提交
1124 1125 1126 1127
                                      column_count,
                                      bret,
                                      valid_offsets));
      }
1128 1129 1130
      if (OB_SUCC(ret) && bret) {
        if (OB_FAIL(remove_cur_offset(cur_part, valid_offsets))) {
          LOG_WARN("failed to remove cur offset", K(ret));
O
obdev 已提交
1131 1132
        }
      }
O
oceanbase-admin 已提交
1133 1134 1135 1136 1137
    }
  }
  return ret;
}

1138 1139 1140
//  1. check range graph type: is_standard_range_/is_equal_range_/is_precise_get_/is_skip_scan_
//  3. remove useless key part
int ObQueryRange::check_graph_type(ObKeyPart &key_part_head)
O
oceanbase-admin 已提交
1141 1142
{
  int ret = OB_SUCCESS;
1143
  int64_t max_pos = -1;
O
obdev 已提交
1144
  int64_t cur_pos = 0;
1145 1146 1147 1148 1149 1150 1151
  int64_t max_precise_pos = -1;
  int64_t ss_max_precise_pos = -1;
  table_graph_.key_part_head_ = &key_part_head;
  table_graph_.is_standard_range_ = is_standard_graph(&key_part_head);
  table_graph_.is_precise_get_ = is_precise_get(key_part_head, max_precise_pos);
  table_graph_.skip_scan_offset_ = -1;
  ObKeyPart *ss_head = NULL;
O
obdev 已提交
1152
  ObSqlBitSet<> key_offsets;
1153 1154 1155 1156 1157 1158 1159
  if (OB_FAIL(check_skip_scan_range(&key_part_head,
                                    table_graph_.is_standard_range_,
                                    max_precise_pos,
                                    ss_head,
                                    table_graph_.skip_scan_offset_,
                                    ss_max_precise_pos))) {
    LOG_WARN("failed to check skip scan", K(ret));
O
obdev 已提交
1160
  } else if (OB_FAIL(is_strict_equal_graph(&key_part_head, cur_pos, max_pos, table_graph_.is_equal_range_))) {
1161
    LOG_WARN("is strict equal graph failed", K(ret));
O
obdev 已提交
1162
  } else if (OB_FAIL(remove_useless_range_graph(is_ss_range() ? ss_head : &key_part_head, key_offsets))) {
1163 1164 1165 1166 1167
    LOG_WARN("failed to remove useless range", K(ret));
  } else if (OB_FAIL(remove_precise_range_expr(is_ss_range() ? ss_max_precise_pos : max_precise_pos))) {
    LOG_WARN("remove precise range expr failed", K(ret));
  } else if (OB_FAIL(fill_range_exprs(max_precise_pos, table_graph_.skip_scan_offset_, ss_max_precise_pos))) {
    LOG_WARN("failed to fill range exprs", K(ret));
O
oceanbase-admin 已提交
1168
  }
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
  return ret;
}

int ObQueryRange::check_skip_scan_range(ObKeyPart *key_part_head,
                                        const bool is_standard_range,
                                        const int64_t max_precise_pos,
                                        ObKeyPart *&ss_head,
                                        int64_t &skip_scan_offset,
                                        int64_t &ss_max_precise_pos)
{
  int ret = OB_SUCCESS;
  ss_head = NULL;
  skip_scan_offset = -1;
  ss_max_precise_pos = -1;
  if (!is_standard_range) {
    /* only standard range can extract skip scan range */
  } else {
    ObKeyPart *cur = key_part_head;
    // skip prefix precise range
    while (NULL != cur && cur->pos_.offset_ < max_precise_pos) {
      cur = cur->and_next_;
O
oceanbase-admin 已提交
1190
    }
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
    if (NULL != cur) {
      ss_head = cur;
      skip_scan_offset = ss_head->pos_.offset_;
      is_precise_get(*ss_head, ss_max_precise_pos, true);
    }
  }
  return ret;
}

int ObQueryRange::reset_skip_scan_range()
{
  int ret = OB_SUCCESS;
  if (-1 == table_graph_.skip_scan_offset_) {
    /* do nothing */
  } else if (OB_ISNULL(table_graph_.key_part_head_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret), K(table_graph_.key_part_head_));
  } else {
O
obdev 已提交
1209
    ObSqlBitSet<> key_offsets;
1210 1211 1212 1213
    int64_t max_precise_pos = -1;
    table_graph_.is_precise_get_ = is_precise_get(*table_graph_.key_part_head_, max_precise_pos);
    table_graph_.skip_scan_offset_ = -1;
    ss_range_exprs_.reset();
O
obdev 已提交
1214
    if (OB_FAIL(remove_useless_range_graph(table_graph_.key_part_head_, key_offsets))) {
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
      LOG_WARN("failed to remove useless range", K(ret));
    } else if (OB_FAIL(remove_precise_range_expr(max_precise_pos))) {
      LOG_WARN("remove precise range expr failed", K(ret));
    }
  }
  return ret;
}

bool ObQueryRange::is_precise_get(const ObKeyPart &key_part_head,
                                  int64_t &max_precise_pos,
                                  bool ignore_head /* = false */)
{
  bool is_precise_get = true;
  int64_t max_pos = -1;
  int64_t depth = ignore_head ? key_part_head.pos_.offset_ - 1 : -1;
  bool is_terminated = false;
W
wangt1xiuyi 已提交
1231
  bool is_phy_rowid_key_part = false;
1232
  for (const ObKeyPart *cur = &key_part_head; !is_terminated && NULL != cur; cur = cur->and_next_) {
O
obdev 已提交
1233 1234 1235 1236
    if (cur->is_in_key()) {
      if (cur->in_keypart_->is_strict_in_ &&
          cur->in_keypart_->get_min_offset() == (++depth)) {
        depth = cur->in_keypart_->get_max_offset();
1237 1238 1239 1240
        if (is_precise_get) {
          is_precise_get = (cur->in_keypart_->is_in_precise_get() &&
                            cur->or_next_ == NULL && cur->item_next_ == NULL);
        }
O
obdev 已提交
1241 1242 1243 1244 1245 1246
      } else {
        is_precise_get = false;
        max_pos = cur->in_keypart_->get_min_offset();
        is_terminated = true;
      }
    } else if (cur->pos_.offset_ != (++depth)) {
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
      is_precise_get = false;
      max_pos = depth;
      is_terminated = true;
    } else if (NULL != cur->or_next_ || NULL != cur->item_next_) {
      is_precise_get = false;
    } else if (cur->is_like_key() || cur->is_geo_key()) {
      is_precise_get = false;
    } else if (!cur->is_equal_condition()) {
      is_precise_get = false;
    } else {
W
wangt1xiuyi 已提交
1257
      is_phy_rowid_key_part = cur->is_phy_rowid_key_part();
1258 1259 1260 1261 1262
    }
    if (!is_terminated) {
      if (is_strict_in_graph(cur)) {
        // do nothing
      } else if (!is_general_graph(*cur)) {
O
obdev 已提交
1263 1264
        max_pos = cur->is_in_key() ? cur->in_keypart_->get_min_offset() + 1 :
                                       cur->pos_.offset_ + 1;
1265 1266
        is_terminated = true;
      } else if (has_scan_key(*cur)) {
O
obdev 已提交
1267 1268
        max_pos = cur->is_in_key() ? cur->in_keypart_->get_min_offset() + 1 :
                                       cur->pos_.offset_ + 1;
1269
        is_terminated = true;
W
wangzelin.wzl 已提交
1270
      }
O
oceanbase-admin 已提交
1271 1272
    }
  }
1273 1274

  max_precise_pos = is_terminated ? max_pos : depth + 1;
W
wangt1xiuyi 已提交
1275
  if (is_precise_get && depth != column_count_ - 1 && !is_phy_rowid_key_part) {
1276
    is_precise_get = false;
O
oceanbase-admin 已提交
1277
  }
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
  return is_precise_get;
}

int ObQueryRange::fill_range_exprs(const int64_t max_precise_pos,
                                   const int64_t ss_offset,
                                   const int64_t ss_max_precise_pos)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("query isn't init", K_(query_range_ctx));
  } else {
    ObSEArray<ObRawExpr*, 4> range_exprs;
    ObSEArray<ObRawExpr*, 4> ss_range_exprs;
    bool precise = true;
    bool ss_precise = true;
    for (int64_t i = 0; OB_SUCC(ret) && i < query_range_ctx_->precise_range_exprs_.count(); ++i) {
      precise = true;
      ss_precise = is_ss_range();
      ObRangeExprItem &expr_item = query_range_ctx_->precise_range_exprs_.at(i);
      for (int64_t j = 0 ; (precise || ss_precise) && j < expr_item.cur_pos_.count() ; ++j) {
        if (expr_item.cur_pos_.at(j) >= max_precise_pos) {
          precise = false;
        }
        if (ss_precise && (expr_item.cur_pos_.at(j) < ss_offset || expr_item.cur_pos_.at(j) >= ss_max_precise_pos)) {
          ss_precise = false;
        }
      }

      if (OB_SUCC(ret) && NULL != expr_item.cur_expr_) {
        if (precise && OB_FAIL(range_exprs.push_back(const_cast<ObRawExpr*>(expr_item.cur_expr_)))) {
          LOG_WARN("push back precise range expr failed", K(ret));
        } else if (ss_precise && OB_FAIL(ss_range_exprs.push_back(const_cast<ObRawExpr*>(expr_item.cur_expr_)))) {
          LOG_WARN("push back precise range expr failed", K(ret));
        }
O
oceanbase-admin 已提交
1313 1314
      }
    }
1315 1316 1317 1318 1319 1320 1321 1322 1323
    if (OB_FAIL(ret)) {
    } else if (OB_FAIL(range_exprs_.assign(range_exprs))) {
      LOG_WARN("failed to assign range exprs", K(ret));
    } else if (OB_FAIL(ss_range_exprs_.assign(ss_range_exprs))) {
      LOG_WARN("failed to assign skip scan range exprs", K(ret));
    } else {
      LOG_DEBUG("finish fill range exprs", K(max_precise_pos), K(range_exprs));
      LOG_DEBUG("finish fill skip scan range exprs", K(ss_offset), K(ss_max_precise_pos), K(ss_range_exprs));
    }
O
oceanbase-admin 已提交
1324 1325 1326 1327
  }
  return ret;
}

W
wangzelin.wzl 已提交
1328 1329 1330 1331 1332 1333 1334
//这个函数用来判断待抽取的表达式的column type和表达式的比较类型是否兼容,
//然后来判断该表达式到底是应该进行精确抽取还是放大成(min, max)
bool ObQueryRange::can_be_extract_range(ObItemType cmp_type,
                                        const ObExprResType &col_type,
                                        const ObExprCalcType &calc_type,
                                        ObObjType data_type,
                                        bool &always_true)
O
oceanbase-admin 已提交
1335 1336 1337
{
  bool bret = true;
  always_true = true;
W
wangzelin.wzl 已提交
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363
  //决定一个表达式能否运用我们的抽取规则的前提是进行抽取后的集合范围有没有比表达式表达的值域范围更小
  //对于一个表达式col compare const,比较类型calc_type决定了一个集合A(A中的元素是calc_type)满足关系,
  //而query range需要确定一个集合B(集合B中的元素都是column_type)被A包含,
  //这样才能让query range抽取的column value都满足这个表达式
  //而集合B是query range通过calc_type和column_type以及表达式抽取规则确定的一个集合
  //抽取的规则无论是类型的转换,还是字符集的转换,都只能做到一对一,例如int->varchar, 123被转换成'123',不会是'0123'
  //字符集UTF8MB4_GENERAL_CI'A'->UTF8MB4_BIN'A'而不会是UTF8MB4_BIN'a'
  //因此要满足col compare const这个表达式,如果column_type和calc_type不兼容,那么需要涉及到类型转换
  //能完整表达compare关系的表达式为:f1(col, calc_type) compare f2(const, calc_type)
  //f1表示将col的值从column_type映射到calc_type,因此要讨论集合A和集合B的关系,就是讨论f1的映射关系
  //影响集合范围的因素可能是类型和字符集,而字符集只有在字符串类型才有意义
  //第一种情况:
  //如果column_type和calc_type的类型相同并且字符集也相同(如果为字符串类型),那么f1是一一映射关系
  //也就是集合A=集合B
  //第二种情况:
  //如果column_type是大小写敏感的字符集,而calc_type是大小写不敏感的字符集,那么f1就是一个一对多的关系
  //!f1就是一个多对一的关系,general_ci 'A'-> bin'a' or bin'A'那么通过query range规则推导出来的B包含于A,不满足假设,
  //因此这种情况query range的结果是全集(min, max)
  //第三种情况:
  //如果column_type是字符串类型,而calc_type是非字符串类型,由于两者的排序规则和转换规则不一,
  //f1是多对一的关系,例如'0123'->123, '123'->123,那么!f1是一对多的关系,也不满足假设,所以这种情况下query range结果也是全集(min, max)
  //第四种情况:
  //如果column_type是数值类型,而calc_type是字符串类型,通过第三种情况可知,数值类型到字符串类型的映射f1是
  //一对多的关系,那么!f1的关系是多对一的关系,而query range的抽取规则是一一映射的关系,任何一个属于集合A的元素
  //a都能唯一确定出一个值b在集合B中使表达式成立,因此第四种情况也是能够通过抽取规则抽取的
  //其它情况下的f1也都是一一映射关系,集合A=集合B,因此也能够使用抽取规则
O
oceanbase-admin 已提交
1364 1365 1366 1367
  if (T_OP_NSEQ == cmp_type && ObNullType == data_type) {
    bret = true;
  }
  if (bret && T_OP_NSEQ != cmp_type && ObNullType == data_type) {
W
wangzelin.wzl 已提交
1368
    //pk cmp null
O
oceanbase-admin 已提交
1369
    bret = false;
W
wangzelin.wzl 已提交
1370
    //视作恒false处理
O
oceanbase-admin 已提交
1371 1372 1373
    always_true = false;
  }
  if (bret && T_OP_LIKE == cmp_type) {
W
wangzelin.wzl 已提交
1374 1375 1376
    //只对string like string的形式进行抽取
    if ((! col_type.is_string_or_lob_locator_type())
      || (! calc_type.is_string_or_lob_locator_type())) {
O
oceanbase-admin 已提交
1377
      bret = false;
W
wangzelin.wzl 已提交
1378
      //不能进行规则抽取,将表达式视为恒true处理
O
oceanbase-admin 已提交
1379 1380 1381 1382 1383 1384
      always_true = true;
    }
  }
  if (bret) {
    bool is_cast_monotonic = false;
    int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1385 1386 1387 1388 1389
    //由于cast对于某些时间类型的某些值域有特殊处理,导致A cast B,不一定可逆,
    //一个表达式能够抽取,需要双向都满足cast单调
    if (OB_FAIL(ObObjCaster::is_cast_monotonic(col_type.get_type(),
                                                 calc_type.get_type(),
                                                 is_cast_monotonic))) {
O
oceanbase-admin 已提交
1390 1391 1392 1393
      LOG_WARN("check is cast monotonic failed", K(ret));
    } else if (!is_cast_monotonic) {
      bret = false;
      always_true = true;
W
wangzelin.wzl 已提交
1394 1395 1396
    } else if (OB_FAIL(ObObjCaster::is_cast_monotonic(calc_type.get_type(),
                                                        col_type.get_type(),
                                                        is_cast_monotonic))) {
O
oceanbase-admin 已提交
1397 1398 1399 1400
      LOG_WARN("check is cast monotonic failed", K(ret));
    } else if (!is_cast_monotonic) {
      bret = false;
      always_true = true;
W
wangzelin.wzl 已提交
1401 1402 1403 1404 1405
    } else if (calc_type.is_string_or_lob_locator_type()
               && col_type.is_string_or_lob_locator_type()) {
      if (T_OP_LIKE == cmp_type && col_type.is_nstring()) {
        bret = true;
      } else if (col_type.get_collation_type() != calc_type.get_collation_type()) {
O
oceanbase-admin 已提交
1406 1407 1408
        bret = false;
        always_true = true;
      }
X
xj0 已提交
1409 1410 1411
    } else if (calc_type.is_json() && col_type.is_json()) {
      bret = false;
      always_true = true;
O
oceanbase-admin 已提交
1412 1413 1414 1415
    }
  }
  return bret;
}
W
wangzelin.wzl 已提交
1416 1417 1418 1419 1420 1421 1422 1423

int ObQueryRange::get_const_key_part(const ObRawExpr *l_expr,
                                     const ObRawExpr *r_expr,
                                     const ObRawExpr *escape_expr,
                                     ObItemType cmp_type,
                                     const ObExprResType &result_type,
                                     ObKeyPart *&out_key_part,
                                     const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
1424 1425 1426 1427 1428
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr) || (OB_ISNULL(escape_expr) && T_OP_LIKE == cmp_type)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid argument.", K(ret), KP(l_expr), KP(r_expr));
1429
  } else if (!l_expr->is_immutable_const_expr() || !r_expr->is_immutable_const_expr()) {
W
wangzelin.wzl 已提交
1430
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
O
oceanbase-admin 已提交
1431
  } else {
W
wangzelin.wzl 已提交
1432 1433 1434 1435 1436
    ObObj l_val;
    ObObj r_val;
    bool l_valid = false;
    bool r_valid = false;
    const ObExprCalcType &calc_type = result_type.get_calc_meta();
O
oceanbase-admin 已提交
1437 1438
    ObCollationType cmp_cs_type = calc_type.get_collation_type();
    // '?' is const too, if " '?' cmp const ", we seem it as true now
W
wangzelin.wzl 已提交
1439 1440 1441 1442 1443
    if (OB_FAIL(get_calculable_expr_val(l_expr, l_val, l_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (OB_FAIL(get_calculable_expr_val(r_expr, r_val, r_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (!l_valid || !r_valid) {
O
oceanbase-admin 已提交
1444
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
W
wangzelin.wzl 已提交
1445 1446
    } else if (l_val.is_null() || r_val.is_null()) {
      if (l_val.is_null() && r_val.is_null() && T_OP_NSEQ == cmp_type) {
O
oceanbase-admin 已提交
1447 1448 1449 1450 1451 1452 1453 1454 1455
        GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
      } else {
        GET_ALWAYS_TRUE_OR_FALSE(false, out_key_part);
      }
    } else if (cmp_type >= T_OP_EQ && cmp_type <= T_OP_NE) {
      ObObjType compare_type = ObMaxType;
      int64_t eq_cmp = 0;
      ObCastMode cast_mode = CM_WARN_ON_FAIL;
      ObCastCtx cast_ctx(&allocator_, &dtc_params, cast_mode, cmp_cs_type);
W
wangzelin.wzl 已提交
1456 1457 1458
      if (OB_FAIL(ObExprResultTypeUtil::get_relational_cmp_type(compare_type,
                                                                l_val.get_type(),
                                                                r_val.get_type()))) {
O
oceanbase-admin 已提交
1459
        LOG_WARN("get compare type failed", K(ret));
W
wangzelin.wzl 已提交
1460 1461
      } else if (OB_FAIL(ObRelationalExprOperator::compare_nullsafe(eq_cmp, l_val, r_val,
                                                                    cast_ctx, compare_type, cmp_cs_type))) {
O
oceanbase-admin 已提交
1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480
        LOG_WARN("compare obj failed", K(ret));
      } else if (T_OP_EQ == cmp_type || T_OP_NSEQ == cmp_type) {
        GET_ALWAYS_TRUE_OR_FALSE(0 == eq_cmp, out_key_part);
      } else if (T_OP_LE == cmp_type) {
        GET_ALWAYS_TRUE_OR_FALSE(eq_cmp <= 0, out_key_part);
      } else if (T_OP_LT == cmp_type) {
        GET_ALWAYS_TRUE_OR_FALSE(eq_cmp < 0, out_key_part);
      } else if (T_OP_GE == cmp_type) {
        GET_ALWAYS_TRUE_OR_FALSE(eq_cmp >= 0, out_key_part);
      } else if (T_OP_GT == cmp_type) {
        GET_ALWAYS_TRUE_OR_FALSE(eq_cmp > 0, out_key_part);
      } else {
        GET_ALWAYS_TRUE_OR_FALSE(0 != eq_cmp, out_key_part);
      }
    } else if (T_OP_LIKE == cmp_type) {
      if (!escape_expr->is_const_expr()) {
        ret = OB_INVALID_ARGUMENT;
        LOG_WARN("escape_expr must be const expr", K(ret));
      } else {
W
wangzelin.wzl 已提交
1481 1482 1483 1484 1485 1486
        if (OB_FAIL(get_like_const_range(l_expr,
                                         r_expr,
                                         escape_expr,
                                         cmp_cs_type,
                                         out_key_part,
                                         dtc_params))) {
O
oceanbase-admin 已提交
1487 1488
          LOG_WARN("get like const range failed", K(ret));
        }
W
wangzelin.wzl 已提交
1489

O
oceanbase-admin 已提交
1490 1491
      }
    } else {
W
wangzelin.wzl 已提交
1492
      //do nothing
O
oceanbase-admin 已提交
1493 1494 1495 1496 1497
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
1498 1499 1500 1501 1502 1503 1504 1505 1506
// create table t1(c1 int primary key);
// table get:  select * from t1 where rowid = '*AAEPAQEAwAEAAAA=';#(int)(1)
// table scan: select * from t1 where rowid = '*AAEPAQEAwAEAAAAPAQEAwAEAAAA=';#(int,int)(1,1)
int ObQueryRange::get_rowid_key_part(const ObRawExpr *l_expr,
                                     const ObRawExpr *r_expr,
                                     const ObRawExpr *escape_expr,
                                     ObItemType cmp_type,
                                     ObKeyPart *&out_key_part,
                                     const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
1507 1508 1509 1510 1511 1512
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr) || (OB_ISNULL(escape_expr) && T_OP_LIKE == cmp_type)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid argument.", K(ret), KP(l_expr), KP(r_expr), KP(cmp_type));
  } else {
W
wangzelin.wzl 已提交
1513 1514 1515 1516 1517
    ObSEArray<const ObColumnRefRawExpr *, 4> pk_column_items;
    ObSEArray<ObObj, 4> pk_vals;
    const ObRawExpr *const_expr = NULL;
    ObObj const_val;
    bool is_valid = false;
O
oceanbase-admin 已提交
1518
    ObItemType c_type = cmp_type;
W
wangzelin.wzl 已提交
1519 1520 1521 1522 1523 1524
    bool is_physical_rowid = false;
    uint64_t table_id = common::OB_INVALID_ID;
    uint64_t part_column_id = common::OB_INVALID_ID;

    const ObRawExpr *calc_urowid_expr = NULL;
    if (OB_UNLIKELY(r_expr->has_flag(IS_ROWID))) {
O
oceanbase-admin 已提交
1525
      const_expr = l_expr;
W
wangzelin.wzl 已提交
1526 1527 1528 1529
      c_type = (T_OP_LE == cmp_type ? T_OP_GE : (T_OP_GE == cmp_type ? T_OP_LE :
                                                 (T_OP_LT == cmp_type ? T_OP_GT : (T_OP_GT == cmp_type ? T_OP_LT : cmp_type))));
      calc_urowid_expr = r_expr;
    } else if (l_expr->has_flag(IS_ROWID)) {
O
oceanbase-admin 已提交
1530 1531
      const_expr = r_expr;
      c_type = cmp_type;
W
wangzelin.wzl 已提交
1532 1533
      calc_urowid_expr = l_expr;
    }
1534
    if (!const_expr->is_immutable_const_expr()) {
O
obdev 已提交
1535
      query_range_ctx_->need_final_extract_ = true;
W
wangzelin.wzl 已提交
1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
    }
    if (OB_SUCC(ret)) {
      if (OB_FAIL(get_extract_rowid_range_infos(calc_urowid_expr,
                                                pk_column_items,
                                                is_physical_rowid,
                                                table_id,
                                                part_column_id))) {
        LOG_WARN("failed to get extract rowid range infos");
      } else if (OB_FAIL(get_calculable_expr_val(const_expr, const_val, is_valid, false))) {
        LOG_WARN("failed to get calculable expr val", K(ret));
      } else if (!is_valid) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("rowid expr should not calc failed", K(ret));
      }
    }
    if (OB_SUCC(ret) && OB_NOT_NULL(query_range_ctx_->params_) &&
        !const_expr->has_flag(CNT_DYNAMIC_PARAM)) {
      ObObj val = const_val;
      if (val.is_urowid()) {
O
obdev 已提交
1555 1556
        if (OB_FAIL(check_rowid_val(pk_column_items, val, is_physical_rowid))) {
          LOG_WARN("failed to check rowid", K(ret));
W
wangzelin.wzl 已提交
1557 1558
        }
      }
O
oceanbase-admin 已提交
1559
    }
W
wangzelin.wzl 已提交
1560 1561 1562 1563
    if (OB_SUCC(ret)) {
      ObKeyPart *tmp_key_part = NULL;
      ObKeyPartList key_part_list;
      ObObj val;
1564
      if (const_expr->is_immutable_const_expr()) {
W
wangzelin.wzl 已提交
1565
        val = const_val;
O
oceanbase-admin 已提交
1566
      } else {
W
wangzelin.wzl 已提交
1567 1568 1569 1570
        if (OB_FAIL(get_final_expr_val(const_expr, val))) {
          LOG_WARN("failed to get final expr idx", K(ret));
        }
      }
1571 1572 1573 1574 1575 1576 1577 1578 1579
      if (is_physical_rowid && column_count_ != 1 && !query_range_ctx_->phy_rowid_for_table_loc_) {
        GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
      } else {
        for (int64_t i = 0; OB_SUCC(ret) && i < pk_column_items.count(); ++i) {
          const ObColumnRefRawExpr *column_item = pk_column_items.at(i);
          ObKeyPartId key_part_id(column_item->get_table_id(), column_item->get_column_id());
          ObKeyPartPos *key_part_pos = nullptr;
          bool b_is_key_part = false;
          tmp_key_part = NULL;
W
wangzelin.wzl 已提交
1580 1581
          if (OB_FAIL(is_key_part(key_part_id, key_part_pos, b_is_key_part))) {
            LOG_WARN("is_key_part failed", K(ret));
1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592
          } else if (!b_is_key_part) {
            if (is_physical_rowid &&
                query_range_ctx_->phy_rowid_for_table_loc_ &&
                table_id != common::OB_INVALID_ID &&
                part_column_id != common::OB_INVALID_ID) {
              key_part_id.table_id_ = table_id;
              key_part_id.column_id_ = part_column_id;
            }
            if (OB_FAIL(is_key_part(key_part_id, key_part_pos, b_is_key_part))) {
              LOG_WARN("is_key_part failed", K(ret));
            }
W
wangzelin.wzl 已提交
1593
          }
1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
          if (OB_FAIL(ret) || !b_is_key_part) {
            GET_ALWAYS_TRUE_OR_FALSE(true, tmp_key_part);
          } else if (OB_ISNULL(key_part_pos)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("get null key part pos");
          } else if (OB_ISNULL((tmp_key_part = create_new_key_part()))) {
            ret = OB_ALLOCATE_MEMORY_FAILED;
            LOG_ERROR("alloc memory failed", K(ret));
          } else {
            ObObj tmp_val = val;
            tmp_key_part->rowid_column_idx_ = i;
            tmp_key_part->is_phy_rowid_key_part_ = is_physical_rowid;
            tmp_key_part->id_ = key_part_id;
            tmp_key_part->pos_ = *key_part_pos;
            tmp_key_part->null_safe_ = false;
            //if current expr can be extracted to range, just store the expr
            if (c_type != T_OP_LIKE) {
              bool is_inconsistent_rowid = false;
              if (tmp_val.is_urowid()) {
                if (OB_FAIL(get_result_value_with_rowid(*tmp_key_part,
                                                        tmp_val,
                                                        *query_range_ctx_->exec_ctx_,
                                                        is_inconsistent_rowid))) {
                  LOG_WARN("failed to get result value", K(ret));
                } else if (is_inconsistent_rowid) {
                  GET_ALWAYS_TRUE_OR_FALSE(false, tmp_key_part);
                }
              }
              if (OB_FAIL(ret) || is_inconsistent_rowid) {
              } else if (OB_FAIL(get_normal_cmp_keypart(c_type, tmp_val, *tmp_key_part))) {
                LOG_WARN("get normal cmp keypart failed", K(ret));
W
wangzelin.wzl 已提交
1625
              }
1626
            }
W
wangzelin.wzl 已提交
1627
          }
1628 1629 1630 1631 1632 1633 1634
          if (OB_FAIL(ret)) {
          } else if (OB_FAIL(add_and_item(key_part_list, tmp_key_part))) {
            LOG_WARN("Add basic query key part failed", K(ret));
          } else if (pk_column_items.count() - 1 == i &&
                    OB_FAIL(and_range_graph(key_part_list, out_key_part))) {
            LOG_WARN("and basic query key part failed", K(ret));
          }
W
wangzelin.wzl 已提交
1635
        }
O
oceanbase-admin 已提交
1636 1637
      }
    }
W
wangzelin.wzl 已提交
1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675
    LOG_TRACE("succeed to get rowid key part", KPC(out_key_part));
  }
  return ret;
}

int ObQueryRange::get_extract_rowid_range_infos(const ObRawExpr *calc_urowid_expr,
                                                ObIArray<const ObColumnRefRawExpr*> &pk_columns,
                                                bool &is_physical_rowid,
                                                uint64_t &table_id,
                                                uint64_t &part_column_id)
{
  int ret = OB_SUCCESS;
  is_physical_rowid = false;
  table_id = common::OB_INVALID_ID;
  part_column_id = common::OB_INVALID_ID;
  if (OB_ISNULL(calc_urowid_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(calc_urowid_expr));
  } else {
    for (int64_t i = 0; OB_SUCC(ret) && i < calc_urowid_expr->get_param_count(); ++i) {
      if (calc_urowid_expr->get_param_expr(i)->has_flag(IS_COLUMN)) {
        const ObColumnRefRawExpr * col_expr =
                       static_cast<const ObColumnRefRawExpr *>(calc_urowid_expr->get_param_expr(i));
        table_id = col_expr->get_table_id();
        // pk_vals may store generated col which is partition key but not primary key
        if (!col_expr->is_rowkey_column()) {
          /*do nothing*/
        } else if (OB_FAIL(pk_columns.push_back(col_expr))) {
          LOG_WARN("push back pk_column item failed", K(ret));
        } else {/*do nothing*/}
      } else if (calc_urowid_expr->get_param_expr(i)->get_expr_type() == T_FUN_SYS_CALC_TABLET_ID) {
        ObSEArray<ObRawExpr *, 4> column_exprs;
        if (OB_FAIL(ObRawExprUtils::extract_column_exprs(calc_urowid_expr->get_param_expr(i),
                                                         column_exprs))) {
          LOG_WARN("get column exprs error", K(ret));
        } else {
          is_physical_rowid = true;
          bool find_it = false;
O
obdev 已提交
1676
          for (int64_t j = 0; OB_SUCC(ret) && !find_it && j < column_exprs.count(); ++j) {
W
wangzelin.wzl 已提交
1677
            ObColumnRefRawExpr *col_expr = NULL;
O
obdev 已提交
1678
            if (OB_ISNULL(col_expr = static_cast<ObColumnRefRawExpr*>(column_exprs.at(j)))) {
W
wangzelin.wzl 已提交
1679 1680 1681 1682
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("get unexpected null", K(ret), K(col_expr));
            } else {
              ObKeyPartId id(col_expr->get_table_id(), col_expr->get_column_id());
1683
              ObKeyPartPos *pos = nullptr;
O
obdev 已提交
1684 1685 1686 1687
              bool b_key_part = false;
              if (OB_FAIL(is_key_part(id, pos, b_key_part))) {
                LOG_WARN("failed to check is key part", K(ret));
              } else if (b_key_part) {
W
wangzelin.wzl 已提交
1688 1689 1690
                find_it = true;
                table_id = col_expr->get_table_id();
                part_column_id = col_expr->get_column_id();
O
obdev 已提交
1691
              }
W
wangzelin.wzl 已提交
1692 1693 1694 1695 1696
            }
          }
        }
      } else {/*do nothing*/}
    }
O
obdev 已提交
1697
    LOG_TRACE("get extract rowid range infos", K(is_physical_rowid), K(part_column_id),
W
wangzelin.wzl 已提交
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708
                                               K(pk_columns), KPC(calc_urowid_expr));
  }
  return ret;
}

int ObQueryRange::get_column_key_part(const ObRawExpr *l_expr,
                                      const ObRawExpr *r_expr,
                                      const ObRawExpr *escape_expr,
                                      ObItemType cmp_type,
                                      const ObExprResType &result_type,
                                      ObKeyPart *&out_key_part,
1709 1710
                                      const ObDataTypeCastParams &dtc_params,
                                      bool &is_bound_modified)
W
wangzelin.wzl 已提交
1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr) || (OB_ISNULL(escape_expr) && T_OP_LIKE == cmp_type)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid argument.", K(ret), KP(l_expr), KP(r_expr), KP(cmp_type));
  } else {
    const ObColumnRefRawExpr *column_item = NULL;
    const ObRawExpr *const_expr = NULL;
    const ObExprCalcType &calc_type = result_type.get_calc_meta();
    ObItemType c_type = cmp_type;
    ObObj const_val;
    bool is_valid = true;
    if (OB_UNLIKELY(r_expr->has_flag(IS_COLUMN))) {
      column_item = static_cast<const ObColumnRefRawExpr *>(r_expr);
      const_expr = l_expr;
      c_type = (T_OP_LE == cmp_type ? T_OP_GE : (T_OP_GE == cmp_type ? T_OP_LE :
                                                 (T_OP_LT == cmp_type ? T_OP_GT : (T_OP_GT == cmp_type ? T_OP_LT : cmp_type))));
    } else if (l_expr->has_flag(IS_COLUMN)) {
      column_item = static_cast<const ObColumnRefRawExpr *>(l_expr);
      const_expr = r_expr;
      c_type = cmp_type;
    }
1733
    if (!const_expr->is_immutable_const_expr()) {
O
obdev 已提交
1734
      query_range_ctx_->need_final_extract_ = true;
W
wangzelin.wzl 已提交
1735
    }
O
obdev 已提交
1736
    ObKeyPartId id(column_item->get_table_id(), column_item->get_column_id());
1737
    ObKeyPartPos *pos = nullptr;
O
oceanbase-admin 已提交
1738 1739
    bool b_is_key_part = false;
    bool always_true = true;
O
obdev 已提交
1740
    if (OB_FAIL(is_key_part(id, pos, b_is_key_part))) {
O
oceanbase-admin 已提交
1741
      LOG_WARN("is_key_part failed", K(ret));
O
obdev 已提交
1742
    } else if (!b_is_key_part || OB_UNLIKELY(!const_expr->is_const_expr())) {
W
wangzelin.wzl 已提交
1743
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
1744 1745 1746 1747
    } else if (OB_ISNULL(pos)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get null key part pos");
    } else if (!can_be_extract_range(cmp_type, pos->column_type_, calc_type,
W
wangzelin.wzl 已提交
1748
                                     const_expr->get_result_type().get_type(), always_true)) {
O
oceanbase-admin 已提交
1749
      GET_ALWAYS_TRUE_OR_FALSE(always_true, out_key_part);
W
wangzelin.wzl 已提交
1750 1751 1752 1753
    } else if (OB_FAIL(get_calculable_expr_val(const_expr, const_val, is_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (!is_valid) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
O
oceanbase-admin 已提交
1754 1755 1756 1757 1758
    } else if (OB_ISNULL((out_key_part = create_new_key_part()))) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_ERROR("alloc memory failed", K(ret));
    } else {
      ObObj val;
O
obdev 已提交
1759
      out_key_part->id_ = id;
1760
      out_key_part->pos_ = *pos;
O
oceanbase-admin 已提交
1761
      out_key_part->null_safe_ = (T_OP_NSEQ == c_type);
1762
      if (const_expr->is_immutable_const_expr()
W
wangzelin.wzl 已提交
1763 1764
          || (!const_expr->has_flag(CNT_DYNAMIC_PARAM)
              && T_OP_LIKE == c_type
1765
              && NULL != query_range_ctx_->params_)) {
W
wangzelin.wzl 已提交
1766 1767 1768 1769
        val = const_val;
      } else {
        if (OB_FAIL(get_final_expr_val(const_expr, val))) {
          LOG_WARN("failed to get final expr idx", K(ret));
O
oceanbase-admin 已提交
1770 1771
        }
      }
W
wangzelin.wzl 已提交
1772
      //if current expr can be extracted to range, just store the expr
O
oceanbase-admin 已提交
1773 1774 1775 1776 1777 1778
      if (OB_SUCC(ret)) {
        if (c_type != T_OP_LIKE) {
          if (OB_FAIL(get_normal_cmp_keypart(c_type, val, *out_key_part))) {
            LOG_WARN("get normal cmp keypart failed", K(ret));
          }
        } else {
W
wangzelin.wzl 已提交
1779 1780 1781 1782 1783 1784
          ObObj escape_val;
          is_valid = false;
          if (OB_FAIL(get_calculable_expr_val(escape_expr, escape_val, is_valid))) {
            LOG_WARN("failed to get calculable expr val", K(ret));
          } else if (!is_valid) {
            GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
1785 1786
          } else if (!const_expr->is_immutable_const_expr() ||
                     !escape_expr->is_immutable_const_expr()) {
O
oceanbase-admin 已提交
1787 1788
            if (OB_FAIL(out_key_part->create_like_key())) {
              LOG_WARN("create like key part failed", K(ret));
W
wangzelin.wzl 已提交
1789 1790 1791 1792
            } else if (OB_FAIL(get_final_expr_val(const_expr, out_key_part->like_keypart_->pattern_))) {
              LOG_WARN("failed to get final expr idx", K(ret));
            } else if (OB_FAIL(get_final_expr_val(escape_expr, out_key_part->like_keypart_->escape_))) {
              LOG_WARN("failed to get final expr idx", K(ret));
1793
            } else if (!escape_expr->is_immutable_const_expr()) {
O
obdev 已提交
1794
              query_range_ctx_->need_final_extract_ = true;
W
wangzelin.wzl 已提交
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815
            } else {
              // do nothing
            }
            if (OB_SUCC(ret) &&
                (NULL != query_range_ctx_->params_) &&
                !const_expr->has_flag(CNT_DYNAMIC_PARAM) &&
                !escape_expr->has_flag(CNT_DYNAMIC_PARAM)) {
              char escape_ch = 0x00;
              if (escape_val.is_null()) {
                escape_ch = '\\';
              } else {
                escape_ch = (escape_val.get_string_len()==0)?0x00:*(escape_val.get_string_ptr());
              }

              if (OB_FAIL(ret)) {
                // do nothing
              } else if(val.is_null()) {
                query_range_ctx_->cur_expr_is_precise_ = false;
              } else if(OB_FAIL(ObQueryRange::is_precise_like_range(val,
                                              escape_ch,
                                              query_range_ctx_->cur_expr_is_precise_))) {
K
Klawz 已提交
1816
                LOG_WARN("failed to judge whether is precise", K(ret));
W
wangzelin.wzl 已提交
1817 1818 1819
              } else if (OB_FAIL(add_precise_constraint(const_expr,
                                                        query_range_ctx_->cur_expr_is_precise_))) {
                LOG_WARN("failed to add precise constraint", K(ret));
O
obdev 已提交
1820 1821
              } else if (OB_FAIL(add_prefix_pattern_constraint(const_expr))) {
                LOG_WARN("failed to add prefix pattern constraint", K(ret));
W
wangzelin.wzl 已提交
1822
              }
O
oceanbase-admin 已提交
1823 1824
            }
          } else {
W
wangzelin.wzl 已提交
1825
            if (OB_FAIL(get_like_range(val, escape_val, *out_key_part, dtc_params))) {
O
oceanbase-admin 已提交
1826 1827 1828
              LOG_WARN("get like range failed", K(ret));
            }
          }
W
wangzelin.wzl 已提交
1829 1830
          if (OB_SUCC(ret) && is_oracle_mode()) {
            // NChar like Nchar, Char like Char is not precise due to padding blank characters
1831
            ObObjType column_type = pos->column_type_.get_type();
W
wangzelin.wzl 已提交
1832 1833 1834 1835 1836 1837
            ObObjType const_type = const_expr->get_result_type().get_type();
            if ((ObCharType == column_type && ObCharType == const_type) ||
                (ObNCharType == column_type && ObNCharType == const_type)) {
              query_range_ctx_->cur_expr_is_precise_ = false;
            }
          }
O
oceanbase-admin 已提交
1838 1839
        }
        if (OB_SUCC(ret) && out_key_part->is_normal_key() && !out_key_part->is_question_mark()) {
1840
          if (OB_FAIL(out_key_part->cast_value_type(dtc_params, contain_row_, is_bound_modified))) {
O
oceanbase-admin 已提交
1841 1842 1843 1844 1845
            LOG_WARN("cast keypart value type failed", K(ret));
          } else {
            // do nothing
          }
        }
1846
        if (OB_SUCC(ret) && OB_FAIL(check_expr_precise(out_key_part, const_expr, calc_type, *pos))) {
O
obdev 已提交
1847
          LOG_WARN("failed to check expr precise", K(ret));
O
oceanbase-admin 已提交
1848 1849 1850 1851 1852 1853 1854
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
1855 1856 1857
int ObQueryRange::get_normal_cmp_keypart(ObItemType cmp_type,
                                         const ObObj &val,
                                         ObKeyPart &out_keypart) const
O
oceanbase-admin 已提交
1858 1859
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1860 1861
  bool always_false = false;
  //精确的range expr
O
oceanbase-admin 已提交
1862 1863
  if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
O
obdev 已提交
1864
    LOG_WARN("query range context is null", K(ret));
O
oceanbase-admin 已提交
1865 1866 1867 1868
  } else if (OB_FAIL(out_keypart.create_normal_key())) {
    LOG_WARN("create normal key failed", K(ret));
  } else if (OB_ISNULL(out_keypart.normal_keypart_)) {
    ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
1869
    LOG_WARN("normal keypart is null", K(ret));
W
wangzelin.wzl 已提交
1870 1871
  } else if (val.is_null() && T_OP_NSEQ != cmp_type) {
    always_false = true;
O
oceanbase-admin 已提交
1872 1873 1874
  } else if (T_OP_EQ == cmp_type || T_OP_NSEQ == cmp_type) {
    out_keypart.normal_keypart_->include_start_ = true;
    out_keypart.normal_keypart_->include_end_ = true;
O
obdev 已提交
1875 1876
    out_keypart.normal_keypart_->start_ = val;
    out_keypart.normal_keypart_->end_ = val;
O
oceanbase-admin 已提交
1877
  } else if (T_OP_LE == cmp_type || T_OP_LT == cmp_type) {
W
wangzelin.wzl 已提交
1878 1879 1880 1881
    //index order in storage is, Null is greater than min, less than the value of any meaningful
    //c1 < val doesn't contain Null -> (NULL, val)
    if (lib::is_oracle_mode()) {
      // Oracle 存储层使用 NULL Last
O
oceanbase-admin 已提交
1882 1883 1884 1885 1886 1887 1888 1889 1890
      out_keypart.normal_keypart_->start_.set_min_value();
    } else {
      out_keypart.normal_keypart_->start_.set_null();
    }
    out_keypart.normal_keypart_->end_ = val;
    out_keypart.normal_keypart_->include_start_ = false;
    out_keypart.normal_keypart_->include_end_ = (T_OP_LE == cmp_type);
  } else if (T_OP_GE == cmp_type || T_OP_GT == cmp_type) {
    out_keypart.normal_keypart_->start_ = val;
W
wangzelin.wzl 已提交
1891 1892
    if (lib::is_oracle_mode()) {
      // Oracle 存储层使用 NULL Last
O
oceanbase-admin 已提交
1893 1894 1895 1896 1897 1898 1899 1900 1901
      out_keypart.normal_keypart_->end_.set_null();
    } else {
      out_keypart.normal_keypart_->end_.set_max_value();
    }
    out_keypart.normal_keypart_->include_start_ = (T_OP_GE == cmp_type);
    out_keypart.normal_keypart_->include_end_ = false;
  }
  if (OB_SUCC(ret)) {
    query_range_ctx_->cur_expr_is_precise_ = true;
W
wangzelin.wzl 已提交
1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912
    if (!always_false) {
      out_keypart.normal_keypart_->always_false_ = false;
      out_keypart.normal_keypart_->always_true_ = false;
    } else {
      out_keypart.normal_keypart_->start_.set_max_value();
      out_keypart.normal_keypart_->end_.set_min_value();
      out_keypart.normal_keypart_->include_start_ = false;
      out_keypart.normal_keypart_->include_end_ = false;
      out_keypart.normal_keypart_->always_false_ = true;
      out_keypart.normal_keypart_->always_true_ = false;
    }
O
oceanbase-admin 已提交
1913 1914 1915 1916
  }
  return ret;
}

O
obdev 已提交
1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937
int ObQueryRange::get_geo_single_keypart(const ObObj &val_start, const ObObj &val_end, ObKeyPart &out_keypart) const
{
  int ret = OB_SUCCESS;
  if (OB_FAIL(out_keypart.create_normal_key())) {
    LOG_WARN("create normal key failed", K(ret));
  } else if (OB_ISNULL(out_keypart.normal_keypart_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("normal keypart is null");
  } else {
    out_keypart.normal_keypart_->include_start_ = true;
    out_keypart.normal_keypart_->include_end_ = true;
    out_keypart.normal_keypart_->start_ = val_start;
    out_keypart.normal_keypart_->end_ = val_end;
  }
  if (OB_SUCC(ret)) {
    out_keypart.normal_keypart_->always_false_ = false;
    out_keypart.normal_keypart_->always_true_ = false;
  }
  return ret;
}

W
wangzelin.wzl 已提交
1938 1939 1940 1941 1942 1943
int ObQueryRange::get_row_key_part(const ObRawExpr *l_expr,
                                   const ObRawExpr *r_expr,
                                   ObItemType cmp_type,
                                   const ObExprResType &result_type,
                                   ObKeyPart *&out_key_part,
                                   const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid argument.", KP(l_expr), KP(r_expr), K_(query_range_ctx));
  } else {
    bool row_is_precise = true;
    if (T_OP_EQ != cmp_type) {
      row_is_precise = false;
    }
    ObKeyPartList key_part_list;
W
wangzelin.wzl 已提交
1955
    ObKeyPart *row_tail = out_key_part;
O
oceanbase-admin 已提交
1956
    // resolver makes sure the syntax right, so we don't concern whether the numbers of row are equal
W
wangzelin.wzl 已提交
1957 1958
    const ObOpRawExpr *l_row = static_cast<const ObOpRawExpr *>(l_expr);
    const ObOpRawExpr *r_row = static_cast<const ObOpRawExpr *>(r_expr);
O
oceanbase-admin 已提交
1959
    int64_t num = 0;
W
wangzelin.wzl 已提交
1960 1961 1962
    num = l_row->get_param_count() <= r_row->get_param_count()
        ? l_row->get_param_count()
        : r_row->get_param_count();
O
oceanbase-admin 已提交
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974

    ObItemType c_type = T_INVALID;
    switch (cmp_type) {
      case T_OP_LT:
      case T_OP_LE:
        c_type = T_OP_LE;
        break;
      case T_OP_GT:
      case T_OP_GE:
        c_type = T_OP_GE;
        break;
      default:
W
wangzelin.wzl 已提交
1975 1976 1977
        //其它的compare type,不做改变传递下去,在向量中,T_OP_EQ和T_OP_NSEQ的处理逻辑跟普通条件一样,
        //T_OP_NE抽取range没有意义,不能改变compare type类型,让下层能够判断并忽略这样的row compare
        //子查询的compare type也将原来的compare type传递下去,让下层判断接口能够忽略子查询的compare表达式
O
oceanbase-admin 已提交
1978 1979 1980 1981 1982 1983
        c_type = cmp_type;
        break;
    }
    bool b_flag = false;
    ObArenaAllocator alloc;
    ObExprResType res_type(alloc);
W
wangzelin.wzl 已提交
1984
    ObKeyPart *tmp_key_part = NULL;
1985
    int64_t normal_key_cnt = 0;
O
oceanbase-admin 已提交
1986 1987 1988
    for (int i = 0; OB_SUCC(ret) && !b_flag && i < num; ++i) {
      res_type.set_calc_meta(result_type.get_row_calc_cmp_types().at(i));
      tmp_key_part = NULL;
1989 1990 1991
      bool is_bound_modified = false;
      const ObRawExpr *l_expr = l_row->get_param_expr(i);
      const ObRawExpr *r_expr = r_row->get_param_expr(i);
1992 1993 1994
      if (OB_FAIL(check_null_param_compare_in_row(l_expr,
                                                  r_expr,
                                                  tmp_key_part))) {
W
wangzelin.wzl 已提交
1995 1996
        LOG_WARN("failed to check null param compare in row", K(ret));
      } else if (tmp_key_part == NULL &&
1997 1998
                 OB_FAIL(get_basic_query_range(l_expr,
                                               r_expr,
W
wangzelin.wzl 已提交
1999
                                               NULL,
2000
                                               i < num - 1 ? c_type : cmp_type,
W
wangzelin.wzl 已提交
2001 2002
                                               res_type,
                                               tmp_key_part,
2003 2004
                                               dtc_params,
                                               is_bound_modified))) {
O
oceanbase-admin 已提交
2005
        LOG_WARN("Get basic query key part failed", K(ret), K(*l_row), K(*r_row), K(c_type));
2006 2007 2008 2009 2010
      } else if (OB_ISNULL(tmp_key_part)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret));
      } else if (T_OP_ROW == l_expr->get_expr_type()
                 || T_OP_ROW == r_expr->get_expr_type()) {
O
oceanbase-admin 已提交
2011 2012
        // ((a,b),(c,d)) = (((1,2),(2,3)),((1,2),(2,3)))
        row_is_precise = false;
O
obdev 已提交
2013 2014 2015 2016
      } else if (OB_ISNULL(tmp_key_part)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret));
      } else if (tmp_key_part->is_always_false()) {
L
Larry955 已提交
2017 2018 2019
        if (i == 0) {
          out_key_part = tmp_key_part;
        }
O
obdev 已提交
2020
        b_flag = true;
O
oceanbase-admin 已提交
2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
      } else if (T_OP_EQ == cmp_type || T_OP_NSEQ == cmp_type) {
        row_is_precise = (row_is_precise && query_range_ctx_->cur_expr_is_precise_);
        if (OB_FAIL(add_and_item(key_part_list, tmp_key_part))) {
          LOG_WARN("Add basic query key part failed", K(ret));
        } else if (num - 1 == i) {
          if (OB_FAIL(and_range_graph(key_part_list, out_key_part))) {
            LOG_WARN("and basic query key part failed", K(ret));
          } else {
            b_flag = true;
          }
        }
2032 2033 2034 2035 2036 2037
      } else if (tmp_key_part->is_always_true()) {
        // (c1,c2) < (1,2), if c1 is not key but c2 is, then key_part c2 < 2 is returned
        // however, (0,3) < (1,2) but not satisfy c2 < 2
        // hence, extract row key part until we meet always true
        b_flag = true;
        row_is_precise = false;
O
oceanbase-admin 已提交
2038 2039 2040 2041 2042 2043
      } else if (OB_FAIL(add_row_item(row_tail, tmp_key_part))) {
        LOG_WARN("Add basic query key part failed", K(ret));
      } else {
        if (NULL == out_key_part) {
          out_key_part = tmp_key_part;
        }
O
obdev 已提交
2044
        row_tail = tmp_key_part;
2045 2046
        normal_key_cnt += 1;
        const ObRawExpr *const_expr = l_expr->is_const_expr() ? l_expr : r_expr;
L
Larry955 已提交
2047
        if (OB_FAIL(check_row_bound(tmp_key_part, dtc_params, const_expr, is_bound_modified))) {
2048 2049 2050 2051 2052
          LOG_WARN("failed to check bound modified");
        } else if (is_bound_modified) {
          b_flag = true;
          row_is_precise = false;
        }
O
oceanbase-admin 已提交
2053 2054 2055
      }
    }
    if (OB_SUCC(ret)) {
O
obdev 已提交
2056 2057 2058 2059
      if (OB_UNLIKELY(NULL == out_key_part)) {
        GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
      }
      if (OB_FAIL(ret)) {
2060 2061
      } else if (out_key_part->is_always_true() || out_key_part->is_always_false() ||
                 (normal_key_cnt <= 1 && T_OP_EQ != cmp_type)) {
O
obdev 已提交
2062 2063
        query_range_ctx_->cur_expr_is_precise_ = false;
      } else {
2064 2065 2066
        if (!contain_row_ && T_OP_EQ != cmp_type) {
          contain_row_ = true;
        }
O
obdev 已提交
2067 2068
        query_range_ctx_->cur_expr_is_precise_ = row_is_precise;
      }
2069 2070
      LOG_TRACE("succeed to get row key part",
          K(contain_row_), K(b_flag), K(row_is_precise), K(normal_key_cnt), K(*out_key_part));
O
oceanbase-admin 已提交
2071 2072 2073 2074 2075
    }
  }
  return ret;
}

L
Larry955 已提交
2076
int ObQueryRange::check_row_bound(ObKeyPart *key_part,
2077 2078 2079 2080 2081
                              const ObDataTypeCastParams &dtc_params,
                              const ObRawExpr *const_expr,
                              bool &is_bound_modified)
{
  int ret = OB_SUCCESS;
L
Larry955 已提交
2082 2083 2084
  ObObj const_val;
  bool is_valid = false;
  int64_t cmp = 0;
2085 2086 2087
  if (OB_ISNULL(key_part) || OB_ISNULL(query_range_ctx_) || OB_ISNULL(const_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(key_part), K(query_range_ctx_), K(const_expr));
L
Larry955 已提交
2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100
  } else if (OB_FAIL(get_calculable_expr_val(const_expr, const_val, is_valid))) {
    LOG_WARN("failed to calculate val", K(ret), K(*const_expr), K(const_val), K(is_valid));
  } else if (!is_valid) {
    // do nothing
  } else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params, allocator_, key_part->pos_,
                                                const_val, cmp))) {
    LOG_WARN("failed to cast value", K(ret));
  } else if (cmp != 0 || ob_obj_type_class(const_expr->get_data_type()) !=
                         ob_obj_type_class(key_part->pos_.column_type_.get_type())) {
    is_bound_modified = true;
  }
  LOG_TRACE("succeed to check bound",
            K(is_bound_modified), K(cmp), K(is_valid), K(*key_part), K(*const_expr), K(const_val));
2101 2102 2103
  return ret;
}

O
oceanbase-admin 已提交
2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116
// Get range from basic compare expression, like 'col >= 30', 'row(c1, c2) > row(1, 2)'
//  if this compare expression is not kinds of that we can use,
//  return alway true key part, because it may be in OR expression
//  E.g.
//  case 1:
//         key1 > 0 and (key2 < 5 or not_key3 >0)
//         currently, we get range from 'not_key3 >0', if we do not generate  always true key part for it,
//         the result of (key2 < 5 or not_key3 >0) will be 'key2 belongs (min, 5)'
//  case 2:
//         key1 > 0 and (key2 < 5 or key1+key2 >0)
//  case 3:
//         key1 > 0 and (key2 < 5 or func(key1) >0)

W
wangzelin.wzl 已提交
2117 2118 2119 2120 2121 2122
int ObQueryRange::get_basic_query_range(const ObRawExpr *l_expr,
                                        const ObRawExpr *r_expr,
                                        const ObRawExpr *escape_expr,
                                        ObItemType cmp_type,
                                        const ObExprResType &result_type,
                                        ObKeyPart *&out_key_part,
2123 2124
                                        const ObDataTypeCastParams &dtc_params,
                                        bool &is_bound_modified)
O
oceanbase-admin 已提交
2125 2126 2127
{
  int ret = OB_SUCCESS;
  out_key_part = NULL;
W
wangzelin.wzl 已提交
2128 2129 2130 2131
  if (OB_ISNULL(query_range_ctx_)
      || OB_ISNULL(l_expr)
      || OB_ISNULL(r_expr)
      || (OB_ISNULL(escape_expr) && T_OP_LIKE == cmp_type)) {
O
oceanbase-admin 已提交
2132 2133
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("Wrong input params to get basic query range",
W
wangzelin.wzl 已提交
2134 2135 2136
             K(ret), KP(query_range_ctx_), KP(l_expr), KP(r_expr), KP(escape_expr), K(cmp_type));
  } else if ((T_OP_ROW == l_expr->get_expr_type() && T_OP_ROW != r_expr->get_expr_type())
             || (T_OP_ROW != l_expr->get_expr_type() && T_OP_ROW == r_expr->get_expr_type())) {
O
oceanbase-admin 已提交
2137 2138 2139
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("Row must compare to row", K(ret));
  } else {
W
wangzelin.wzl 已提交
2140
    //在进行单值抽取的时候,先将cur_expr_is_precise_初始化为false
O
oceanbase-admin 已提交
2141 2142 2143
    query_range_ctx_->cur_expr_is_precise_ = false;
  }
  if (OB_FAIL(ret)) {
W
wangzelin.wzl 已提交
2144 2145 2146
    //do nothing
  } else if (T_OP_LIKE == cmp_type && !escape_expr->is_const_expr()) {
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
O
oceanbase-admin 已提交
2147
  } else if (IS_BASIC_CMP_OP(cmp_type)) {
W
wangzelin.wzl 已提交
2148 2149 2150 2151 2152 2153 2154 2155 2156
    if (T_OP_ROW != l_expr->get_expr_type()) {// 1. unary compare
      if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(l_expr, l_expr))) {
        LOG_WARN("failed to get expr without lossless cast", K(ret));
      } else if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(r_expr, r_expr))) {
        LOG_WARN("failed to get expr without lossless cast", K(ret));
      } else if (l_expr->is_const_expr() && r_expr->is_const_expr()) { //const
        if (OB_FAIL(get_const_key_part(l_expr, r_expr, escape_expr, cmp_type,
                                      result_type, out_key_part, dtc_params))) {
          LOG_WARN("get const key part failed.", K(ret));
O
oceanbase-admin 已提交
2157
        }
W
wangzelin.wzl 已提交
2158 2159 2160
      } else if ((l_expr->has_flag(IS_COLUMN) && r_expr->is_const_expr())
                || (l_expr->is_const_expr() && r_expr->has_flag(IS_COLUMN) && T_OP_LIKE != cmp_type)) {
        if (OB_FAIL(get_column_key_part(l_expr, r_expr, escape_expr, cmp_type,
2161
                                        result_type, out_key_part, dtc_params, is_bound_modified))) {//column
W
wangzelin.wzl 已提交
2162
          LOG_WARN("get column key part failed.", K(ret));
O
oceanbase-admin 已提交
2163
        }
W
wangzelin.wzl 已提交
2164 2165 2166
      } else if ((l_expr->has_flag(IS_ROWID) && r_expr->is_const_expr())
                || (r_expr->has_flag(IS_ROWID) && l_expr->is_const_expr() && T_OP_LIKE != cmp_type)) {
        if (OB_FAIL(get_rowid_key_part(l_expr, r_expr, escape_expr, cmp_type,
O
obdev 已提交
2167
                                       out_key_part, dtc_params))) {//rowid
W
wangzelin.wzl 已提交
2168
          LOG_WARN("get rowid key part failed.", K(ret));
O
oceanbase-admin 已提交
2169
        }
W
wangzelin.wzl 已提交
2170 2171 2172 2173
      } else if (l_expr->has_flag(IS_COLUMN) && r_expr->has_flag(IS_COLUMN)) {
        GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
      } else {
        GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
O
oceanbase-admin 已提交
2174
      }
W
wangzelin.wzl 已提交
2175
    } else if (OB_FAIL(get_row_key_part(l_expr, r_expr, cmp_type, result_type,
O
obdev 已提交
2176
                                        out_key_part, dtc_params))) {// 2. row compare
O
oceanbase-admin 已提交
2177 2178 2179 2180 2181 2182 2183 2184 2185
      LOG_WARN("get row key part failed.", K(ret));
    }
  } else {
    // we can not extract range from this type, return all
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
  }
  return ret;
}

W
wangzelin.wzl 已提交
2186 2187 2188 2189 2190 2191
int ObQueryRange::get_like_const_range(const ObRawExpr *text_expr,
                                       const ObRawExpr *pattern_expr,
                                       const ObRawExpr *escape_expr,
                                       ObCollationType cmp_cs_type,
                                       ObKeyPart *&out_key_part,
                                       const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2192 2193
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
2194
  if (OB_ISNULL(text_expr) || OB_ISNULL(pattern_expr) ||  OB_ISNULL(escape_expr)) {
O
oceanbase-admin 已提交
2195 2196 2197
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("invalid argument", K(ret), K(text_expr), K(pattern_expr), K(escape_expr));
  } else {
W
wangzelin.wzl 已提交
2198 2199 2200
    ObObj text;
    ObObj pattern;
    ObObj escape;
O
oceanbase-admin 已提交
2201 2202 2203
    ObString escape_str;
    ObString text_str;
    ObString pattern_str;
W
wangzelin.wzl 已提交
2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215
    bool text_valid = false;
    bool pattern_valid = false;
    bool escape_valid = false;
    if (OB_FAIL(get_calculable_expr_val(text_expr, text, text_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (OB_FAIL(get_calculable_expr_val(pattern_expr, pattern, pattern_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (OB_FAIL(get_calculable_expr_val(escape_expr, escape, escape_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (!text_valid || !pattern_valid || !escape_valid) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    } else if (escape.is_null()) {
O
oceanbase-admin 已提交
2216 2217 2218 2219 2220 2221 2222 2223 2224 2225
      escape_str.assign_ptr("\\", 1);
    } else if (ObVarcharType != escape.get_type()) {
      ObObj tmp_obj = escape;
      tmp_obj.set_scale(escape_expr->get_result_type().get_scale());
      ObCastCtx cast_ctx(&allocator_, &dtc_params, CM_WARN_ON_FAIL, cmp_cs_type);
      EXPR_GET_VARCHAR_V2(escape, escape_str);
    } else {
      escape_str = escape.get_varchar();
    }
    if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
2226
      if (escape_str.empty()) { // escape ''
O
oceanbase-admin 已提交
2227 2228 2229 2230
        escape_str.assign_ptr("\\", 1);
      }
      if (ObVarcharType != text.get_type()) {
        ObObj tmp_obj = text;
W
wangzelin.wzl 已提交
2231
        tmp_obj.set_scale(text_expr->get_result_type().get_scale()); // 1.0 like 1
O
oceanbase-admin 已提交
2232 2233 2234 2235 2236 2237 2238 2239 2240
        ObCastCtx cast_ctx(&allocator_, &dtc_params, CM_WARN_ON_FAIL, cmp_cs_type);
        EXPR_GET_VARCHAR_V2(tmp_obj, text_str);
      } else {
        text_str = text.get_varchar();
      }
    }
    if (OB_SUCC(ret)) {
      if (ObVarcharType != pattern.get_type()) {
        ObObj tmp_obj = pattern;
W
wangzelin.wzl 已提交
2241
        tmp_obj.set_scale(pattern_expr->get_result_type().get_scale()); // 1 like 1.0
O
oceanbase-admin 已提交
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251
        ObCastCtx cast_ctx(&allocator_, &dtc_params, CM_WARN_ON_FAIL, cmp_cs_type);
        EXPR_GET_VARCHAR_V2(tmp_obj, pattern_str);
      } else {
        pattern_str = pattern.get_varchar();
      }
    }
    if (OB_SUCC(ret)) {
      ObObj result;
      bool is_true = false;
      if (OB_FAIL(ObExprLike::calc_with_non_instr_mode(result,
W
wangzelin.wzl 已提交
2252 2253 2254 2255 2256
                                                       cmp_cs_type,
                                                       escape.get_collation_type(),
                                                       text_str,
                                                       pattern_str,
                                                       escape_str))) { // no optimization.
O
oceanbase-admin 已提交
2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276
        LOG_WARN("calc like func failed", K(ret));
      } else if (OB_FAIL(ObObjEvaluator::is_true(result, is_true))) {
        LOG_WARN("failed to call is_true", K(ret));
      } else if (is_true) {
        GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
      } else {
        GET_ALWAYS_TRUE_OR_FALSE(false, out_key_part);
      }
    }
  }
  return ret;
}

//  Add row item to the end of the row list
//  1. if item is always true, do not do next
//      there are two kinds of cases:
//      1) real true, row(k1, 2, k2)>row(1, 1, 1), "2>1" is true.
//          Under this kind of case, in fact we can ignore the second item and do next
//      2) not real true, row(k1, k2, k2)>=(1, k1, 4), "k2>=k1" is run-time defined,
//          we can not know during parser, so true is returned.
K
Klawz 已提交
2277
//          under this case, we can not ignore it. (k1=1 and k2=3) satisfied this condition,
O
oceanbase-admin 已提交
2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289
//          but not satisfied row(k1, k2)>=(1, 4)
//      we can not distinguish them, so do not do next.
//  2. if item is always false, no need to do next
//  3. if key part pos is not larger than exists', ignore it. because the range already be (min, max)
//      E.g.
//          a. rowkey(c1, c2, c3), condition: row(c1, c3, c2) > row(1, 2, 3).
//              while compare, row need item in order,  when considering c3, key part c2 must have range,
//              so (min, max) already used for c2.
//          b. (c1, c1, c2) > (const1, const2, const3) ==> (c1, c2) > (const1, const3)
//
//  NB: 1 and 2 are ensured by caller

W
wangzelin.wzl 已提交
2290
int ObQueryRange::add_row_item(ObKeyPart *&row_tail, ObKeyPart *key_part)
O
oceanbase-admin 已提交
2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317
{
  int ret = OB_SUCCESS;
  if (NULL != key_part) {
    if (NULL == row_tail) {
      row_tail = key_part;
    } else if (key_part->is_always_true()) {
      // ignore
    } else if (key_part->is_always_false()) {
      row_tail->and_next_ = key_part;
      key_part->and_next_ = NULL;
    } else {
      if (NULL == row_tail->and_next_ && row_tail->pos_.offset_ < key_part->pos_.offset_) {
        row_tail->and_next_ = key_part;
        key_part->and_next_ = NULL;
      } else {
        // find key part id no less than it
        // ignore
      }
    }
  } else {
    // do nothing
  }
  return ret;
}

// Add and item to array

W
wangzelin.wzl 已提交
2318
int ObQueryRange::add_and_item(ObKeyPartList &and_storage, ObKeyPart *key_part)
O
oceanbase-admin 已提交
2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332
{
  int ret = OB_SUCCESS;
  if (NULL != key_part) {
    if (key_part->is_always_true()) {
      // everything and true is itself
      // if other item exists, ignore this key_part
      if (and_storage.get_size() <= 0) {
        if (!and_storage.add_last(key_part)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Add and key part graph failed", K(ret));
        }
      }
    } else if (key_part->is_always_false()) {
      // everything and false is false
W
wangzelin.wzl 已提交
2333 2334
      if (1 == and_storage.get_size() && NULL != and_storage.get_first()
          && and_storage.get_first()->is_always_false()) {
O
oceanbase-admin 已提交
2335 2336 2337 2338 2339 2340 2341 2342
        // already false, ignore add action
      } else {
        and_storage.clear();
        if (!and_storage.add_last(key_part)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Add and key part graph failed", K(ret));
        }
      }
W
wangzelin.wzl 已提交
2343 2344 2345
    } else { // normal case
      if (1 == and_storage.get_size() && NULL != and_storage.get_first()
          && and_storage.get_first()->is_always_false()) {
O
oceanbase-admin 已提交
2346 2347
        // already false, ignore add action
      } else {
W
wangzelin.wzl 已提交
2348 2349
        if (1 == and_storage.get_size() && NULL != and_storage.get_first()
            && and_storage.get_first()->is_always_true()) {
O
oceanbase-admin 已提交
2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365
          and_storage.clear();
        }
        if (!and_storage.increasing_add(key_part)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Add and key part graph failed", K(ret));
        }
      }
    }
  } else {
    // do nothing
  }
  return ret;
}

// Add or item to array

W
wangzelin.wzl 已提交
2366
int ObQueryRange::add_or_item(ObKeyPartList &or_storage, ObKeyPart *key_part)
O
oceanbase-admin 已提交
2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380
{
  int ret = OB_SUCCESS;
  if (NULL != key_part) {
    if (key_part->is_always_false()) {
      // everything or false is itself
      // if other item exists, ignore this key_part
      if (or_storage.get_size() <= 0) {
        if (!or_storage.add_last(key_part)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Add or key part graph failed", K(ret));
        }
      }
    } else if (key_part->is_always_true()) {
      // everything or true is true
W
wangzelin.wzl 已提交
2381 2382
      if (1 == or_storage.get_size() && NULL != or_storage.get_first()
          && or_storage.get_first()->is_always_true()) {
O
oceanbase-admin 已提交
2383 2384 2385 2386 2387 2388 2389 2390
        // already true, ignore add action
      } else {
        or_storage.clear();
        if (!or_storage.add_last(key_part)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Add or key part graph failed", K(ret));
        }
      }
W
wangzelin.wzl 已提交
2391 2392 2393
    } else { // normal case
      if (1 == or_storage.get_size() && NULL != or_storage.get_first()
          && or_storage.get_first()->is_always_true()) {
O
oceanbase-admin 已提交
2394 2395
        // already true, ignore add action
      } else {
W
wangzelin.wzl 已提交
2396 2397
        if (1 == or_storage.get_size()
            && NULL != or_storage.get_first() && or_storage.get_first()->is_always_false()) {
O
oceanbase-admin 已提交
2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
          or_storage.clear();
        }
        if (!or_storage.add_last(key_part)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Add or key part graph failed", K(ret));
        }
      }
    }
  } else {
    // do nothing
  }
  return ret;
}

W
wangzelin.wzl 已提交
2412 2413 2414
int ObQueryRange::pre_extract_basic_cmp(const ObRawExpr *node,
                                        ObKeyPart *&out_key_part,
                                        const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2415 2416 2417 2418 2419 2420
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(node)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("node is null.", K(node));
  } else {
W
wangzelin.wzl 已提交
2421 2422
    const ObRawExpr *escape_expr = NULL;
    const ObOpRawExpr *multi_expr = static_cast<const ObOpRawExpr *>(node);
O
oceanbase-admin 已提交
2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444
    if (T_OP_LIKE != node->get_expr_type()) {
      if (2 != multi_expr->get_param_count()) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("multi_expr must has 2 arguments", K(ret));
      }
    } else {
      if (3 != multi_expr->get_param_count()) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("multi_expr must has 3 arguments", K(ret));
      } else {
        escape_expr = multi_expr->get_param_expr(2);
      }
    }
    if (OB_SUCC(ret)) {
      const ObRawExpr* right_expr = multi_expr->get_param_expr(1);
      if (lib::is_oracle_mode() && T_OP_ROW == multi_expr->get_param_expr(0)->get_expr_type()) {
        if (T_OP_ROW == multi_expr->get_param_expr(1)->get_expr_type() &&
            1 == multi_expr->get_param_expr(1)->get_param_count() &&
            T_OP_ROW == multi_expr->get_param_expr(1)->get_param_expr(0)->get_expr_type()) {
          right_expr = multi_expr->get_param_expr(1)->get_param_expr(0);
        }
      }
W
wangzelin.wzl 已提交
2445
      //因为我们只处理某些特殊的表达式,对于一些复杂表达式即使是精确的,也不对其做优化,所以先将flag初始化为false
2446
      bool dummy_is_bound_modified = false;
O
oceanbase-admin 已提交
2447
      if (OB_FAIL(get_basic_query_range(multi_expr->get_param_expr(0),
W
wangzelin.wzl 已提交
2448 2449 2450 2451 2452
                                        right_expr,
                                        escape_expr,
                                        node->get_expr_type(),
                                        node->get_result_type(),
                                        out_key_part,
2453 2454
                                        dtc_params,
                                        dummy_is_bound_modified))) {
O
oceanbase-admin 已提交
2455 2456 2457 2458 2459 2460 2461
        LOG_WARN("Get basic query key part failed", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
2462 2463 2464
int ObQueryRange::pre_extract_ne_op(const ObOpRawExpr *t_expr,
                                    ObKeyPart *&out_key_part,
                                    const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2465 2466 2467 2468 2469
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(t_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", K(t_expr), K_(query_range_ctx));
W
wangzelin.wzl 已提交
2470
  } else if (2 != t_expr->get_param_count()) {//trip op expr
O
oceanbase-admin 已提交
2471 2472 2473 2474
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("t_expr must has 2 arguments", K(ret));
  } else {
    bool is_precise = true;
W
wangzelin.wzl 已提交
2475 2476
    const ObRawExpr *l_expr = t_expr->get_param_expr(0);
    const ObRawExpr *r_expr = t_expr->get_param_expr(1);
O
oceanbase-admin 已提交
2477
    ObKeyPartList key_part_list;
2478 2479 2480 2481 2482 2483
    if (T_OP_ROW == l_expr->get_expr_type() && T_OP_ROW == r_expr->get_expr_type()) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    } else {
      for (int i = 0; OB_SUCC(ret) && i < 2; ++i) {
        query_range_ctx_->cur_expr_is_precise_ = false;
        ObKeyPart *tmp = NULL;
2484
        bool dummy_is_bound_modified = false;
2485 2486 2487 2488 2489 2490
        if (OB_FAIL(get_basic_query_range(l_expr,
                                          r_expr,
                                          NULL,
                                          i == 0 ? T_OP_LT : T_OP_GT,
                                          t_expr->get_result_type(),
                                          tmp,
2491 2492
                                          dtc_params,
                                          dummy_is_bound_modified))) {
2493 2494 2495 2496 2497 2498 2499 2500
          LOG_WARN("Get basic query range failed", K(ret));
        } else if (OB_FAIL(add_or_item(key_part_list, tmp))) {
          LOG_WARN("push back failed", K(ret));
        } else {
          // A != B 表达式被拆分成了两个表达式, A < B OR A > B
          // 要保证每个表达式都是精确的,整个表达式才是精确的
          is_precise = (is_precise && query_range_ctx_->cur_expr_is_precise_);
        }
O
oceanbase-admin 已提交
2501
      }
2502 2503 2504 2505 2506 2507
      if (OB_SUCC(ret)) {
        query_range_ctx_->cur_expr_is_precise_ = is_precise;
        //not need params when preliminary extract
        if (OB_FAIL(or_range_graph(key_part_list, NULL, out_key_part, dtc_params))) {
          LOG_WARN("or range graph failed", K(ret));
        }
O
oceanbase-admin 已提交
2508 2509 2510 2511 2512 2513
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
2514 2515 2516
int ObQueryRange::pre_extract_is_op(const ObOpRawExpr *b_expr,
                                    ObKeyPart *&out_key_part,
                                    const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2517 2518 2519 2520 2521 2522
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(b_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", K(b_expr), K_(query_range_ctx));
  } else if (ObNullType == b_expr->get_param_expr(1)->get_result_type().get_type()) {
W
wangzelin.wzl 已提交
2523
    //pk is null will be extracted
2524
    bool dummy_is_bound_modified = false;
O
obdev 已提交
2525
    if (2 != b_expr->get_param_count()) {//binary op expr
O
oceanbase-admin 已提交
2526
      ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
2527
      LOG_WARN("b_expr must has 2 arguments", K(ret));
O
oceanbase-admin 已提交
2528
    } else if (OB_FAIL(get_basic_query_range(b_expr->get_param_expr(0),
W
wangzelin.wzl 已提交
2529 2530 2531 2532 2533
                                             b_expr->get_param_expr(1),
                                             NULL,
                                             T_OP_NSEQ,
                                             b_expr->get_result_type(),
                                             out_key_part,
2534 2535
                                             dtc_params,
                                             dummy_is_bound_modified))) {
O
oceanbase-admin 已提交
2536 2537 2538 2539 2540 2541 2542 2543 2544
      LOG_WARN("Get basic query key part failed", K(ret));
    }
  } else {
    query_range_ctx_->cur_expr_is_precise_ = false;
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
  }
  return ret;
}

W
wangzelin.wzl 已提交
2545 2546 2547
int ObQueryRange::pre_extract_btw_op(const ObOpRawExpr *t_expr,
                                     ObKeyPart *&out_key_part,
                                     const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2548 2549 2550 2551 2552
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(t_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", K(t_expr), K_(query_range_ctx));
W
wangzelin.wzl 已提交
2553
  } else if (3 != t_expr->get_param_count()) {//trip op expr
O
oceanbase-admin 已提交
2554 2555 2556 2557
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("t_expr must has 3 arguments", K(ret));
  } else {
    bool btw_op_is_precise = true;
W
wangzelin.wzl 已提交
2558
    const ObRawExpr *l_expr = t_expr->get_param_expr(0);
O
oceanbase-admin 已提交
2559 2560
    ObKeyPartList key_part_list;
    for (int i = 0; OB_SUCC(ret) && i < 2; ++i) {
W
wangzelin.wzl 已提交
2561 2562
      const ObRawExpr *r_expr = t_expr->get_param_expr(i + 1);
      ObKeyPart *tmp = NULL;
2563
      bool dummy_is_bound_modified = false;
W
wangzelin.wzl 已提交
2564 2565 2566 2567 2568 2569
      if (OB_FAIL(get_basic_query_range(l_expr,
                                        r_expr,
                                        NULL,
                                        i == 0 ? T_OP_GE : T_OP_LE,
                                        t_expr->get_result_type(),
                                        tmp,
2570 2571
                                        dtc_params,
                                        dummy_is_bound_modified))) {
O
oceanbase-admin 已提交
2572 2573 2574 2575
        LOG_WARN("Get basic query range failed", K(ret));
      } else if (OB_FAIL(add_and_item(key_part_list, tmp))) {
        LOG_WARN("push back failed", K(ret));
      } else {
W
wangzelin.wzl 已提交
2576 2577
        //BETWEEN...AND...表达式被拆分成了两个表达式
        //要保证每个表达式都是精确的,整个表达式才是精确的
O
oceanbase-admin 已提交
2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590
        btw_op_is_precise = (btw_op_is_precise && query_range_ctx_->cur_expr_is_precise_);
      }
    }
    if (OB_SUCC(ret)) {
      query_range_ctx_->cur_expr_is_precise_ = btw_op_is_precise;
      if (OB_FAIL(and_range_graph(key_part_list, out_key_part))) {
        LOG_WARN("and range graph failed", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
2591 2592 2593
int ObQueryRange::pre_extract_not_btw_op(const ObOpRawExpr *t_expr,
                                         ObKeyPart *&out_key_part,
                                         const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2594 2595 2596 2597 2598
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(t_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", K(t_expr), K_(query_range_ctx));
W
wangzelin.wzl 已提交
2599
  } else if (3 != t_expr->get_param_count()) {//trip op expr
O
oceanbase-admin 已提交
2600 2601 2602 2603
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("t_expr must has 3 arguments", K(ret));
  } else {
    bool not_btw_op_is_precise = true;
W
wangzelin.wzl 已提交
2604
    const ObRawExpr *l_expr = t_expr->get_param_expr(0);
O
oceanbase-admin 已提交
2605 2606 2607
    ObKeyPartList key_part_list;
    for (int i = 0; OB_SUCC(ret) && i < 2; ++i) {
      query_range_ctx_->cur_expr_is_precise_ = false;
W
wangzelin.wzl 已提交
2608 2609
      const ObRawExpr *r_expr = t_expr->get_param_expr(i + 1);
      ObKeyPart *tmp = NULL;
2610
      bool dummy_is_bound_modified = false;
W
wangzelin.wzl 已提交
2611 2612 2613 2614 2615 2616
      if (OB_FAIL(get_basic_query_range(l_expr,
                                        r_expr,
                                        NULL,
                                        i == 0 ? T_OP_LT : T_OP_GT,
                                        t_expr->get_result_type(),
                                        tmp,
2617 2618
                                        dtc_params,
                                        dummy_is_bound_modified))) {
O
oceanbase-admin 已提交
2619 2620 2621 2622
        LOG_WARN("Get basic query range failed", K(ret));
      } else if (OB_FAIL(add_or_item(key_part_list, tmp))) {
        LOG_WARN("push back failed", K(ret));
      } else {
W
wangzelin.wzl 已提交
2623 2624
        //NOT BETWEEN...AND...表达式被拆分成了两个表达式
        //要保证每个表达式都是精确的,整个表达式才是精确的
O
oceanbase-admin 已提交
2625 2626 2627 2628 2629
        not_btw_op_is_precise = (not_btw_op_is_precise && query_range_ctx_->cur_expr_is_precise_);
      }
    }
    if (OB_SUCC(ret)) {
      query_range_ctx_->cur_expr_is_precise_ = not_btw_op_is_precise;
W
wangzelin.wzl 已提交
2630
      //not need params when preliminary extract
O
oceanbase-admin 已提交
2631 2632 2633 2634 2635 2636 2637 2638
      if (OB_FAIL(or_range_graph(key_part_list, NULL, out_key_part, dtc_params))) {
        LOG_WARN("or range graph failed", K(ret));
      }
    }
  }
  return ret;
}

O
obdev 已提交
2639
// to extract single in expr such as c1 in (xxx)
W
wangzelin.wzl 已提交
2640 2641 2642
int ObQueryRange::pre_extract_single_in_op(const ObOpRawExpr *b_expr,
                                           ObKeyPart *&out_key_part,
                                           const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2643 2644
{
  int ret = OB_SUCCESS;
2645
  const ObOpRawExpr *r_expr = NULL;
O
oceanbase-admin 已提交
2646 2647 2648 2649 2650 2651
  if (OB_ISNULL(b_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr or query_range_ctx is null. ", K(b_expr), K_(query_range_ctx));
  } else if (2 != b_expr->get_param_count()) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("t_expr must be 3 argument", K(ret));
2652 2653 2654 2655 2656 2657
  } else if (T_OP_ROW != b_expr->get_param_expr(1)->get_expr_type()) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("expect row_expr in in_expr", K(ret));
  } else if (OB_ISNULL(r_expr = static_cast<const ObOpRawExpr *>(b_expr->get_param_expr(1)))) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("r_expr is null.", K(ret));
2658
  } else if (r_expr->get_param_count() > MAX_RANGE_SIZE_OLD) {
2659 2660 2661
    // do not extract range over MAX_RANGE_SIZE
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    query_range_ctx_->cur_expr_is_precise_ = false;
O
oceanbase-admin 已提交
2662
  } else {
2663 2664 2665 2666 2667 2668 2669
    ObArenaAllocator alloc;
    bool cur_in_is_precise = true;
    ObKeyPart *tmp_tail = NULL;
    ObKeyPart *find_false = NULL;
    for (int64_t i = 0; OB_SUCC(ret) && i < r_expr->get_param_count(); i++) {
      ObKeyPart *tmp = NULL;
      ObExprResType res_type(alloc);
2670
      bool dummy_is_bound_modified = false;
2671 2672 2673 2674 2675 2676 2677 2678
      if (OB_FAIL(get_in_expr_res_type(b_expr, i, res_type))) {
        LOG_WARN("get in expr element result type failed", K(ret), K(i));
      } else if (OB_FAIL(get_basic_query_range(b_expr->get_param_expr(0),
                                                r_expr->get_param_expr(i),
                                                NULL,
                                                T_OP_EQ,
                                                res_type,
                                                tmp,
2679 2680
                                                dtc_params,
                                                dummy_is_bound_modified))) {
2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696
        LOG_WARN("Get basic query range failed", K(ret));
      } else if (OB_ISNULL(tmp) || NULL != tmp->or_next_) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("tmp is null or tmp->or_next is not null", K(ret), K(tmp));
      } else if (tmp->is_always_true()) { // find true , out_key_part -> true, ignore other
        out_key_part = tmp;
        cur_in_is_precise = (cur_in_is_precise && query_range_ctx_->cur_expr_is_precise_);
        break;
      } else if (tmp->is_always_false()) { // find false
        find_false = tmp;
      } else if (NULL == tmp_tail) {
        tmp_tail = tmp;
        out_key_part = tmp;
      } else {
        tmp_tail->or_next_ = tmp;
        tmp_tail = tmp;
O
oceanbase-admin 已提交
2697 2698
      }
      if (OB_SUCC(ret)) {
2699 2700 2701 2702 2703 2704 2705 2706
        cur_in_is_precise = (cur_in_is_precise && query_range_ctx_->cur_expr_is_precise_);
      }
    }
    if (OB_SUCC(ret)) {
      if (NULL != find_false && NULL == out_key_part) {
        out_key_part = find_false;
      }
      query_range_ctx_->cur_expr_is_precise_ = cur_in_is_precise;
2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719
      int64_t max_pos = -1;
      int64_t cur_pos = out_key_part->pos_.offset_;
      bool is_strict_equal = false;
      if (query_range_ctx_->only_one_expr_ &&
          OB_FAIL(is_strict_equal_graph(out_key_part, cur_pos, max_pos, is_strict_equal))) {
        LOG_WARN("is trict equal graph failed", K(ret));
      } else if (NULL != out_key_part && !is_strict_equal) {
        ObKeyPartList key_part_list;
        if (OB_FAIL(split_or(out_key_part, key_part_list))) {
          LOG_WARN("split temp_result to or_list failed", K(ret));
        } else if (OB_FAIL(or_range_graph(key_part_list, NULL, out_key_part, dtc_params))) {
          LOG_WARN("or range graph failed", K(ret));
        }
O
oceanbase-admin 已提交
2720 2721 2722 2723 2724 2725
      }
    }
  }
  return ret;
}

O
obdev 已提交
2726 2727 2728 2729
// to extract complex exprs that contain in expr such as c1 in (xxx) or c1 > y
int ObQueryRange::pre_extract_complex_in_op(const ObOpRawExpr *b_expr,
                                            ObKeyPart *&out_key_part,
                                            const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
2730 2731 2732
{
  int ret = OB_SUCCESS;
  // treat IN operation as 'left_param = right_item_1 or ... or left_param = right_item_n'
2733
  const ObOpRawExpr *r_expr = NULL;
O
oceanbase-admin 已提交
2734 2735 2736
  if (OB_ISNULL(b_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", K(b_expr), K_(query_range_ctx));
W
wangzelin.wzl 已提交
2737
  } else if (2 != b_expr->get_param_count()) {//binary op expr
O
oceanbase-admin 已提交
2738 2739
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("t_expr must has 3 arguments", K(ret));
2740 2741 2742
  } else if (OB_ISNULL(r_expr = static_cast<const ObOpRawExpr *>(b_expr->get_param_expr(1)))) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("r_expr is null.", K(ret));
2743
  } else if (r_expr->get_param_count() > MAX_RANGE_SIZE_OLD) {
2744 2745
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    query_range_ctx_->cur_expr_is_precise_ = false;
O
oceanbase-admin 已提交
2746
  } else {
2747 2748 2749 2750 2751 2752
    ObKeyPartList key_part_list;
    ObArenaAllocator alloc;
    bool cur_in_is_precise = true;
    for (int64_t i = 0; OB_SUCC(ret) && i < r_expr->get_param_count(); i++) {
      ObKeyPart *tmp = NULL;
      ObExprResType res_type(alloc);
2753
      bool dummy_is_bound_modified = false;
2754 2755 2756 2757 2758 2759 2760 2761
      if (OB_FAIL(get_in_expr_res_type(b_expr, i, res_type))) {
        LOG_WARN("get in expr element result type failed", K(ret), K(i));
      } else if (OB_FAIL(get_basic_query_range(b_expr->get_param_expr(0),
                                                r_expr->get_param_expr(i),
                                                NULL,
                                                T_OP_EQ,
                                                res_type,
                                                tmp,
2762 2763
                                                dtc_params,
                                                dummy_is_bound_modified))) {
2764 2765 2766 2767 2768
        LOG_WARN("Get basic query range failed", K(ret));
      } else if (OB_FAIL(add_or_item(key_part_list, tmp))) {
        LOG_WARN("push back failed", K(ret));
      } else {
        cur_in_is_precise = (cur_in_is_precise && query_range_ctx_->cur_expr_is_precise_);
O
oceanbase-admin 已提交
2769
      }
2770 2771 2772 2773 2774
    }
    if (OB_SUCC(ret)) {
      query_range_ctx_->cur_expr_is_precise_ = cur_in_is_precise;
      if (OB_FAIL(or_range_graph(key_part_list, NULL, out_key_part, dtc_params))) {
        LOG_WARN("or range graph failed", K(ret));
O
oceanbase-admin 已提交
2775 2776 2777 2778 2779 2780
      }
    }
  }
  return ret;
}

2781 2782 2783
int ObQueryRange::pre_extract_in_op_with_opt(const ObOpRawExpr *b_expr,
                                             ObKeyPart *&out_key_part,
                                             const ObDataTypeCastParams &dtc_params)
O
obdev 已提交
2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837
{
  int ret = OB_SUCCESS;
  const ObOpRawExpr *r_expr = NULL;
  if (OB_ISNULL(b_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr or query_range_ctx is null. ", K(b_expr), K_(query_range_ctx));
  } else if (OB_UNLIKELY(2 != b_expr->get_param_count())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("b_expr must be 2 argument", K(ret));
  } else {
    const ObRawExpr *l_expr = b_expr->get_param_expr(0);
    const ObOpRawExpr *r_expr = static_cast<const ObOpRawExpr *>(b_expr->get_param_expr(1));
    // set to be true at the very begining
    query_range_ctx_->cur_expr_is_precise_ = true;
    ObArenaAllocator alloc;
    ObExprResType res_type(alloc);
    if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr) ||
        OB_UNLIKELY(r_expr->get_param_count() == 0)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get invalid argument", K(ret), K(l_expr), K(r_expr));
    } else if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(l_expr, l_expr))) {
      LOG_WARN("failed to get expr without lossless cast", K(ret));
    } else if (OB_FAIL(get_in_expr_res_type(b_expr, 0, res_type))) {
      LOG_WARN("get in expr element result type failed", K(ret));
    } else if (l_expr->get_expr_type() == T_OP_ROW) {
      if (OB_FAIL(get_multi_in_key_part(static_cast<const ObOpRawExpr *>(l_expr),
                                        r_expr, res_type, out_key_part, dtc_params))) {
        LOG_WARN("failed to create in key part that contains rows", K(ret));
      }
    } else if (l_expr->is_column_ref_expr()) {
      if (OB_FAIL(get_single_in_key_part(static_cast<const ObColumnRefRawExpr *>(l_expr),
                                         r_expr, res_type, out_key_part, dtc_params))) {
        LOG_WARN("failed to create single column in key part", K(ret));
      }
    } else if (l_expr->has_flag(IS_ROWID)) {
      if (OB_FAIL(get_rowid_in_key_part(l_expr, r_expr, -1, out_key_part, dtc_params))) {
        LOG_WARN("failed to get rowid in key part", K(ret));
      }
    } else {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    }
  }
  return ret;
}

int ObQueryRange::get_multi_in_key_part(const ObOpRawExpr *l_expr,
                                        const ObOpRawExpr *r_expr,
                                        const ObExprResType &res_type,
                                        ObKeyPart *&out_key_part,
                                        const ObDataTypeCastParams &dtc_params)
{
  int ret = OB_SUCCESS;
  ObKeyPart *tmp_key_part = NULL;
  bool has_rowid = false;
2838
  common::hash::ObHashMap<int64_t, ObKeyPartPos*> idx_pos_map;
O
obdev 已提交
2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880
  common::hash::ObHashMap<int64_t, InParamMeta *> idx_param_map;
  common::hash::ObHashMap<int64_t, int64_t> expr_idx_param_idx_map;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(l_expr), K(r_expr));
  } else if (OB_FAIL(prepare_multi_in_info(l_expr,
                                           r_expr,
                                           tmp_key_part,
                                           has_rowid,
                                           idx_pos_map,
                                           idx_param_map,
                                           expr_idx_param_idx_map,
                                           dtc_params))) {
    LOG_WARN("failed to prepare row in info", K(ret));
  } else if (NULL == tmp_key_part) {
    // no valid key existed in IN expr
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
  } else if (has_rowid) {
    // do nothing
    out_key_part = tmp_key_part;
  } else {
    // store expr idx that belongs to in key but can not extract ranges
    ObSEArray<int64_t, 4> invalid_expr_idx;
    // store param idx that belongs to in key but can not extract ranges
    ObSEArray<int64_t, 4> invalid_param_idx;
    // store idx that not belongs to any keys
    ObSEArray<int64_t, 4> not_key_idx;
    // store val idx that can not extract range
    ObSEArray<int64_t, 4> invalid_val_idx;
    ObArenaAllocator alloc;
    for (int64_t i = 0; OB_SUCC(ret) && i < r_expr->get_param_count(); ++i) {
      const ObRawExpr *r_param = r_expr->get_param_expr(i);
      if (OB_ISNULL(r_param) || OB_UNLIKELY(r_param->get_expr_type() != T_OP_ROW)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret));
      } else {
        ObExprResType param_res_type(alloc);
        for (int64_t j = 0; OB_SUCC(ret) && j < r_param->get_param_count(); ++j) {
          if (!is_contain(invalid_expr_idx, j) && !is_contain(not_key_idx, j)) {
            param_res_type.set_calc_meta(res_type.get_row_calc_cmp_types().at(j));
            const ObRawExpr *const_expr = r_param->get_param_expr(j);
            InParamMeta *param_meta = NULL;
2881
            ObKeyPartPos *cur_key_pos = nullptr;
O
obdev 已提交
2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894
            bool can_be_extract = true;
            bool always_true = true;
            bool is_val_valid = true;
            if (OB_ISNULL(const_expr)) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("get unexpected null", K(ret));
            } else if (OB_FAIL(idx_pos_map.get_refactored(j, cur_key_pos))) {
              if (OB_UNLIKELY(OB_HASH_NOT_EXIST != ret)) {
                LOG_WARN("failed to get key meta", K(ret));
              } else {
                // TO HANDLE: (c1, 1) in ((1,2), (1,1))
                ret = OB_SUCCESS;
                const ObRawExpr *l_param = l_expr->get_param_expr(j);
2895
                if (!l_param->is_immutable_const_expr() || !const_expr->is_immutable_const_expr()) {
O
obdev 已提交
2896 2897 2898 2899 2900 2901 2902 2903 2904
                  ret = not_key_idx.push_back(j);
                } else if (OB_FAIL(check_const_val_valid(l_param,
                                                         const_expr,
                                                         res_type,
                                                         dtc_params,
                                                         is_val_valid))) {
                  LOG_WARN("failed to check const value valid", K(ret));
                }
              }
2905 2906 2907
            } else if (OB_ISNULL(cur_key_pos)) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("get unexpected null", K(ret), K(j));
O
obdev 已提交
2908 2909 2910 2911 2912 2913
            } else if (OB_UNLIKELY(!const_expr->is_const_expr())) {
              can_be_extract = false;
              always_true = true;
            } else if (OB_FAIL(idx_param_map.get_refactored(j, param_meta))) {
              LOG_WARN("failed to get param meta", K(ret));
            } else if (!can_be_extract_range(T_OP_EQ,
2914
                                             cur_key_pos->column_type_,
O
obdev 已提交
2915 2916 2917 2918 2919 2920
                                             param_res_type.get_calc_meta(),
                                             const_expr->get_result_type().get_type(),
                                             always_true)) {
              can_be_extract = false;
            } else if (OB_FAIL(get_param_value(tmp_key_part->in_keypart_,
                                               param_meta,
2921
                                               *cur_key_pos,
O
obdev 已提交
2922 2923 2924 2925 2926 2927 2928 2929 2930
                                               const_expr,
                                               dtc_params,
                                               is_val_valid))) {
              LOG_WARN("failed to get param value", K(ret));
            } else if (!is_val_valid) {
              // do nothing
            } else if (OB_FAIL(check_expr_precise(tmp_key_part,
                                                  const_expr,
                                                  param_res_type.get_calc_meta(),
2931
                                                  *cur_key_pos))) {
O
obdev 已提交
2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965
              LOG_WARN("failed to check expr precise", K(ret));
            }
            if (OB_SUCC(ret) && !can_be_extract) {
              if (always_true) {
                int64_t param_idx = -1;
                if (OB_FAIL(invalid_expr_idx.push_back(j))) {
                  LOG_WARN("failed to push back expr idx", K(ret));
                } else if (OB_FAIL(expr_idx_param_idx_map.get_refactored(j, param_idx))) {
                  LOG_WARN("failed to get param idx", K(ret));
                } else if (OB_FAIL(invalid_param_idx.push_back(param_idx))) {
                  LOG_WARN("failed to push back invalid param idx", K(ret));
                }
              } else {
                is_val_valid = false;
              }
            }
            if (OB_SUCC(ret) && !is_val_valid &&
                OB_FAIL(add_var_to_array_no_dup(invalid_val_idx, i))) {
              LOG_WARN("failed to add invalid val idx", K(ret), K(i));
            }
          }
        }
      }
    }
    if (OB_FAIL(ret)) {
    } else if (!invalid_param_idx.empty() &&
               query_range_ctx_ != NULL &&
               OB_FALSE_IT(query_range_ctx_->cur_expr_is_precise_ = false)) {
    } else if (OB_FAIL(tmp_key_part->remove_in_params(invalid_param_idx, true))) {
      LOG_WARN("failed to adjust in key part param", K(ret));
    } else if (OB_FAIL(tmp_key_part->remove_in_params_vals(invalid_val_idx))) {
      LOG_WARN("failed to adjust in param values", K(ret));
    } else if (OB_FAIL(tmp_key_part->formalize_keypart(contain_row_))) {
      LOG_WARN("failed to formalize in key", K(ret));
L
Larry955 已提交
2966 2967 2968 2969
    } else if (tmp_key_part->is_always_true() || tmp_key_part->is_always_false()) {
      query_range_ctx_->cur_expr_is_precise_ = false;
    }
    if (OB_SUCC(ret)) {
O
obdev 已提交
2970 2971 2972 2973 2974 2975 2976 2977 2978 2979
      out_key_part = tmp_key_part;
    }
  }
  return ret;
}

int ObQueryRange::prepare_multi_in_info(const ObOpRawExpr *l_expr,
                                        const ObOpRawExpr *r_expr,
                                        ObKeyPart *&tmp_key_part,
                                        bool &has_rowid,
2980
                                        common::hash::ObHashMap<int64_t, ObKeyPartPos*> &idx_pos_map,
O
obdev 已提交
2981 2982 2983 2984 2985 2986 2987 2988 2989
                                        common::hash::ObHashMap<int64_t, InParamMeta *> &idx_param_map,
                                        common::hash::ObHashMap<int64_t, int64_t> &expr_idx_param_idx_map,
                                        const ObDataTypeCastParams &dtc_params)
{
  int ret = OB_SUCCESS;
  has_rowid = false;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(l_expr), K(r_expr));
2990
  } else if (OB_UNLIKELY(l_expr->get_param_count() > MAX_EXTRACT_IN_COLUMN_NUMBER)) {
K
Klawz 已提交
2991
    // do nothing
2992
  } else if (OB_FAIL(idx_pos_map.create(l_expr->get_param_count(), "IdxKeyMap", "IdxKeyMap"))) {
O
obdev 已提交
2993
    LOG_WARN("fail to init hashmap", K(ret));
2994
  } else if (OB_FAIL(idx_param_map.create(l_expr->get_param_count(), "IdxParamMap", "IdxParamMap"))) {
O
obdev 已提交
2995
    LOG_WARN("fail to init hashmap", K(ret));
2996
  } else if (OB_FAIL(expr_idx_param_idx_map.create(l_expr->get_param_count(), "IdxMap", "IdxMap"))) {
O
obdev 已提交
2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019
    LOG_WARN("fail to init hashmap", K(ret));
  } else {
    int64_t param_cnt = 0;
    for (int64_t i = 0; OB_SUCC(ret) && !has_rowid && i < l_expr->get_param_count(); ++i) {
      const ObRawExpr *expr = l_expr->get_param_expr(i);
      if (OB_ISNULL(expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret));
      } else if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(expr, expr))) {
        LOG_WARN("failed to get expr without lossless cast", K(ret));
      } else if (expr->has_flag(IS_ROWID)) {
        // for multi rowid, we only extract the first one
        if (OB_FAIL(get_rowid_in_key_part(expr, r_expr, i, tmp_key_part, dtc_params))) {
          LOG_WARN("failed to get rowid key part", K(ret));
        } else {
          has_rowid = true;
          query_range_ctx_->cur_expr_is_precise_ = false;
        }
      } else if (!expr->is_column_ref_expr()) {
        query_range_ctx_->cur_expr_is_precise_ = false;
      } else {
        const ObColumnRefRawExpr *col_expr = static_cast<const ObColumnRefRawExpr *>(expr);
        ObKeyPartId key_id(col_expr->get_table_id(), col_expr->get_column_id());
3020
        ObKeyPartPos *key_pos = nullptr;
O
obdev 已提交
3021 3022 3023 3024 3025
        bool b_key_part = false;
        if (OB_FAIL(is_key_part(key_id, key_pos, b_key_part))) {
          LOG_WARN("failed to check key part", K(ret));
        } else if (!b_key_part) {
          query_range_ctx_->cur_expr_is_precise_ = false;
3026 3027 3028
        } else if (OB_ISNULL(key_pos)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get null key part pos");
O
obdev 已提交
3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051
        } else {
          if (tmp_key_part == NULL) {
            if (OB_ISNULL(tmp_key_part = create_new_key_part())) {
              ret = OB_ALLOCATE_MEMORY_FAILED;
              LOG_WARN("get unexpected null", K(ret));
            } else if (OB_FAIL(tmp_key_part->create_in_key())) {
              LOG_WARN("failed to create in key part", K(ret));
            } else {
              tmp_key_part->in_keypart_->table_id_ = col_expr->get_table_id();
            }
          }
          InParamMeta *new_param_meta = NULL;
          if (OB_FAIL(ret)) {
          } else if (OB_ISNULL(new_param_meta =
                     tmp_key_part->in_keypart_->create_param_meta(allocator_))) {
            ret = OB_ALLOCATE_MEMORY_FAILED;
            LOG_WARN("get unexpected null", K(ret));
          } else if (OB_FAIL(idx_pos_map.set_refactored(i, key_pos))) {
            LOG_WARN("failed to set idx to key meta map", K(ret));
          } else if (OB_FAIL(idx_param_map.set_refactored(i, new_param_meta))) {
            LOG_WARN("failed to set idx to key meta map", K(ret));
          } else if (OB_FAIL(expr_idx_param_idx_map.set_refactored(i, param_cnt++))) {
            LOG_WARN("failed to set expr idx to key idx map", K(ret));
3052
          } else if (OB_FAIL(tmp_key_part->in_keypart_->offsets_.push_back(key_pos->offset_))) {
O
obdev 已提交
3053 3054 3055 3056
            LOG_WARN("failed to push back key offset", K(ret));
          } else if (OB_FAIL(tmp_key_part->in_keypart_->in_params_.push_back(new_param_meta))) {
            LOG_WARN("failed to push back param", K(ret));
          } else {
3057
            new_param_meta->pos_ = *key_pos;
O
obdev 已提交
3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127
          }
        }
      }
    }
  }
  return ret;
}

int ObQueryRange::check_const_val_valid(const ObRawExpr *l_expr,
                                        const ObRawExpr *r_expr,
                                        const ObExprResType &res_type,
                                        const ObDataTypeCastParams &dtc_params,
                                        bool &is_valid)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else {
    ObObj l_val;
    ObObj r_val;
    bool l_valid = false;
    bool r_valid = false;
    const ObExprCalcType &calc_type = res_type.get_calc_meta();
    ObCollationType cmp_cs_type = calc_type.get_collation_type();
    // '?' is const too, if " '?' cmp const ", we seem it as true now
    if (OB_FAIL(get_calculable_expr_val(l_expr, l_val, l_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (OB_FAIL(get_calculable_expr_val(r_expr, r_val, r_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (!l_valid || !r_valid) {
      // do nothing
    } else if (l_val.is_null() || r_val.is_null()) {
      is_valid = false;
    } else {
      ObObjType compare_type = ObMaxType;
      int64_t eq_cmp = 0;
      ObCastMode cast_mode = CM_WARN_ON_FAIL;
      ObCastCtx cast_ctx(&allocator_, &dtc_params, cast_mode, cmp_cs_type);
      if (OB_FAIL(ObExprResultTypeUtil::get_relational_cmp_type(compare_type,
                                                                l_val.get_type(),
                                                                r_val.get_type()))) {
        LOG_WARN("get compare type failed", K(ret));
      } else if (OB_FAIL(ObRelationalExprOperator::compare_nullsafe(eq_cmp, l_val, r_val,
                                                                    cast_ctx, compare_type,
                                                                    cmp_cs_type))) {
        LOG_WARN("compare obj failed", K(ret));
      } else if (eq_cmp != 0) {
        is_valid = false;
      }
    }
  }
  return ret;
}

int ObQueryRange::get_param_value(ObInKeyPart *in_key,
                                  InParamMeta *param_meta,
                                  const ObKeyPartPos &pos,
                                  const ObRawExpr *const_expr,
                                  const ObDataTypeCastParams &dtc_params,
                                  bool &is_val_valid)
{
  int ret = OB_SUCCESS;
  is_val_valid = true;
  if (OB_ISNULL(in_key) || OB_ISNULL(param_meta) || OB_ISNULL(const_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(in_key), K(param_meta), K(const_expr));
  } else {
    ObObj val;
    bool is_valid = false;
3128
    if (const_expr->is_immutable_const_expr()) {
O
obdev 已提交
3129 3130 3131
      if (OB_FAIL(get_calculable_expr_val(const_expr, val, is_valid))) {
        LOG_WARN("failed to get calculable expr val", K(ret));
      } else if (!is_valid) {
3132
        is_val_valid = false;
O
obdev 已提交
3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154
      }
    } else {
      if (OB_FAIL(get_final_expr_val(const_expr, val))) {
        LOG_WARN("failed to get final expr idx", K(ret));
      } else {
        query_range_ctx_->need_final_extract_ = true;
        in_key->contain_questionmark_ = true;
      }
    }
    if (OB_SUCC(ret) && (val.is_null() || val.is_ext())) {
      is_val_valid = false;
    }
    int64_t cmp = 0;
    if (OB_FAIL(ret) || !is_val_valid) {
    } else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params, allocator_,
                                                 pos, val, cmp))) {
      LOG_WARN("failed to try cast value type", K(ret));
    } else if (cmp == 0) {
      val.set_collation_type(pos.column_type_.get_collation_type());
    } else {
      is_val_valid = false;
    }
3155 3156 3157
    if (OB_SUCC(ret) && OB_FAIL(param_meta->vals_.push_back(val))) {
      LOG_WARN("failed to push back val", K(ret));
    }
O
obdev 已提交
3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176
  }
  return ret;
}

int ObQueryRange::get_single_in_key_part(const ObColumnRefRawExpr *col_expr,
                                         const ObOpRawExpr *r_expr,
                                         const ObExprResType &res_type,
                                         ObKeyPart *&out_key_part,
                                         const ObDataTypeCastParams &dtc_params)
{
  int ret = OB_SUCCESS;
  ObKeyPart *tmp_key_part = NULL;
  bool is_always_true = false;
  if (OB_ISNULL(col_expr) || OB_ISNULL(r_expr) ||
      OB_UNLIKELY(r_expr->get_param_count() == 0)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get invalid argument", K(ret), K(col_expr), K(r_expr));
  } else {
    ObKeyPartId key_id(col_expr->get_table_id(), col_expr->get_column_id());
3177
    ObKeyPartPos *key_pos = nullptr;
O
obdev 已提交
3178 3179 3180 3181 3182 3183
    bool b_key_part = false;
    InParamMeta *new_param_meta = NULL;
    if (OB_FAIL(is_key_part(key_id, key_pos, b_key_part))) {
      LOG_WARN("failed to check key part", K(ret));
    } else if (!b_key_part) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
3184 3185 3186
    } else if (OB_ISNULL(key_pos)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get null key part pos");
O
obdev 已提交
3187 3188 3189 3190 3191 3192 3193 3194
    } else if (OB_ISNULL(tmp_key_part = create_new_key_part())) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_WARN("failed to create new key part", K(ret));
    } else if (OB_FAIL(tmp_key_part->create_in_key())) {
      LOG_WARN("failed to create in key part", K(ret));
    } else if (OB_ISNULL(tmp_key_part->in_keypart_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get unexpected null", K(ret));
3195
    } else if (OB_FAIL(tmp_key_part->in_keypart_->offsets_.push_back(key_pos->offset_))) {
O
obdev 已提交
3196 3197 3198 3199 3200 3201
      LOG_WARN("failed to push back key offset", K(ret));
    } else if (OB_ISNULL(new_param_meta = tmp_key_part->in_keypart_->create_param_meta(allocator_))) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_WARN("failed to create new param meta", K(ret));
    } else {
      tmp_key_part->in_keypart_->table_id_ = col_expr->get_table_id();
3202
      tmp_key_part->in_keypart_->is_strict_in_ = true;
3203
      new_param_meta->pos_ = *key_pos;
3204
      ObSEArray<int64_t, 4> invalid_val_idx;
O
obdev 已提交
3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217
      bool always_true = false;
      for (int64_t i = 0; OB_SUCC(ret) && !always_true && i < r_expr->get_param_count(); ++i) {
        const ObRawExpr *const_expr = r_expr->get_param_expr(i);
        bool cur_can_be_extract = true;
        bool cur_always_true = true;
        bool is_val_valid = true;
        if (OB_ISNULL(const_expr)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get unexpected null", K(ret));
        } else if (OB_UNLIKELY(!const_expr->is_const_expr())) {
          cur_can_be_extract = false;
          cur_always_true = true;
        } else if (!can_be_extract_range(T_OP_EQ,
3218
                                        key_pos->column_type_,
O
obdev 已提交
3219 3220 3221 3222 3223 3224
                                        res_type.get_calc_meta(),
                                        const_expr->get_result_type().get_type(),
                                        cur_always_true)) {
          cur_can_be_extract = false;
        } else if (OB_FAIL(get_param_value(tmp_key_part->in_keypart_,
                                          new_param_meta,
3225
                                          *key_pos,
O
obdev 已提交
3226 3227 3228 3229 3230 3231 3232 3233 3234
                                          const_expr,
                                          dtc_params,
                                          is_val_valid))) {
          LOG_WARN("failed to get param value", K(ret));
        } else if (!is_val_valid) {
          // do nothing
        } else if (OB_FAIL(check_expr_precise(tmp_key_part,
                                              const_expr,
                                              res_type.get_calc_meta(),
3235
                                              *key_pos))) {
O
obdev 已提交
3236 3237 3238 3239 3240 3241
          LOG_WARN("failed to check expr precise", K(ret));
        }
        if (OB_SUCC(ret) && !cur_can_be_extract && cur_always_true) {
          GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
          always_true = true;
        } // for always false, just no need to add the value to in param
3242 3243 3244
        if (OB_SUCC(ret) && !is_val_valid && OB_FAIL(invalid_val_idx.push_back(i))) {
          LOG_WARN("failed to push back invalid val idx", K(ret));
        }
O
obdev 已提交
3245 3246
      }
      if (OB_SUCC(ret) && !always_true) {
3247
        if (OB_UNLIKELY(new_param_meta->vals_.empty())) {
O
obdev 已提交
3248 3249 3250 3251
          // all always false
          GET_ALWAYS_TRUE_OR_FALSE(false, out_key_part);
        } else if (OB_FAIL(tmp_key_part->in_keypart_->in_params_.push_back(new_param_meta))) {
          LOG_WARN("failed to push back param meta", K(ret));
3252 3253 3254 3255
        } else if (OB_FAIL(tmp_key_part->remove_in_params_vals(invalid_val_idx))) {
          LOG_WARN("failed to adjust in param values", K(ret));
        } else if (OB_FAIL(tmp_key_part->formalize_keypart(contain_row_))) {
          LOG_WARN("failed to formalize in key", K(ret));
O
obdev 已提交
3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355
        } else {
          out_key_part = tmp_key_part;
        }
      }
    }
  }
  return ret;
}

int ObQueryRange::get_rowid_in_key_part(const ObRawExpr *l_expr,
                                        const ObOpRawExpr *r_expr,
                                        const int64_t idx,
                                        ObKeyPart *&out_key_part,
                                        const ObDataTypeCastParams &dtc_params)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(l_expr), K(r_expr));
  } else {
    bool cur_in_is_precise = true;
    ObKeyPart *tmp_tail = NULL;
    ObKeyPart *find_false = NULL;
    for (int64_t i = 0; OB_SUCC(ret) && i < r_expr->get_param_count(); ++i) {
      const ObRawExpr *expr = r_expr->get_param_expr(i);
      const ObRawExpr *cur_param = NULL;
      const ObOpRawExpr *row_expr = NULL;
      ObKeyPart *tmp = NULL;
      if (OB_ISNULL(expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret));
      } else if (idx != -1) { // comes from multi row in
        if (OB_UNLIKELY(T_OP_ROW != expr->get_expr_type()) ||
            OB_ISNULL(row_expr = static_cast<const ObOpRawExpr *>(expr)) ||
            OB_UNLIKELY(idx < 0 || idx >= row_expr->get_param_count())) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get invalid param", K(ret), K(idx), K(*expr), K(*row_expr));
        } else {
          cur_param = row_expr->get_param_expr(idx);
        }
      } else {
        cur_param = expr;
      }
      if (OB_FAIL(ret)) {
      } else if (OB_ISNULL(cur_param)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret));
      } else if (OB_FAIL(get_rowid_key_part(l_expr, cur_param, NULL,
                                            T_OP_EQ, tmp, dtc_params))) {
        LOG_WARN("failed to get rowid key part", K(ret));
      }  else if (OB_ISNULL(tmp) || NULL != tmp->or_next_) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("tmp is null or tmp->or_next is not null", K(ret), K(tmp));
      } else if (tmp->is_always_true()) { // find true , out_key_part -> true, ignore other
        out_key_part = tmp;
        cur_in_is_precise = (cur_in_is_precise && query_range_ctx_->cur_expr_is_precise_);
        break;
      } else if (tmp->is_always_false()) { // find false
        find_false = tmp;
      } else if (NULL == tmp_tail) {
        tmp_tail = tmp;
        out_key_part = tmp;
      } else {
        tmp_tail->or_next_ = tmp;
        tmp_tail = tmp;
      }
      if (OB_SUCC(ret)) {
        cur_in_is_precise = (cur_in_is_precise && query_range_ctx_->cur_expr_is_precise_);
      }
    }
    if (OB_SUCC(ret)) {
      if (NULL != find_false && NULL == out_key_part) {
        out_key_part = find_false;
      }
      query_range_ctx_->cur_expr_is_precise_ = cur_in_is_precise;
    }
  }
  return ret;
}

int ObQueryRange::check_rowid_val(const ObIArray<const ObColumnRefRawExpr *> &pk_column_items,
                                  const ObObj &val, const bool is_physical_rowid)
{
  int ret = OB_SUCCESS;
  uint64_t pk_cnt;
  ObArray<ObObj> pk_vals;
  const ObURowIDData &urowid_data = val.get_urowid();
  if (is_physical_rowid && !urowid_data.is_physical_rowid()) {
    ret = OB_INVALID_ROWID;
    LOG_WARN("get invalid rowid", K(ret), K(urowid_data), K(is_physical_rowid));
  } else if (OB_FAIL(urowid_data.get_pk_vals(pk_vals))) {
    LOG_WARN("get pk values failed", K(ret));
  } else {
    pk_cnt = urowid_data.get_real_pk_count(pk_vals);
    if (OB_UNLIKELY(pk_cnt != pk_column_items.count())) {
      ret = OB_INVALID_ROWID;
      LOG_WARN("invalid rowid, table rowkey cnt and encoded row cnt mismatch", K(ret),
                                                        K(pk_cnt), K(pk_column_items.count()));
    } else {
      for (int i = 0; OB_SUCC(ret) && i < pk_cnt; ++i) {
C
chaser-ch 已提交
3356 3357 3358
        ObObjMeta meta1 = pk_vals.at(i).meta_;
        ObObjMeta meta2 = pk_column_items.at(i)->get_result_type();
        meta2.set_scale(pk_column_items.at(i)->get_scale());
O
obdev 已提交
3359
        if (!pk_vals.at(i).is_null() &&
C
chaser-ch 已提交
3360
            !ObSQLUtils::is_same_type_for_compare(meta1, meta2)) {
O
obdev 已提交
3361 3362
          ret = OB_INVALID_ROWID;
          LOG_WARN("invalid rowid, table rowkey type and encoded type mismatch", K(ret),
C
chaser-ch 已提交
3363 3364
                   K(pk_vals.at(i).meta_), K(pk_vals.at(i).meta_.get_scale()),
                   K(pk_column_items.at(i)->get_result_type()));
O
obdev 已提交
3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408
        }
      }
    }
  }
  return ret;
}

int ObQueryRange::check_expr_precise(ObKeyPart *key_part,
                                     const ObRawExpr *const_expr,
                                     const ObExprCalcType &calc_type,
                                     const ObKeyPartPos &key_pos)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(key_part)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else {
    if (key_pos.column_type_.is_string_type() && calc_type.is_string_type()) {
      if (CS_TYPE_UTF8MB4_GENERAL_CI == key_pos.column_type_.get_collation_type()
          && CS_TYPE_UTF8MB4_GENERAL_CI != calc_type.get_collation_type()) {
        // we will set collation type of value to column's collation type,
        // however, if general bin transform to general ci,
        // the result may be N:1, the range may be amplified and turn to inprecise
        query_range_ctx_->cur_expr_is_precise_ = false;
      }
    }
    if (is_oracle_mode() && NULL != const_expr &&
        (key_part->is_normal_key() || key_part->is_in_key())) {
      // c1 char(5), c2 varchar(5) 对于值'abc', c1 = 'abc  ', c2 = 'abc'
      // in oracle mode, 'abc  ' is not equals to 'abc', but the range of c1 = cast('abc' as varchar2(5))
      // is extracted as (abc ; abc), this is because that storage layer does not padding emptycharacter,
      // as a result, by using the range above, value 'abc  ' is selected, which is incorrect.
      // to avoid this, set the range to be not precise
      const ObObjType &column_type = key_pos.column_type_.get_type();
      const ObObjType &const_type = const_expr->get_result_type().get_type();
      if ((ObCharType == column_type && ObVarcharType == const_type) ||
          (ObNCharType == column_type && ObNVarchar2Type == const_type)) {
        query_range_ctx_->cur_expr_is_precise_ = false;
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3409 3410 3411 3412 3413 3414 3415 3416
// treat L NOT IN (R1, ... , Rn) operation as '(L < R1 or L > R1) and ... and (L < Rn or L > Rn)'
int ObQueryRange::pre_extract_not_in_op(const ObOpRawExpr *b_expr,
                                        ObKeyPart *&out_key_part,
                                        const ObDataTypeCastParams &dtc_params)
{
  int ret = OB_SUCCESS;
  const ObRawExpr *l_expr = NULL;
  const ObOpRawExpr *r_expr = NULL;
3417 3418 3419 3420
  ObSQLSessionInfo *session = NULL;
  bool enable_not_in_range = false;
  if (OB_ISNULL(b_expr) || OB_ISNULL(query_range_ctx_) || OB_ISNULL(query_range_ctx_->exec_ctx_)
      || OB_ISNULL(session = query_range_ctx_->exec_ctx_->get_my_session())) {
W
wangzelin.wzl 已提交
3421
    ret = OB_INVALID_ARGUMENT;
3422
    LOG_WARN("unexpected null", K(b_expr), K_(query_range_ctx), K(session));
W
wangzelin.wzl 已提交
3423 3424
  } else if (2 != b_expr->get_param_count()) {//binary op expr
    ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
3425
    LOG_WARN("b_expr must has 2 arguments", K(ret));
W
wangzelin.wzl 已提交
3426 3427 3428 3429
  } else if (OB_ISNULL(l_expr = b_expr->get_param_expr(0)) ||
             OB_ISNULL(r_expr = static_cast<const ObOpRawExpr *>(b_expr->get_param_expr(1)))) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("r_expr is null.", K(ret));
3430 3431 3432 3433 3434
  } else if (OB_FAIL(session->is_enable_range_extraction_for_not_in(enable_not_in_range))) {
    LOG_WARN("failed to check not in range enabled", K(ret));
  } else if (!enable_not_in_range || r_expr->get_param_count() > MAX_NOT_IN_SIZE
             || l_expr->get_expr_type() == T_OP_ROW) {
    // do not extract range: 1. not in range is disabled; 2. not in size over MAX_NOT_IN_SIZE
W
wangzelin.wzl 已提交
3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    query_range_ctx_->cur_expr_is_precise_ = false;
  } else {
    bool cur_expr_is_precise = true;
    ObKeyPartList key_part_list;
    ObArenaAllocator alloc;
    for (int64_t i = 0; OB_SUCC(ret) && i < r_expr->get_param_count(); ++i) {
      ObKeyPart *tmp = NULL;
      ObExprResType res_type(alloc);
      ObKeyPartList or_array;
      bool cur_or_is_precise = true;
      if (OB_FAIL(get_in_expr_res_type(b_expr, i, res_type))) {
        LOG_WARN("get in expr element result type failed", K(ret), K(i));
      }
      for (int64_t j = 0; OB_SUCC(ret) && j < 2; ++j) {
        query_range_ctx_->cur_expr_is_precise_ = false;
3451
        bool dummy_is_bound_modified = false;
W
wangzelin.wzl 已提交
3452 3453 3454 3455 3456 3457
        if (OB_FAIL(get_basic_query_range(l_expr,
                                          r_expr->get_param_expr(i),
                                          NULL,
                                          j == 0 ? T_OP_LT : T_OP_GT,
                                          res_type,
                                          tmp,
3458 3459
                                          dtc_params,
                                          dummy_is_bound_modified))) {
W
wangzelin.wzl 已提交
3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490
          LOG_WARN("Get basic query range failed", K(ret));
        } else if (OB_FAIL(add_or_item(or_array, tmp))) {
          LOG_WARN("push back failed", K(ret));
        } else {
          cur_or_is_precise = (cur_or_is_precise && query_range_ctx_->cur_expr_is_precise_);
        }
      }
      if (OB_SUCC(ret)) {
        query_range_ctx_->cur_expr_is_precise_ = cur_or_is_precise;
        if (OB_FAIL(or_range_graph(or_array, NULL, tmp, dtc_params))) {
          LOG_WARN("or range graph failed", K(ret));
        } else if (OB_FAIL(add_and_item(key_part_list, tmp))) {
          LOG_WARN("push back failed", K(ret));
        } else {
          cur_expr_is_precise = (cur_expr_is_precise && query_range_ctx_->cur_expr_is_precise_);
        }
      }
    }

    if (OB_SUCC(ret)) {
      query_range_ctx_->cur_expr_is_precise_ = cur_expr_is_precise;
      if (OB_FAIL(and_range_graph(key_part_list, out_key_part))) {
        LOG_WARN("and range graph failed", K(ret));
      }
    }
  }
  return ret;
}

int ObQueryRange::pre_extract_and_or_op(const ObOpRawExpr *m_expr,
                                        ObKeyPart *&out_key_part,
3491
                                        const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
3492 3493 3494 3495 3496 3497 3498 3499 3500
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(m_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", K(m_expr), K_(query_range_ctx));
  } else {
    bool cur_expr_is_precise = true;
    ObKeyPartList key_part_list;
    for (int64_t i = 0; OB_SUCC(ret) && i < m_expr->get_param_count(); ++i) {
W
wangzelin.wzl 已提交
3501
      ObKeyPart *tmp = NULL;
O
oceanbase-admin 已提交
3502
      query_range_ctx_->cur_expr_is_precise_ = false;
3503
      if (OB_FAIL(preliminary_extract(m_expr->get_param_expr(i), tmp, dtc_params))) {
O
oceanbase-admin 已提交
3504 3505 3506 3507 3508
        LOG_WARN("preliminary_extract failed", K(ret));
      } else if (T_OP_AND == m_expr->get_expr_type()) {
        if (OB_FAIL(add_and_item(key_part_list, tmp))) {
          LOG_WARN("push back failed", K(ret));
        }
W
wangzelin.wzl 已提交
3509
      } else { //T_OP_OR
O
oceanbase-admin 已提交
3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533
        if (OB_FAIL(add_or_item(key_part_list, tmp))) {
          LOG_WARN("push back failed", K(ret));
        }
      }
      if (OB_SUCC(ret)) {
        cur_expr_is_precise = (cur_expr_is_precise && query_range_ctx_->cur_expr_is_precise_);
      }
    }
    if (OB_SUCC(ret)) {
      query_range_ctx_->cur_expr_is_precise_ = cur_expr_is_precise;
      if (T_OP_AND == m_expr->get_expr_type()) {
        if (OB_FAIL(and_range_graph(key_part_list, out_key_part))) {
          LOG_WARN("and range graph failed", K(ret));
        }
      } else {
        if (OB_FAIL(or_range_graph(key_part_list, NULL, out_key_part, dtc_params))) {
          LOG_WARN("or range graph failed", K(ret));
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3534 3535
int ObQueryRange::pre_extract_const_op(const ObRawExpr *c_expr,
                                       ObKeyPart *&out_key_part)
O
oceanbase-admin 已提交
3536 3537 3538 3539 3540 3541
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(c_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", K(c_expr), K_(query_range_ctx));
  } else {
W
wangzelin.wzl 已提交
3542 3543
    ObObj val;
    bool is_valid = false;
O
oceanbase-admin 已提交
3544 3545
    bool b_val = false;
    query_range_ctx_->cur_expr_is_precise_ = false;
3546
    if (!c_expr->is_immutable_const_expr()) {
O
oceanbase-admin 已提交
3547
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
W
wangzelin.wzl 已提交
3548 3549 3550 3551 3552
    } else if (OB_FAIL(get_calculable_expr_val(c_expr, val, is_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (!is_valid) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    } else if (OB_FAIL(ObObjEvaluator::is_true(val, b_val))) {
O
oceanbase-admin 已提交
3553 3554 3555 3556 3557 3558 3559 3560
      LOG_WARN("get bool value failed.", K(ret));
    } else {
      GET_ALWAYS_TRUE_OR_FALSE(b_val, out_key_part);
    }
  }
  return ret;
}

O
obdev 已提交
3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585
int ObQueryRange::get_dwithin_item(const ObRawExpr *expr, const ObConstRawExpr *&extra_item)
{
  int ret = OB_SUCCESS;
  if (expr->get_param_count() != 3) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid param num", K(expr->get_param_count()));
  } else {
    extra_item = static_cast<const ObConstRawExpr *>(expr->get_param_expr(2));
    if (OB_ISNULL(extra_item)) {
      ret = OB_INVALID_ARGUMENT;
      LOG_WARN("invalid param val", K(ret));
    }
  }
  return ret;
}

int ObQueryRange::set_geo_keypart_whole_range(ObKeyPart &out_key_part)
{
  int ret = OB_SUCCESS;
  if (OB_FAIL(out_key_part.create_normal_key())) {
    LOG_WARN("create normal key failed", K(ret));
  } else if (OB_ISNULL(out_key_part.normal_keypart_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("normal keypart is null", K(ret));
  } else {
K
Klawz 已提交
3586
    // set whole range when const expr calculate failed in constant fold
O
obdev 已提交
3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623
    out_key_part.normal_keypart_->start_.set_min_value();
    out_key_part.normal_keypart_->end_.set_max_value();
    out_key_part.normal_keypart_->always_false_ = false;
    out_key_part.normal_keypart_->always_true_ = true;
    out_key_part.normal_keypart_->include_start_ = false;
    out_key_part.normal_keypart_->include_end_ = false;
  }
  return ret;
}

int ObQueryRange::pre_extract_geo_op(const ObOpRawExpr *geo_expr,
                                     ObKeyPart *&out_key_part,
                                     const ObDataTypeCastParams &dtc_params)
{
  UNUSED(dtc_params);
  int ret = OB_SUCCESS;
  if (OB_ISNULL(geo_expr) || OB_ISNULL(query_range_ctx_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("expr is null.", KP(geo_expr), K_(query_range_ctx));
  } else {
    bool cur_expr_is_precise = true;
    ObKeyPartList key_part_list;
    const ObRawExpr *expr = ObRawExprUtils::skip_inner_added_expr(geo_expr);
    const ObRawExpr *l_expr = expr->get_param_expr(0);
    const ObRawExpr *r_expr = expr->get_param_expr(1);
    const ObConstRawExpr *extra_item = NULL;
    const ObRawExpr *const_item = NULL;
    const ObColumnRefRawExpr *column_item = NULL;
    common::ObGeoRelationType op_type;
    if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    } else if (l_expr->has_flag(IS_COLUMN) && r_expr->has_flag(IS_COLUMN)) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    } else if (l_expr->has_flag(IS_DYNAMIC_PARAM) && r_expr->has_flag(IS_DYNAMIC_PARAM)) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    } else {
      op_type = get_geo_relation(expr->get_expr_type());
O
obdev 已提交
3624 3625
      if (OB_UNLIKELY(r_expr->has_flag(CNT_COLUMN))) {
        column_item = ObRawExprUtils::get_column_ref_expr_recursively(r_expr);
O
obdev 已提交
3626
        const_item = l_expr;
O
obdev 已提交
3627 3628
      } else if (l_expr->has_flag(CNT_COLUMN)) {
        column_item = ObRawExprUtils::get_column_ref_expr_recursively(l_expr);
O
obdev 已提交
3629 3630 3631 3632
        const_item = r_expr;
        op_type = (ObGeoRelationType::T_COVERS == op_type ? ObGeoRelationType::T_COVEREDBY :
                  (ObGeoRelationType::T_COVEREDBY == op_type ? ObGeoRelationType::T_COVERS : op_type));
      } else {
O
obdev 已提交
3633 3634 3635 3636 3637 3638 3639
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("failed to find column item", K(ret), KPC(r_expr), KPC(l_expr));
      }

      if (OB_SUCC(ret) && OB_ISNULL(column_item)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("failed to find column item", K(ret), KPC(r_expr), KPC(l_expr));
O
obdev 已提交
3640 3641 3642
      }

      if (OB_SUCC(ret)) {
O
obdev 已提交
3643 3644 3645 3646 3647 3648 3649 3650 3651
        bool is_cellid_col = false;
        uint64_t column_id = column_item->get_column_id();
        ObGeoColumnInfo column_info;
        if (OB_FAIL(columnId_map_.get_refactored(column_id, column_info))) {
          if (OB_NOT_INIT == ret || OB_HASH_NOT_EXIST == ret) {
            ret = OB_SUCCESS;
          } else {
            LOG_WARN("failed to get from columnId_map_", K(ret));
          }
O
obdev 已提交
3652
        } else {
O
obdev 已提交
3653 3654 3655
          is_cellid_col = true;
        }
        if (OB_SUCC(ret)) {
3656
          if (!const_item->is_immutable_const_expr()) {
O
obdev 已提交
3657
            query_range_ctx_->need_final_extract_ = true;
O
obdev 已提交
3658
          }
O
obdev 已提交
3659 3660
          ObKeyPartId key_part_id(column_item->get_table_id(),
                                  is_cellid_col ? column_info.cellid_columnId_ : column_id);
3661
          ObKeyPartPos *key_part_pos = nullptr;
O
obdev 已提交
3662 3663 3664 3665
          bool b_is_key_part = false;
          if (OB_FAIL(is_key_part(key_part_id, key_part_pos, b_is_key_part))) {
            LOG_WARN("is_key_part failed", K(ret));
          } else if (!b_is_key_part) {
O
obdev 已提交
3666
            GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
3667 3668 3669
          } else if (OB_ISNULL(key_part_pos)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("get null key part pos");
O
obdev 已提交
3670 3671 3672
          } else if (OB_ISNULL((out_key_part = create_new_key_part()))) {
            ret = OB_ALLOCATE_MEMORY_FAILED;
            LOG_ERROR("alloc memory failed", K(ret));
O
obdev 已提交
3673
          } else {
O
obdev 已提交
3674 3675
            contain_geo_filters_ = true;
            out_key_part->id_ = key_part_id;
3676
            out_key_part->pos_ = *key_part_pos;
O
obdev 已提交
3677 3678 3679
            if (op_type == ObGeoRelationType::T_DWITHIN) {
              if (OB_FAIL(get_dwithin_item(expr, extra_item))) {
                LOG_WARN("failed to get dwithin item", K(ret));
O
obdev 已提交
3680
              }
O
obdev 已提交
3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699
            }

            ObObj const_val;
            bool is_valid = true;
            if (OB_FAIL(ret)) {
              // do nothing
            } else if (OB_FAIL(get_calculable_expr_val(const_item, const_val, is_valid))) {
              LOG_WARN("failed to get calculable expr val", K(ret));
            } else if (!is_valid) {
              GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
            } else if (OB_FAIL(out_key_part->create_geo_key())) {
              LOG_WARN("create like geo part failed", K(ret));
            } else if (extra_item != NULL &&
                      OB_FAIL(get_calculable_expr_val(extra_item,
                                                      out_key_part->geo_keypart_->distance_,
                                                      is_valid))) {
              LOG_WARN("failed to get calculable expr val", K(ret));
            } else if (!is_valid) {
              GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
O
obdev 已提交
3700
            } else {
3701
              if (!const_item->is_immutable_const_expr()) {
O
obdev 已提交
3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713
                ObObj val;
                out_key_part->geo_keypart_->geo_type_ = op_type;
                if (OB_FAIL(get_final_expr_val(const_item, out_key_part->geo_keypart_->wkb_))) {
                  LOG_WARN("failed to get final expr idx", K(ret));
                } else if (extra_item != NULL &&
                          OB_FAIL(get_final_expr_val(extra_item, out_key_part->geo_keypart_->distance_))) {
                    LOG_WARN("failed to get final distance expr idx", K(ret));
                }
              } else {
                if (OB_FAIL(get_geo_range(const_val, op_type, out_key_part))) {
                  LOG_WARN("create geo range failed", K(ret));
                }
O
obdev 已提交
3714 3715 3716 3717 3718 3719 3720 3721 3722 3723
              }
            }
          }
        }
      }
    }
  }
  return ret;
}

O
oceanbase-admin 已提交
3724 3725 3726
//  For each index, preliminary extract query range,
//  the result may contain prepared '?' expression.
//  If prepared '?' expression exists, final extract action is needed
W
wangzelin.wzl 已提交
3727 3728 3729
int ObQueryRange::preliminary_extract(const ObRawExpr *node,
                                      ObKeyPart *&out_key_part,
                                      const ObDataTypeCastParams &dtc_params,
3730
                                      const bool is_single_in)
O
oceanbase-admin 已提交
3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742
{
  int ret = OB_SUCCESS;
  out_key_part = NULL;
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to do stack overflow check", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack overflow", K(ret));
  } else if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("argument is not inited", K(ret), KP(node), KP(query_range_ctx_));
W
wangzelin.wzl 已提交
3743
  } else if(NULL == node) {
O
oceanbase-admin 已提交
3744 3745
    // do nothing
  } else if (node->is_const_expr()) {
W
wangzelin.wzl 已提交
3746
    if(OB_FAIL(pre_extract_const_op(node, out_key_part))) {
O
oceanbase-admin 已提交
3747 3748 3749
      LOG_WARN("extract is_op failed", K(ret));
    }
  } else {
W
wangzelin.wzl 已提交
3750
    const ObOpRawExpr *b_expr = static_cast<const ObOpRawExpr *>(node);
O
oceanbase-admin 已提交
3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770
    if (IS_BASIC_CMP_OP(node->get_expr_type())) {
      if (OB_FAIL(pre_extract_basic_cmp(node, out_key_part, dtc_params))) {
        LOG_WARN("extract basic cmp failed", K(ret));
      }
    } else if (T_OP_NE == node->get_expr_type()) {
      if (OB_FAIL(pre_extract_ne_op(b_expr, out_key_part, dtc_params))) {
        LOG_WARN("extract ne_op failed", K(ret));
      }
    } else if (T_OP_IS == node->get_expr_type()) {
      if (OB_FAIL(pre_extract_is_op(b_expr, out_key_part, dtc_params))) {
        LOG_WARN("extract is_op failed", K(ret));
      }
    } else if (T_OP_BTW == node->get_expr_type()) {
      if (OB_FAIL(pre_extract_btw_op(b_expr, out_key_part, dtc_params))) {
        LOG_WARN("extract btw_op failed", K(ret));
      }
    } else if (T_OP_NOT_BTW == node->get_expr_type()) {
      if (OB_FAIL(pre_extract_not_btw_op(b_expr, out_key_part, dtc_params))) {
        LOG_WARN("extract not_btw failed", K(ret));
      }
W
wangzelin.wzl 已提交
3771
    } else if (T_OP_IN  == node->get_expr_type()) {
3772 3773
      if (OB_FAIL(pre_extract_in_op(b_expr, out_key_part, dtc_params, is_single_in))) {
        LOG_WARN("extract in_op failed", K(ret));
O
oceanbase-admin 已提交
3774
      }
W
wangzelin.wzl 已提交
3775 3776 3777 3778
    } else if (T_OP_NOT_IN  == node->get_expr_type()) {
      if (OB_FAIL(pre_extract_not_in_op(b_expr, out_key_part, dtc_params))) {
        LOG_WARN("extract in_op failed", K(ret));
      }
O
oceanbase-admin 已提交
3779
    } else if (T_OP_AND == node->get_expr_type() || T_OP_OR == node->get_expr_type()) {
3780
      if (OB_FAIL(pre_extract_and_or_op(b_expr, out_key_part, dtc_params))) {
O
oceanbase-admin 已提交
3781 3782
        LOG_WARN("extract and_or failed", K(ret));
      }
O
obdev 已提交
3783 3784 3785 3786
    } else if (node->is_spatial_expr()) {
      if (OB_FAIL(pre_extract_geo_op(b_expr, out_key_part, dtc_params))) {
        LOG_WARN("extract and_or failed", K(ret));
      }
O
oceanbase-admin 已提交
3787 3788 3789 3790 3791 3792 3793 3794
    } else {
      query_range_ctx_->cur_expr_is_precise_ = false;
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    }
  }
  return ret;
}

3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899
int ObQueryRange::pre_extract_in_op(const ObOpRawExpr *b_expr,
                                    ObKeyPart *&out_key_part,
                                    const ObDataTypeCastParams &dtc_params,
                                    const bool is_single_in)
{
  int ret = OB_SUCCESS;
  bool use_in_optimization = false;
  if (OB_ISNULL(query_range_ctx_) || OB_ISNULL(b_expr) ||
      OB_UNLIKELY(b_expr->get_expr_type() != T_OP_IN || 2 != b_expr->get_param_count())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get invalid argument", K(ret), K(query_range_ctx_), K(b_expr));
  } else if (OB_FAIL(check_row_in_need_in_optimization(b_expr, is_single_in, use_in_optimization))) {
    LOG_WARN("failed to check need use_in_optimization", K(ret));
  } else if (use_in_optimization) {
    if (OB_FAIL(pre_extract_in_op_with_opt(b_expr, out_key_part, dtc_params))) {
      LOG_WARN("extract single in_op failed", K(ret));
    } else if (OB_ISNULL(out_key_part)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get unexpected null", K(ret));
    } else if (!out_key_part->is_always_true() && !out_key_part->is_always_false()) {
      contain_in_ = true;
    }
  } else {
    if (is_single_in) {
      if (OB_FAIL(pre_extract_single_in_op(b_expr, out_key_part, dtc_params))) {
        LOG_WARN("extract single in_op failed", K(ret));
      }
    } else if (OB_FAIL(pre_extract_complex_in_op(b_expr, out_key_part, dtc_params))) {
      LOG_WARN("extract in_op failed", K(ret));
    }
  }
  LOG_TRACE("succeed to extract range from in_expr", K(ret),
    K(use_in_optimization), K(contain_in_), K(query_range_ctx_), KPC(out_key_part));
  return ret;
}

int ObQueryRange::check_row_in_need_in_optimization(const ObOpRawExpr *b_expr,
                                                    const bool is_single_in,
                                                    bool &use_in_optimization)
{
  int ret = OB_SUCCESS;
  use_in_optimization = false;
  const ObRawExpr *l_expr = NULL;
  if (OB_ISNULL(query_range_ctx_) || OB_ISNULL(b_expr) ||
      OB_UNLIKELY(b_expr->get_expr_type() != T_OP_IN || 2 != b_expr->get_param_count())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get invalid argument", K(ret), K(query_range_ctx_), K(b_expr));
  } else if (OB_FALSE_IT(use_in_optimization = query_range_ctx_->use_in_optimization_) ||
             OB_FALSE_IT(l_expr = b_expr->get_param_expr(0))) {
    // do nothing
  } else if (OB_ISNULL(l_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else if (l_expr->get_expr_type() == T_OP_ROW) {
    ObSEArray<int64_t, 4> offsets;
    if (!is_single_in) {
      // (c1,c2) in (xxx) or other exprs are not allowed to use in optimization
      use_in_optimization = false;
    } else {
      for (int64_t i = 0; OB_SUCC(ret) && use_in_optimization && i < l_expr->get_param_count(); ++i) {
        const ObRawExpr *expr = l_expr->get_param_expr(i);
        if (OB_ISNULL(expr)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get unexpected null", K(ret));
        } else if (OB_FAIL(ObOptimizerUtil::get_expr_without_lossless_cast(expr, expr))) {
          LOG_WARN("failed to get expr without lossless cast", K(ret));
        } else if (!expr->is_column_ref_expr()) {
          use_in_optimization = false;
        } else {
          const ObColumnRefRawExpr *col_expr = static_cast<const ObColumnRefRawExpr *>(expr);
          ObKeyPartId key_id(col_expr->get_table_id(), col_expr->get_column_id());
          ObKeyPartPos *key_pos = nullptr;
          bool b_key_part = false;
          if (OB_FAIL(is_key_part(key_id, key_pos, b_key_part))) {
            LOG_WARN("failed to check key part", K(ret));
          } else if (!b_key_part) {
            use_in_optimization = false;
          } else if (OB_ISNULL(key_pos)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("get null key part pos");
          } else if (OB_FAIL(offsets.push_back(key_pos->offset_))) {
            LOG_WARN("failed to push back offsets", K(ret));
          }
        }
      }
      if (OB_SUCC(ret) && use_in_optimization) {
        if (offsets.empty()) {
          use_in_optimization = false;
        } else {
          std::sort(offsets.begin(), offsets.end());
          int64_t start_pos = offsets.at(0);
          for (int64_t i = 1; OB_SUCC(ret) && use_in_optimization && i < offsets.count(); ++i) {
            int64_t cur_off = offsets.at(i);
            if (++start_pos != cur_off) {
              use_in_optimization = false;
            }
          }
        }
      }
    }
    LOG_TRACE("succeed to check row_in need in_optimization", K(use_in_optimization), K(offsets), KPC(l_expr));
  }
  return ret;
}

W
wangzelin.wzl 已提交
3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925
int ObQueryRange::check_null_param_compare_in_row(const ObRawExpr *l_expr,
                                                  const ObRawExpr *r_expr,
                                                  ObKeyPart *&out_key_part)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_expr) || OB_ISNULL(r_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected error", K(ret), KP(l_expr), KP(r_expr));
  } else if (((l_expr->has_flag(IS_COLUMN) || l_expr->has_flag(IS_ROWID)) && r_expr->is_const_expr()) ||
             (l_expr->is_const_expr() && (r_expr->has_flag(IS_COLUMN) || r_expr->has_flag(IS_ROWID)))) {
    const ObRawExpr *const_expr = l_expr->is_const_expr() ? l_expr : r_expr;
    ObObj const_val;
    bool is_valid = false;
    if (const_expr->has_flag(CNT_DYNAMIC_PARAM)) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    } else if (OB_FAIL(get_calculable_expr_val(const_expr, const_val, is_valid))) {
      LOG_WARN("failed to get calculable expr val", K(ret));
    } else if (!is_valid) {
      //do nothing
    } else if (const_val.is_null()) {
      GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    }
  } else {/*do nothing*/}
  return ret;
}

O
obdev 已提交
3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941
void ObQueryRange::print_keypart(const ObKeyPart *keypart, const ObString &prefix) const
{
  // or dir
  for (const ObKeyPart *cur = keypart; cur != NULL; cur = cur->or_next_) {
    LOG_TRACE("or_keypart", K(*cur), K(prefix));
  }
  // and dir
  for (const ObKeyPart *cur = keypart; cur != NULL; cur = cur->and_next_) {
    LOG_TRACE("and_keypart", K(*cur), K(prefix));
  }
  // item dir
  for (const ObKeyPart *cur = keypart; cur != NULL; cur = cur->item_next_) {
    LOG_TRACE("and_keypart", K(*cur), K(prefix));
  }
}

W
wangzelin.wzl 已提交
3942 3943
int ObQueryRange::get_in_expr_res_type(const ObRawExpr *in_expr, int64_t val_idx,
                                       ObExprResType &res_type) const
O
oceanbase-admin 已提交
3944 3945
{
  int ret = OB_SUCCESS;
O
obdev 已提交
3946 3947 3948 3949
  const ObRawExpr *l_expr = NULL;
  ObSEArray<ObExprCalcType, 4> calc_types;
  int64_t row_dimension = OB_INVALID_ID;
  if (OB_ISNULL(in_expr) || OB_UNLIKELY(in_expr->get_param_count() <= 0)) {
O
oceanbase-admin 已提交
3950
    ret = OB_INVALID_ARGUMENT;
O
obdev 已提交
3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962
    LOG_WARN("in_expr is null.", K(ret), K(in_expr));
  } else if (OB_ISNULL(l_expr = in_expr->get_param_expr(0))) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else if (OB_FAIL(calc_types.assign(in_expr->get_result_type().get_row_calc_cmp_types()))) {
    LOG_WARN("failed to assign calc types", K(ret));
  } else if (T_OP_ROW != l_expr->get_expr_type()) {
    res_type.set_calc_meta(calc_types.at(val_idx));
  } else if (OB_FALSE_IT(row_dimension = (T_OP_ROW == l_expr->get_expr_type()) ?
                                          l_expr->get_param_count() : 1)) {
  } else if (OB_FAIL(res_type.init_row_dimension(row_dimension))) {
    LOG_WARN("fail to init row dimension", K(ret), K(row_dimension));
O
oceanbase-admin 已提交
3963
  } else {
O
obdev 已提交
3964 3965
    for (int64_t i = 0; OB_SUCC(ret) && i < row_dimension; ++i) {
      ret = res_type.get_row_calc_cmp_types().push_back(calc_types.at(val_idx * row_dimension + i));
O
oceanbase-admin 已提交
3966 3967 3968 3969 3970
    }
  }
  return ret;
}

3971
int ObQueryRange::is_key_part(const ObKeyPartId &id, ObKeyPartPos *&pos, bool &is_key_part)
O
oceanbase-admin 已提交
3972 3973
{
  int ret = OB_SUCCESS;
O
obdev 已提交
3974 3975
  is_key_part = false;
  if (OB_ISNULL(query_range_ctx_)) {
O
oceanbase-admin 已提交
3976 3977 3978
    ret = OB_NOT_INIT;
    LOG_WARN("query_range_ctx_ is not inited.", K(ret));
  } else {
O
obdev 已提交
3979
    int64_t max_off = query_range_ctx_->max_valid_offset_;
O
oceanbase-admin 已提交
3980
    int map_ret = query_range_ctx_->key_part_map_.get_refactored(id, pos);
3981 3982
    if (OB_SUCCESS == map_ret && OB_NOT_NULL(pos) &&
        (max_off == -1 || (max_off != - 1 && pos->offset_ <= max_off))) {
O
oceanbase-admin 已提交
3983 3984
      is_key_part = true;
      SQL_REWRITE_LOG(DEBUG, "id pair is  key part", K_(id.table_id), K_(id.column_id));
O
obdev 已提交
3985 3986 3987 3988
    } else if (OB_HASH_NOT_EXIST != map_ret) {
      ret = map_ret;
      LOG_WARN("get kay_part_id from hash map failed",
                      K(ret), K_(id.table_id), K_(id.column_id));
O
oceanbase-admin 已提交
3989
    } else {
O
obdev 已提交
3990 3991
      is_key_part = false;
      SQL_REWRITE_LOG(DEBUG, "id pair is not key part", K_(id.table_id), K_(id.column_id));
O
oceanbase-admin 已提交
3992 3993 3994 3995 3996 3997 3998 3999
    }
  }
  return ret;
}

// split the head key part to general term or-array.
// each gt has its own and_next_, so no need to deep copy it.

W
wangzelin.wzl 已提交
4000
int ObQueryRange::split_general_or(ObKeyPart *graph, ObKeyPartList &or_storage)
O
oceanbase-admin 已提交
4001 4002 4003 4004
{
  int ret = OB_SUCCESS;
  or_storage.clear();
  if (NULL != graph) {
W
wangzelin.wzl 已提交
4005
    ObKeyPart *cur_gt = graph;
O
oceanbase-admin 已提交
4006
    while (NULL != cur_gt && OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
4007
      ObKeyPart *or_next_gt = cur_gt->cut_general_or_next();
O
oceanbase-admin 已提交
4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020
      if (!or_storage.add_last(cur_gt)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("Split graph to or array failed", K(ret));
      } else {
        cur_gt = or_next_gt;
      }
    }
  } else {
    // do nothing
  }
  return ret;
}

W
wangzelin.wzl 已提交
4021

O
oceanbase-admin 已提交
4022 4023 4024
// split the head key part to or-list
// several or key parts may share and_next_, so deep copy is needed.

W
wangzelin.wzl 已提交
4025
int ObQueryRange::split_or(ObKeyPart *graph, ObKeyPartList &or_list)
O
oceanbase-admin 已提交
4026 4027 4028
{
  int ret = OB_SUCCESS;
  if (NULL != graph) {
W
wangzelin.wzl 已提交
4029 4030
    ObKeyPart *cur = (graph);
    ObKeyPart *prev_and_next = NULL;
O
oceanbase-admin 已提交
4031
    while (OB_SUCC(ret) && NULL != cur) {
W
wangzelin.wzl 已提交
4032
      ObKeyPart *or_next = cur->or_next_;
O
oceanbase-admin 已提交
4033 4034 4035 4036
      if (cur->and_next_ != prev_and_next) {
        prev_and_next = cur->and_next_;
      } else {
        if (NULL != prev_and_next) {
W
wangzelin.wzl 已提交
4037
          ObKeyPart *new_and_next = NULL;
O
oceanbase-admin 已提交
4038 4039
          if (OB_FAIL(deep_copy_range_graph(cur->and_next_, new_and_next))) {
            LOG_WARN("Copy range graph failed", K(ret));
4040 4041 4042 4043
          } else if (is_reach_mem_limit_) {
            cur->and_next_ = NULL;
          } else {
            cur->and_next_ = new_and_next;
O
oceanbase-admin 已提交
4044 4045 4046 4047 4048
          }
        }
      }
      if (OB_SUCC(ret)) {
        cur->or_next_ = NULL;
O
obdev 已提交
4049
        if (OB_UNLIKELY(!or_list.add_last(cur))) {
O
oceanbase-admin 已提交
4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Split graph to or array failed", K(ret));
        } else {
          cur = or_next;
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4061
//int ObQueryRange::deal_not_align_keypart(ObKeyPart *l_cur,
O
oceanbase-admin 已提交
4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138
//                                         ObKeyPart *r_cur,
//                                         const int64_t &s_offset,
//                                         const int64_t &e_offset,
//                                         ObKeyPart *&rest1)
//{
//  int ret = OB_SUCCESS;
//  ObKeyPart *tail = NULL;
//  while (OB_SUCC(ret)
//         && ) {
//    ObKeyPart *new_key_part = NULL;
//    if (OB_FAIL(alloc_full_key_part(new_key_part))) {
//      //warn
//    } else if (NULL != l_cur && NULL != r_cur) {
//      if (l_cur->pos_.offset_ < r_cur->pos_.offset_) {
//        if (s_need_continue) {
//          new_key_part->set_normal_start(l_cur);
//        }
//        if (e_need_continue) {
//          new_key_part->set_normal_end(l_cur);
//        }
//        if (OB_FAIL(link_item(new_key_part, l_cur))) {
//          //warn
//        } else if (NULL != l_cur->or_next_) {
//          l_cur = NULL;
//        } else {
//          l_cur = l_cur->and_next_;
//        }
//      } else if (l_cur->pos_.offset_ > r_cur->pos_.offset_) {
//        if (s_need_continue) {
//          new_key_part->set_normal_start(r_cur);
//        }
//        if (e_need_continue) {
//          new_key_part->set_normal_end(r_cur);
//        }
//        if (OB_FAIL(link_item(new_key_part, r_cur))) {
//          //warn
//        } else if (NULL != r_cur->or_next_) {
//          r_cur = NULL;
//        } else {
//          r_cur = r_cur->and_next_;
//        }
//      }
//    } else {
//      if (NULL == l_cur) {
//        new_key_part->set_normal_start(r_cur);
//        new_key_part->set_normal_end(r_cur);
//        if (OB_FAIL(link_item(new_key_part, r_cur))) {
//          //warn
//        } else if (NULL != r_cur->or_next_) {
//          r_cur = NULL;
//        } else {
//          r_cur = r_cur->and_next_;
//        }
//      } else if (NULL == r_cur) {
//        new_key_part->set_normal_start(l_cur);
//        new_key_part->set_normal_end(l_cur);
//        if (OB_FAIL(link_item(new_key_part, l_cur))) {
//          //warn
//        } else if (NULL != l_cur->or_next_) {
//          l_cur = NULL;
//        } else {
//          l_cur = l_cur->and_next_;
//        }
//      }
//    }
//    if (OB_SUCC(ret) && NULL != new_key_part) {
//      if (NULL == tail) {
//        tail = new_key_part;
//        rest1 = tail;
//      } else {
//        tail->and_next_ = new_key_part;
//        tail = new_key_part;
//      }
//    }
//  }
//  return ret;
//}
W
wangzelin.wzl 已提交
4139
//int ObQueryRange::link_item(ObKeyPart *new_key_part, ObKeyPart *cur)
O
oceanbase-admin 已提交
4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166
//{
//  int ret = OB_SUCCESS;
//  ObKeyPart *item = cur ? cur->item_next_ : NULL;
//  while (OB_SUCC(ret) && NULL != item) {
//    ObKeyPart *new_item = NULL;
//    if (OB_ISNULL(new_item = deep_copy_key_part(item))) {
//      ret = OB_ERR_UNEXPECTED;
//      LOG_WARN("Cope item key part failed", K(ret));
//    } else {
//      new_item->item_next_ = new_key_part->item_next_;
//      new_key_part->item_next_ = new_item;
//      item = item->item_next_;
//    }
//  }
//  return ret;
//}
//
// For row action, we need to know where the new start_ and the new end_
// come from, start_border_type/end_border_type will return the new
//  edges source, then we can treat row as integrity
//
//  E.g.
//       row(k1, k2) > (3, 2) and row(k1, k2) > (1, 4)
//       when find the intersection of k1, we need to know the result3 is comes
//       from the first const row(3,2), then 2 is the new start of k2.
//       ==> row(k1, k2) > (3, 2),  not row(k1, k2) > (3, 4)

W
wangzelin.wzl 已提交
4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179
//对于当前范围为等值的时候,取下一个来进行边界判断,例如(a, b)>(1, 2) and (a, b) > (1, 3),
//通过b来判断。
//若出现不对齐的情况,例如(a, c) > (1, 3) and (a, b, c) > (1, 2, 3)
//选取有值那一方为边界,这里选右边
//用两个bool变量来区分起始边界是否需要通过下一个列值来判断。
//对于属于等值条件,但是实际值不相等设为恒false.比如(a,b)=(1, 1) and (a, b)=(1, 2)
//对于非第一列范围无交集的情况,设为恒false.
//比如(a, b) > (1, 2) and (a, b) <  (2, 3) and (a, b) > (1, 4) and (a, b) < (2, 5)

int ObQueryRange::intersect_border_from(const ObKeyPart *l_key_part,
                                        const ObKeyPart *r_key_part,
                                        ObRowBorderType &start_border_type,
                                        ObRowBorderType &end_border_type,
4180 4181
                                        bool &is_always_false,
                                        bool &has_special_key)
O
oceanbase-admin 已提交
4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193
{
  int ret = OB_SUCCESS;
  bool start_identified = true;
  bool end_identified = true;
  bool s_need_continue = false;
  bool e_need_continue = false;
  start_border_type = OB_FROM_NONE;
  end_border_type = OB_FROM_NONE;
  bool left_is_equal = false;
  if (OB_ISNULL(l_key_part) || OB_ISNULL(r_key_part)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid argument.", K(l_key_part), K(r_key_part));
4194 4195
  } else if (has_special_key) {
    // do nothing
O
oceanbase-admin 已提交
4196
  } else if (OB_UNLIKELY(!l_key_part->is_normal_key()) || OB_UNLIKELY(!r_key_part->is_normal_key())) {
4197 4198
    has_special_key = true;
    LOG_INFO("keypart isn't normal key", K(*l_key_part), K(*r_key_part));
O
oceanbase-admin 已提交
4199 4200 4201 4202 4203 4204
  } else if (l_key_part->pos_.offset_ < r_key_part->pos_.offset_) {
    start_border_type = OB_FROM_LEFT;
    end_border_type = OB_FROM_LEFT;
  } else if (l_key_part->pos_.offset_ > r_key_part->pos_.offset_) {
    start_border_type = OB_FROM_RIGHT;
    end_border_type = OB_FROM_RIGHT;
W
wangzelin.wzl 已提交
4205 4206
  } else if (true == (left_is_equal = l_key_part->is_equal_condition())
             || r_key_part->is_equal_condition()) {
O
oceanbase-admin 已提交
4207 4208 4209 4210 4211
    if (l_key_part->is_question_mark() || r_key_part->is_question_mark()) {
      s_need_continue = true;
      e_need_continue = true;
    } else if (l_key_part->has_intersect(r_key_part)) {
      // incase here is last
4212 4213 4214
      if (l_key_part->is_equal_condition() && r_key_part->is_equal_condition()) {
        if (NULL == l_key_part->and_next_ || NULL == r_key_part->and_next_) {
        start_border_type = (NULL == l_key_part->and_next_) ? OB_FROM_RIGHT : OB_FROM_LEFT;
O
oceanbase-admin 已提交
4215
        end_border_type = start_border_type;
4216 4217 4218 4219
        } else {
          s_need_continue = true;
          e_need_continue = true;
        }
O
oceanbase-admin 已提交
4220
      } else {
4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235
        const ObKeyPart *equal_key = left_is_equal ? l_key_part : r_key_part;
        const ObKeyPart *other_key = left_is_equal ? r_key_part : l_key_part;
        if ((0 == equal_key->normal_keypart_->start_.compare(other_key->normal_keypart_->start_) && other_key->normal_keypart_->include_start_) ||
            (0 == equal_key->normal_keypart_->start_.compare(other_key->normal_keypart_->end_) && other_key->normal_keypart_->include_end_)) {
          if (NULL == equal_key->and_next_) {
            start_border_type = left_is_equal ? OB_FROM_LEFT : OB_FROM_RIGHT;
            end_border_type = start_border_type;
          } else {
            s_need_continue = true;
            e_need_continue = true;
          }
        } else {
          start_border_type = left_is_equal ? OB_FROM_LEFT : OB_FROM_RIGHT;
          end_border_type = start_border_type;
        }
O
oceanbase-admin 已提交
4236 4237 4238 4239 4240
      }
    } else {
      is_always_false = true;
    }
  } else {
W
wangzelin.wzl 已提交
4241 4242 4243 4244
    ObObj *s1 = &l_key_part->normal_keypart_->start_;
    ObObj *e1 = &l_key_part->normal_keypart_->end_;
    ObObj *s2 = &r_key_part->normal_keypart_->start_;
    ObObj *e2 = &r_key_part->normal_keypart_->end_;
O
oceanbase-admin 已提交
4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257
    if (OB_ISNULL(s1) || OB_ISNULL(e1) || OB_ISNULL(s2) || OB_ISNULL(e2)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("s1,e1,s2,e2 can not be null", K(ret), KP(s1), KP(e1), KP(s2), KP(e2));
    } else if (l_key_part->is_question_mark() || r_key_part->is_question_mark()) {
      if (!is_min_range_value(*s1) && !is_min_range_value(*s2)) {
        // both have none-min start value
        start_border_type = OB_FROM_NONE;
      } else if (is_min_range_value(*s1) && !is_min_range_value(*s2)) {
        // only r_key_part has start value
        start_border_type = OB_FROM_RIGHT;
      } else if (!is_min_range_value(*s1) && is_min_range_value(*s2)) {
        // only l_key_part has start value
        start_border_type = OB_FROM_LEFT;
W
wangzelin.wzl 已提交
4258
      } else { // both have min start value
O
oceanbase-admin 已提交
4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271
        start_identified = false;
      }
      if (!is_max_range_value(*e1) && !is_max_range_value(*e2)) {
        end_border_type = OB_FROM_NONE;
      } else if (is_max_range_value(*e1) && !is_max_range_value(*e2)) {
        end_border_type = OB_FROM_RIGHT;
      } else if (!is_max_range_value(*e1) && is_max_range_value(*e2)) {
        end_border_type = OB_FROM_LEFT;
      } else {
        end_identified = false;
      }
    } else {
      // has changeless value
O
obdev 已提交
4272
      if (OB_UNLIKELY(l_key_part->id_ != r_key_part->id_ || l_key_part->pos_ != r_key_part->pos_)) {
O
oceanbase-admin 已提交
4273
        ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
4274
        LOG_WARN("l_key_part is not equal to r_key_part", K(ret));
O
oceanbase-admin 已提交
4275 4276 4277 4278 4279 4280 4281 4282 4283
      } else if (l_key_part->has_intersect(r_key_part)) {
        if (is_min_range_value(*s1) && is_min_range_value(*s2)) {
          start_identified = false;
        } else {
          int cmp = s1->compare(*s2);
          if (cmp > 0) {
            start_border_type = OB_FROM_LEFT;
          } else if (cmp < 0) {
            start_border_type = OB_FROM_RIGHT;
W
wangzelin.wzl 已提交
4284
          } else { // equal
O
oceanbase-admin 已提交
4285
            if (NULL == l_key_part->and_next_) {
W
wangzelin.wzl 已提交
4286
              start_border_type = OB_FROM_LEFT; // lucky left
O
oceanbase-admin 已提交
4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298
            }
            s_need_continue = true;
          }
        }
        if (is_max_range_value(*e1) && is_max_range_value(*e2)) {
          end_identified = false;
        } else {
          int cmp = e1->compare(*e2);
          if (cmp > 0) {
            end_border_type = OB_FROM_RIGHT;
          } else if (cmp < 0) {
            end_border_type = OB_FROM_LEFT;
K
Klawz 已提交
4299
          } else { // equal
O
oceanbase-admin 已提交
4300
            if (NULL == l_key_part->and_next_) {
W
wangzelin.wzl 已提交
4301
              end_border_type = OB_FROM_LEFT; // lucky left
O
oceanbase-admin 已提交
4302 4303 4304 4305 4306 4307 4308 4309 4310 4311
            }
            e_need_continue = true;
          }
        }
      } else {
        is_always_false = true;
      }
    }
    if (!start_identified || !end_identified) {
      if (!start_identified && !end_identified) {
W
wangzelin.wzl 已提交
4312 4313
        start_border_type = OB_FROM_LEFT; // lucky left
        end_border_type = OB_FROM_LEFT; // lucky left
O
oceanbase-admin 已提交
4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324
      } else if (start_identified) {
        end_border_type = start_border_type;
        e_need_continue = s_need_continue;
      } else if (end_identified) {
        start_border_type = end_border_type;
        s_need_continue = e_need_continue;
      } else {
        // do nothing
      }
    }
  }
W
wangzelin.wzl 已提交
4325 4326
  if (OB_SUCC(ret)
      && !is_always_false
4327
      && !has_special_key
W
wangzelin.wzl 已提交
4328 4329 4330
      && NULL != l_key_part->and_next_
      && NULL != r_key_part->and_next_
      && (s_need_continue || e_need_continue)) {
O
oceanbase-admin 已提交
4331 4332
    ObRowBorderType tmp_start_border = OB_FROM_NONE;
    ObRowBorderType tmp_end_border = OB_FROM_NONE;
W
wangzelin.wzl 已提交
4333
    if (OB_FAIL(SMART_CALL(intersect_border_from(l_key_part->and_next_, r_key_part->and_next_,
4334
        tmp_start_border, tmp_end_border, is_always_false, has_special_key)))) {
O
oceanbase-admin 已提交
4335 4336 4337 4338 4339 4340
      LOG_WARN("invalid argument.", K(ret), K(l_key_part), K(r_key_part));
    } else if (s_need_continue) {
      start_border_type = tmp_start_border;
      if (e_need_continue) {
        end_border_type = tmp_end_border;
      }
W
wangzelin.wzl 已提交
4341
    } else {}
O
oceanbase-admin 已提交
4342 4343 4344 4345
  }
  return ret;
}

W
wangzelin.wzl 已提交
4346
bool ObQueryRange::is_max_range_value(const ObObj &obj) const
O
oceanbase-admin 已提交
4347 4348 4349 4350
{
  return lib::is_oracle_mode() ? (obj.is_max_value() || obj.is_null()) : obj.is_max_value();
}

W
wangzelin.wzl 已提交
4351
bool ObQueryRange::is_min_range_value(const ObObj &obj) const
O
oceanbase-admin 已提交
4352 4353 4354 4355 4356
{
  return lib::is_oracle_mode() ? (obj.is_min_value()) : (obj.is_min_value() || obj.is_null());
}


W
wangzelin.wzl 已提交
4357 4358 4359 4360 4361 4362 4363 4364 4365 4366
//After wen known where the edges of the row come from,
//set the new edges to the result.
//if or_next_ list is not NULL, cut it.

int ObQueryRange::set_partial_row_border(
    ObKeyPart *l_gt,
    ObKeyPart *r_gt,
    ObRowBorderType start_border_type,
    ObRowBorderType end_border_type,
    ObKeyPart  *&result)
O
oceanbase-admin 已提交
4367 4368
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4369 4370 4371
  ObKeyPart *l_cur = (NULL != l_gt && NULL == l_gt->or_next_) ? l_gt : NULL;
  ObKeyPart *r_cur = (NULL != r_gt && NULL == r_gt->or_next_) ? r_gt : NULL;
  ObKeyPart *prev_key_part = NULL;
O
oceanbase-admin 已提交
4372
  result = NULL;
W
wangzelin.wzl 已提交
4373 4374
  if (ObQueryRange::OB_FROM_NONE != start_border_type
      || ObQueryRange::OB_FROM_NONE != end_border_type) {
O
oceanbase-admin 已提交
4375 4376
    bool b_flag = false;
    while (OB_SUCC(ret) && !b_flag && (NULL != l_cur || NULL != r_cur)) {
W
wangzelin.wzl 已提交
4377 4378 4379 4380 4381
      ObKeyPart *new_key_part = NULL;
      if (start_border_type != end_border_type
          && NULL != l_cur
          && NULL != r_cur
          && l_cur->is_question_mark() != r_cur->is_question_mark()) {
O
oceanbase-admin 已提交
4382 4383
        // we can express such case: start is unknown value, but end is known value
        b_flag = true;
W
wangzelin.wzl 已提交
4384 4385 4386 4387
      } else if (((ObQueryRange::OB_FROM_LEFT == start_border_type || ObQueryRange::OB_FROM_LEFT == end_border_type) && OB_ISNULL(l_cur))
                 || ((ObQueryRange::OB_FROM_RIGHT == start_border_type || ObQueryRange::OB_FROM_RIGHT == end_border_type)
                     && OB_ISNULL(r_cur))) {
        //target row的取值达到被取值row的末尾
O
oceanbase-admin 已提交
4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410
        b_flag = true;
      } else if (OB_FAIL(alloc_full_key_part(new_key_part))) {
        LOG_WARN("Get key part failed", K(ret));
        b_flag = true;
      } else if (OB_ISNULL(new_key_part) || OB_UNLIKELY(!new_key_part->is_normal_key())) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("new_key_part is null.");
      } else {
        new_key_part->normal_keypart_->always_true_ = false;
        if (ObQueryRange::OB_FROM_LEFT == start_border_type && l_cur) {
          new_key_part->set_normal_start(l_cur);
        } else if (ObQueryRange::OB_FROM_RIGHT == start_border_type && NULL != r_cur) {
          new_key_part->set_normal_start(r_cur);
        } else {
          // do nothing
        }
        if (ObQueryRange::OB_FROM_LEFT == end_border_type && l_cur) {
          new_key_part->set_normal_end(l_cur);
        } else if (ObQueryRange::OB_FROM_RIGHT == end_border_type && NULL != r_cur) {
          new_key_part->set_normal_end(r_cur);
        } else {
          // do nothing
        }
4411
        ObKeyPart *item = NULL != l_cur && l_cur->pos_.offset_ == new_key_part->pos_.offset_ ? l_cur->item_next_ : NULL;
O
oceanbase-admin 已提交
4412
        while (OB_SUCC(ret) && NULL != item) {
W
wangzelin.wzl 已提交
4413
          ObKeyPart *new_item = NULL;
O
oceanbase-admin 已提交
4414 4415 4416 4417 4418 4419 4420 4421 4422
          if (OB_ISNULL(new_item = deep_copy_key_part(item))) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("Cope item key part failed", K(ret));
          } else {
            new_item->item_next_ = new_key_part->item_next_;
            new_key_part->item_next_ = new_item;
            item = item->item_next_;
          }
        }
4423
        item = NULL != r_cur && r_cur->pos_.offset_ == new_key_part->pos_.offset_ ? r_cur->item_next_ : NULL;
O
oceanbase-admin 已提交
4424
        while (OB_SUCC(ret) && NULL != item) {
W
wangzelin.wzl 已提交
4425
          ObKeyPart *new_item = NULL;
O
oceanbase-admin 已提交
4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464
          if (OB_ISNULL(new_item = deep_copy_key_part(item))) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("Cope item key part failed", K(ret));
          } else {
            new_item->item_next_ = new_key_part->item_next_;
            new_key_part->item_next_ = new_item;
            item = item->item_next_;
          }
        }
      }
      if (OB_SUCC(ret) && !b_flag) {
        if (NULL != prev_key_part) {
          prev_key_part->and_next_ = new_key_part;
        } else {
          result = new_key_part;
        }
        prev_key_part = new_key_part;
        // if and_next_ does not have or-item, then do next
        if (NULL != l_cur && NULL != l_cur->and_next_ && NULL == l_cur->and_next_->or_next_) {
          l_cur = l_cur->and_next_;
        } else {
          l_cur = NULL;
        }
        if (NULL != r_cur && NULL != r_cur->and_next_ && NULL == r_cur->and_next_->or_next_) {
          r_cur = r_cur->and_next_;
        } else {
          r_cur = NULL;
        }
      }
    }
  }
  return ret;
}

//  do and of general term (gt) when row exists.
//  if you need, find the meaning of gt from comments of do_gt_and().
//
//  ROW(k1(s1, e1), k2(s2, e2)) and ROW(k1(s3, e4), k2(s3, e4))
//         k1(s1, e1): means the first key part in row between s1 and e1.
K
Klawz 已提交
4465
//  because the and operands is row, we can not AND each key part separately.
O
oceanbase-admin 已提交
4466 4467 4468 4469 4470 4471 4472
//  so the result is:
//  ROW(k1(ns1, ne1), k2(ns2, ne2)), if two row values has intersection.
//         if s1>s3, ns1 = s1 and ns2 = s2 else ns1 = s3 and ns2 = s4;
//         if e1<e2, ne1 = e1 and ne2 = e2 else ne1 = e3 and ne2 = e4;
//         if start/end value can not compare, k1 is returned only
//             e.g. row(k1, k2) > (?1, ?2) and row(k1, k2) > (?3, ?4)

W
wangzelin.wzl 已提交
4473
int ObQueryRange::do_row_gt_and(ObKeyPart *l_gt, ObKeyPart *r_gt, ObKeyPart  *&res_gt)
O
oceanbase-admin 已提交
4474 4475
{
  int ret = OB_SUCCESS;
O
obdev 已提交
4476
  if (OB_UNLIKELY(NULL == l_gt && NULL == r_gt)) {
O
oceanbase-admin 已提交
4477 4478 4479 4480 4481 4482
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("Wrong argument", K(ret));
  } else if (NULL == l_gt) {
    res_gt = r_gt;
  } else if (NULL == r_gt) {
    res_gt = l_gt;
4483 4484 4485 4486
  } else if (l_gt->is_in_key() && r_gt->is_in_key()) {
    res_gt = l_gt->in_keypart_->get_min_offset() <= r_gt->in_keypart_->get_min_offset() ? l_gt : r_gt;
    // if in key do and with normal key here,
    // the result is in key
L
Larry955 已提交
4487 4488 4489 4490
  } else if (l_gt->is_in_key()) {
    res_gt = l_gt->in_keypart_->get_min_offset() <= r_gt->pos_.offset_ ? l_gt : r_gt;
  } else if (r_gt->is_in_key()) {
    res_gt = r_gt->in_keypart_->get_min_offset() <= l_gt->pos_.offset_ ? r_gt : l_gt;
O
oceanbase-admin 已提交
4491
  } else if (l_gt->pos_.offset_ < r_gt->pos_.offset_) {
W
wangzelin.wzl 已提交
4492
    res_gt = l_gt; //两个向量做and,右边向量前缀缺失,直接用左边向量的结果
O
oceanbase-admin 已提交
4493
  } else if (r_gt->pos_.offset_ < l_gt->pos_.offset_) {
W
wangzelin.wzl 已提交
4494
    res_gt = r_gt; //两个向量做and,左边向量前缀缺失,直接用右边向量的结果
O
oceanbase-admin 已提交
4495
  } else {
W
wangzelin.wzl 已提交
4496 4497
    ObKeyPart *l_gt_next = l_gt->and_next_;
    ObKeyPart *r_gt_next = r_gt->and_next_;
O
oceanbase-admin 已提交
4498 4499
    res_gt = NULL;
    bool always_true = false;
W
wangzelin.wzl 已提交
4500 4501 4502 4503
    ObKeyPart *find_false = NULL;
    ObKeyPart *tail = NULL;
    ObKeyPart *l_cur = NULL;
    ObKeyPart *r_cur = NULL;
O
oceanbase-admin 已提交
4504 4505
    for (l_cur = l_gt; OB_SUCC(ret) && !always_true && NULL != l_cur; l_cur = l_cur->or_next_) {
      for (r_cur = r_gt; OB_SUCC(ret) && !always_true && NULL != r_cur; r_cur = r_cur->or_next_) {
W
wangzelin.wzl 已提交
4506 4507
        ObKeyPart *result = NULL;
        ObKeyPart *rest = NULL;
4508 4509 4510 4511
        ObKeyPart *new_l_cur = NULL;
        ObKeyPart *new_r_cur = NULL;
        if (OB_FAIL(deep_copy_key_part_and_items(l_cur, new_l_cur))) {
          LOG_WARN("Light copy key part and items failed", K(ret));
4512 4513
        } else if (is_reach_mem_limit_) {
          res_gt = new_l_cur;
4514
          always_true = true;
4515 4516
        } else if(OB_FAIL(deep_copy_key_part_and_items(r_cur, new_r_cur))) {
          LOG_WARN("Right copy key part and items failed", K(ret));
4517
        } else if (OB_ISNULL(new_l_cur) || OB_ISNULL(new_r_cur)) {
O
oceanbase-admin 已提交
4518
          ret = OB_ERR_UNEXPECTED;
4519
          LOG_WARN("get unexpected null", K(ret), K(new_l_cur), K(new_r_cur));
4520 4521
        } else if (is_reach_mem_limit_) {
          res_gt = new_r_cur;
4522
          always_true = true;
4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541
        } else if (new_l_cur->is_like_key()) {
          result = new_r_cur;
        } else if (new_r_cur->is_like_key()) {
          result = new_l_cur;
        } else if (new_l_cur->is_in_key()) {
          result = new_l_cur;
        } else if (new_r_cur->is_in_key()) {
          result = new_r_cur;
        } else if (OB_FAIL(do_key_part_node_and(new_l_cur, new_r_cur, result))) {  // do AND of each key part node only
          LOG_WARN("Do key part node intersection failed", K(ret));
        } else if(OB_ISNULL(result)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("result is null.", K(ret));
        } else if (result->is_always_true()) {
          always_true = true;
          res_gt = result;
        } else if (result->is_always_false()) {
          // ignore
          find_false = result;
O
oceanbase-admin 已提交
4542
        } else {
4543 4544 4545 4546
          // set other value of row
          ObRowBorderType s_border = OB_FROM_NONE;
          ObRowBorderType e_border = OB_FROM_NONE;
          bool is_always_false = false;
4547
          bool has_special_key = false;
4548
          if (OB_FAIL(intersect_border_from(l_cur, r_cur,
4549
              s_border, e_border, is_always_false, has_special_key))) {
4550 4551 4552
            LOG_WARN("Find row border failed", K(ret));
          } else if (is_always_false) {
            result->normal_keypart_->always_false_ = true;
4553
            result->normal_keypart_->always_true_ = false;
4554 4555
            result->normal_keypart_->start_.set_max_value();
            result->normal_keypart_->end_.set_min_value();
O
oceanbase-admin 已提交
4556
            find_false = result;
4557 4558
          } else if (has_special_key) {
            // do nothing
4559 4560 4561 4562 4563 4564 4565
          } else if (OB_FAIL(set_partial_row_border(l_gt_next, r_gt_next,
              s_border, e_border, rest))) {
            LOG_WARN("Set row border failed", K(ret));
          } else if (OB_ISNULL(rest)) {
            //如果做向量条件融合,导致条件被丢弃掉,说明抽取有放大,需要清除掉精确抽取的filter标记,不能去除对应的filter
            if (OB_FAIL(remove_precise_range_expr(result->pos_.offset_ + 1))) {
              LOG_WARN("remove precise range expr failed", K(ret));
O
oceanbase-admin 已提交
4566 4567 4568 4569
            }
          }
        }

4570 4571 4572
        if (OB_SUCC(ret) && !is_reach_mem_limit_ &&
            !result->is_always_false() &&
            !result->is_always_true()) {
O
oceanbase-admin 已提交
4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595
          result->link_gt(rest);
          // link to the or_next_ list
          if (NULL != tail) {
            tail->or_next_ = result;
          } else {
            res_gt = result;
          }
          tail = result;
        }
      }
    }
    if (OB_SUCC(ret) && NULL == res_gt) {
      if (NULL == find_false) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("find_false is null.", K(ret));
      } else {
        res_gt = find_false;
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4596

O
oceanbase-admin 已提交
4597
//  AND single key part (itself) and items in item_next_ list
K
Klawz 已提交
4598
//  Each item in item_next_ list must be unkown item until physical plan open
O
oceanbase-admin 已提交
4599 4600 4601 4602 4603 4604 4605
//
//  E.g.
//       (A1 and ?1 and ?2 and ... and ?m) and (A2 and ?I and ?II and ... and ?n)
//       ==>
//       (A12 and ?1 and ?2 and ... and ?m and ?I and ?II and ... and ?n)
//       A12 is the result of (A1 intersect A2)

W
wangzelin.wzl 已提交
4606 4607 4608 4609
int ObQueryRange::do_key_part_node_and(
    ObKeyPart *l_key_part,
    ObKeyPart *r_key_part,
    ObKeyPart *&res_key_part)
O
oceanbase-admin 已提交
4610 4611 4612 4613 4614 4615 4616
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(l_key_part) || OB_ISNULL(r_key_part)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("Wrong argument", K(ret));
  } else {
    if (l_key_part->is_always_true() || r_key_part->is_always_true()) {
O
obdev 已提交
4617
      res_key_part = l_key_part->is_always_true() ? r_key_part : l_key_part;
O
oceanbase-admin 已提交
4618
    } else if (l_key_part->is_always_false() || r_key_part->is_always_false()) {
O
obdev 已提交
4619 4620
      res_key_part = l_key_part->is_always_false() ? l_key_part : r_key_part;
      res_key_part->and_next_ = NULL;
O
oceanbase-admin 已提交
4621 4622 4623 4624 4625 4626
    } else {
      res_key_part = NULL;
      l_key_part->and_next_ = NULL;
      l_key_part->or_next_ = NULL;
      r_key_part->and_next_ = NULL;
      r_key_part->or_next_ = NULL;
W
wangzelin.wzl 已提交
4627 4628
      ObKeyPart *l_items = l_key_part;
      ObKeyPart *r_items = r_key_part;
4629 4630 4631
      if (!l_key_part->is_question_mark() && !r_key_part->is_question_mark()) {
        l_items = l_key_part->item_next_;
        r_items = r_key_part->item_next_;
4632 4633
        l_key_part->item_next_ = NULL;
        r_key_part->item_next_ = NULL;
4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652
        if (l_key_part->is_in_key() && r_key_part->is_in_key()) {
          ObSEArray<int64_t, 4> common_offsets;
          if (OB_FAIL(ObOptimizerUtil::intersect(l_key_part->in_keypart_->offsets_,
                                                r_key_part->in_keypart_->offsets_,
                                                common_offsets))) {
            LOG_WARN("failed to do intersect", K(ret));
          } else if (OB_UNLIKELY(common_offsets.empty())) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("get unexpected null", K(ret));
          } else if (OB_FAIL(l_key_part->intersect_two_in_keys(r_key_part, common_offsets))) {
            LOG_WARN("failed to merge two in keys", K(ret));
          } else {
            res_key_part = l_key_part;
          }
        } else if (l_key_part->is_in_key()) {
          if (r_key_part->is_phy_rowid_key_part_) {
            res_key_part = r_key_part;
          } else if (OB_FAIL(l_key_part->intersect_in(r_key_part))) {
            LOG_WARN("failed to intersect in key part", K(ret));
O
obdev 已提交
4653 4654 4655
          } else {
            res_key_part = l_key_part;
          }
4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666
        } else if (r_key_part->is_in_key()) {
          if (l_key_part->is_phy_rowid_key_part_) {
            res_key_part = l_key_part;
          } else if (OB_FAIL(r_key_part->intersect_in(l_key_part))) {
            LOG_WARN("failed to intersect in key part", K(ret));
          } else {
            res_key_part = r_key_part;
          }
        } else if (OB_FAIL(l_key_part->intersect(r_key_part, contain_row_))) {
          LOG_WARN("Do key part node intersection failed", K(ret));
        } else {
O
oceanbase-admin 已提交
4667 4668
          res_key_part = l_key_part;
        }
4669 4670 4671 4672 4673 4674 4675
      } else if (!l_key_part->is_question_mark()) {
        res_key_part = l_key_part;
        l_items = l_key_part->item_next_;
      } else if (!r_key_part->is_question_mark()) {
        res_key_part = r_key_part;
        r_items = r_key_part->item_next_;
      }
O
oceanbase-admin 已提交
4676

4677 4678 4679 4680 4681 4682 4683
      // link all unkown-value items
      if (OB_SUCC(ret)) {
        if (NULL != l_items) {
          if (NULL != res_key_part) {
            res_key_part->item_next_ = l_items;
          } else {
            res_key_part = l_items;
O
oceanbase-admin 已提交
4684
          }
4685 4686 4687 4688 4689 4690 4691 4692 4693 4694
        }
        if (NULL != r_items) {
          if (OB_ISNULL(res_key_part)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("res_key_part is null.", K(ret));
          } else {
            ObKeyPart *tail = res_key_part;
            // find the item_next_ list tail
            while (NULL != tail->item_next_) {
              tail = tail->item_next_;
O
oceanbase-admin 已提交
4695
            }
4696
            tail->item_next_ = r_items;
O
oceanbase-admin 已提交
4697 4698 4699 4700 4701 4702 4703 4704 4705
          }
        }
      }
    }
  }
  return ret;
}
//  Just get the key part node itself and items in its item_next_ list

W
wangzelin.wzl 已提交
4706 4707 4708
int ObQueryRange::deep_copy_key_part_and_items(
    const ObKeyPart *src_key_part,
    ObKeyPart  *&dest_key_part)
O
oceanbase-admin 已提交
4709 4710
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4711 4712
  const ObKeyPart *tmp_key_part = src_key_part;
  ObKeyPart *prev_key_part = NULL;
4713
  while (OB_SUCC(ret) && !is_reach_mem_limit_ && NULL != tmp_key_part) {
W
wangzelin.wzl 已提交
4714
    ObKeyPart *new_key_part = NULL;
4715 4716 4717 4718 4719
    if (query_range_ctx_ != NULL &&
       (allocator_.used() - mem_used_) >= query_range_ctx_->range_optimizer_max_mem_size_) {
      is_reach_mem_limit_ = true;
      LOG_WARN("use too much memory return always true keypart", K(mem_used_), K(allocator_.used()));
    } else if (OB_ISNULL(new_key_part = create_new_key_part())) {
O
oceanbase-admin 已提交
4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_ERROR("alloc ObKeyPart failed", K(ret));
    } else if (OB_FAIL(new_key_part->deep_node_copy(*tmp_key_part))) {
      LOG_WARN("Copy key part node failed", K(ret));
    } else {
      if (NULL != prev_key_part) {
        prev_key_part->item_next_ = new_key_part;
      } else {
        dest_key_part = new_key_part;
      }
      prev_key_part = new_key_part;
      tmp_key_part = tmp_key_part->item_next_;
    }
  }
4734 4735 4736 4737 4738 4739 4740 4741
  if (OB_SUCC(ret) && is_reach_mem_limit_) {
    if (OB_FAIL(alloc_full_key_part(dest_key_part))) {
      LOG_WARN("alloc_full_key_part failed", K(ret));
    } else {
      dest_key_part->id_ = src_key_part->id_;
      dest_key_part->pos_ = src_key_part->pos_;
    }
  }
O
oceanbase-admin 已提交
4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756
  return ret;
}

//  Just and the general item
//       each key part in the general item or_next_ list has same and_next_.
//       each key part in the general item or_next_ list may have item_next_,
//       any key part linked by item_next_ is run-time value,
//       which can not know at this time
//
//  l_gt/r_gt is a group
//  l_gt/r_gt must satisfy following features:
//       1. the key parts must have same key offset
//       2. all key part in same or_next_ list have same and_next_.
//
//  E.g.
O
obdev 已提交
4757 4758
//       (A1 or A2 or ... or Am) and (A1 or A2 or ... or An)
//       do general item and, then we get:
O
oceanbase-admin 已提交
4759
//       ==>
O
obdev 已提交
4760 4761
//       (A11 or A12 or ... or A1n or A21 or A22 or ... or A2n or ...... or Am1 or Am2 or ... or Amn)
//       Aij = (Ai from [A1, A2, ..., Am] intersect Aj from [A1, A2, An])
W
wangzelin.wzl 已提交
4762
int ObQueryRange::do_gt_and(ObKeyPart *l_gt, ObKeyPart *r_gt, ObKeyPart *&res_gt)
O
oceanbase-admin 已提交
4763 4764
{
  int ret = OB_SUCCESS;
O
obdev 已提交
4765 4766
  res_gt = NULL;
  if (OB_UNLIKELY(NULL == l_gt && NULL == r_gt)) {
O
oceanbase-admin 已提交
4767 4768 4769 4770 4771 4772 4773
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("Wrong argument", K(ret));
  } else if (NULL == l_gt) {
    res_gt = r_gt;
  } else if (NULL == r_gt) {
    res_gt = l_gt;
  } else {
O
obdev 已提交
4774 4775 4776 4777
    ObKeyPart *find_false = NULL;
    ObKeyPart *tail = NULL;
    ObKeyPart *l_cur = NULL;
    ObKeyPart *r_cur = NULL;
4778
    for (l_cur = l_gt; OB_SUCC(ret) && !is_reach_mem_limit_ && NULL != l_cur; l_cur = l_cur->or_next_) {
O
obdev 已提交
4779
      bool find_true = false;
4780
      for (r_cur = r_gt; OB_SUCC(ret) && !find_true && !is_reach_mem_limit_ && NULL != r_cur; r_cur = r_cur->or_next_) {
O
obdev 已提交
4781 4782 4783 4784 4785
        ObKeyPart *result = NULL;
        ObKeyPart *new_l_cur = NULL;
        ObKeyPart *new_r_cur = NULL;
        if (OB_FAIL(deep_copy_key_part_and_items(l_cur, new_l_cur))) {
          LOG_WARN("Light copy key part and items failed", K(ret));
4786 4787
        } else if (is_reach_mem_limit_) {
          res_gt = new_l_cur;
O
obdev 已提交
4788 4789
        } else if (OB_FAIL(deep_copy_key_part_and_items(r_cur, new_r_cur))) {
          LOG_WARN("right copy key part and items failed", K(ret));
4790 4791
        } else if (is_reach_mem_limit_) {
          res_gt = new_r_cur;
O
obdev 已提交
4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804
        } else if (OB_FAIL(do_key_part_node_and(new_l_cur, new_r_cur, result))) { // do AND of each key part node only
          LOG_WARN("Do key part node intersection failed", K(ret));
        } else if (OB_ISNULL(result)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("result is null.", K(ret));
        } else if (result->is_always_true()) {
          res_gt = result;
          find_true = true;
        } else if (result->is_always_false()) {
          // ignore
          find_false = result;
        } else {
          if (NULL == res_gt) {
O
oceanbase-admin 已提交
4805 4806
            res_gt = result;
          }
O
obdev 已提交
4807 4808 4809 4810 4811
          // link to the or_next_ list
          if (NULL != tail) {
            tail->or_next_ = result;
          }
          tail = result;
O
oceanbase-admin 已提交
4812 4813
        }
      }
O
obdev 已提交
4814 4815 4816 4817 4818 4819 4820 4821 4822
    }
    if (OB_SUCC(ret)) {
      // all false
      if (NULL == res_gt) {
        if (OB_ISNULL(find_false)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("find_false is NULL.", K(ret));
        } else {
          res_gt = find_false;
O
oceanbase-admin 已提交
4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835
        }
      }
    }
  }
  return ret;
}

//  do and operation of each graph in l_array and r_array by two path method,
//  then treat the results as or relation
//
//  we do the and operation recursively:
//  1. if left id < right id, result = left-current-key and RECUSIVE_AND(left-rest-keys, right-keys) ;
//  2. if left id > right id, result = right-current-key and RECUSIVE_AND(left-keys, right-rest-keys) ;
W
wangzelin.wzl 已提交
4836
//  3. if left id == right id, result = INTERSECT(left-current-key, right-current-key) and RECUSIVE_AND(left-rest-keys, right-rest-keys) ;
O
oceanbase-admin 已提交
4837

W
wangzelin.wzl 已提交
4838 4839 4840 4841
int ObQueryRange::and_single_gt_head_graphs(
    ObKeyPartList &l_array,
    ObKeyPartList &r_array,
    ObKeyPartList &res_array)
O
oceanbase-admin 已提交
4842 4843 4844 4845 4846 4847 4848 4849
{
  int ret = OB_SUCCESS;
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to do stack overflow check", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack overflow", K(ret));
O
obdev 已提交
4850
  } else if (OB_UNLIKELY(l_array.get_size() <= 0 || r_array.get_size() <= 0)) {
O
oceanbase-admin 已提交
4851
    ret = OB_INVALID_ARGUMENT;
W
wangzelin.wzl 已提交
4852 4853
    LOG_WARN("And operand can not be empty",
             K(ret), K(l_array.get_size()), K(r_array.get_size()));
4854 4855
  } else if (is_reach_mem_limit_) {
    // do nothing
O
oceanbase-admin 已提交
4856 4857
  } else {
    res_array.clear();
W
wangzelin.wzl 已提交
4858
    ObKeyPart *find_false = NULL;
O
oceanbase-admin 已提交
4859
    bool always_true = false;
W
wangzelin.wzl 已提交
4860
    for (ObKeyPart *l = l_array.get_first();
4861
         OB_SUCC(ret) && !always_true && l != l_array.get_header() && NULL != l && !is_reach_mem_limit_;
O
oceanbase-admin 已提交
4862
         l = l->get_next()) {
W
wangzelin.wzl 已提交
4863 4864
      ObKeyPart *tmp_result = NULL;
      for (ObKeyPart *r = r_array.get_first();
4865
           OB_SUCC(ret) && r != r_array.get_header() && NULL != r && !is_reach_mem_limit_;
O
oceanbase-admin 已提交
4866
           r = r->get_next()) {
W
wangzelin.wzl 已提交
4867 4868
        ObKeyPart *l_cur_gt = NULL;
        ObKeyPart *r_cur_gt = NULL;
O
oceanbase-admin 已提交
4869 4870
        if (OB_FAIL(deep_copy_range_graph(l, l_cur_gt))) {
          LOG_WARN("Left deep copy range graph failed", K(ret));
4871 4872
        } else if (is_reach_mem_limit_) {
          // do nothing
O
oceanbase-admin 已提交
4873 4874
        } else if (OB_FAIL(deep_copy_range_graph(r, r_cur_gt))) {
          LOG_WARN("Right deep copy range graph failed", K(ret));
4875 4876
        } else if (is_reach_mem_limit_) {
          // do nothing
O
obdev 已提交
4877
        } else if (OB_ISNULL(l_cur_gt) || OB_ISNULL(r_cur_gt)) {
O
oceanbase-admin 已提交
4878
          ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
4879
          LOG_WARN("key_part is null.", K(ret), K(l_cur_gt), K(r_cur_gt));
O
oceanbase-admin 已提交
4880
        } else {
W
wangzelin.wzl 已提交
4881 4882 4883
          ObKeyPart *l_and_next = l_cur_gt->and_next_;
          ObKeyPart *r_and_next = r_cur_gt->and_next_;
          ObKeyPart *rest_result = NULL;
O
oceanbase-admin 已提交
4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895
          // false and everything is false
          if (l_cur_gt->is_always_false() || r_cur_gt->is_always_false()) {
            tmp_result = l_cur_gt->is_always_false() ? l_cur_gt : r_cur_gt;
            tmp_result->and_next_ = NULL;
          } else if (r_cur_gt->is_always_true()) {
            tmp_result = l_cur_gt;
          } else if (l_cur_gt->is_always_true()) {
            tmp_result = r_cur_gt;
          } else if (contain_row_) {
            if (OB_FAIL(do_row_gt_and(l_cur_gt, r_cur_gt, tmp_result))) {
              LOG_WARN("AND row failed", K(ret));
            } else if (query_range_ctx_ != NULL) {
W
wangzelin.wzl 已提交
4896 4897
              //经过向量的合并后,为了正确性考虑,都保守不再去filter
              //清空精确条件的记录
O
oceanbase-admin 已提交
4898 4899
              query_range_ctx_->precise_range_exprs_.reset();
            }
W
wangzelin.wzl 已提交
4900
          } else { // normal case
O
oceanbase-admin 已提交
4901
            // 1. do and of the first general item
O
obdev 已提交
4902 4903 4904 4905 4906 4907 4908 4909
            // no always true or always false key part reached here
            if (l_cur_gt->is_in_key() && r_cur_gt->is_in_key()) {
              ObSEArray<int64_t, 4> common_offsets;
              if (OB_FAIL(ObOptimizerUtil::intersect(l_cur_gt->in_keypart_->offsets_,
                                                     r_cur_gt->in_keypart_->offsets_,
                                                     common_offsets))) {
                LOG_WARN("failed to do intersect", K(ret));
              } else if (!common_offsets.empty()) {
4910
                if (OB_FAIL(do_gt_and(l_cur_gt, r_cur_gt, tmp_result))) {
O
obdev 已提交
4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921
                  LOG_WARN("failed to do in key and next", K(ret));
                }
              } else if (l_cur_gt->in_keypart_->get_min_offset() < r_cur_gt->in_keypart_->get_min_offset()) {
                tmp_result = l_cur_gt;
                r_and_next = r_cur_gt;
              } else {
                tmp_result = r_cur_gt;
                l_and_next = l_cur_gt;
              }
            } else if (l_cur_gt->is_in_key()) {
              if (is_contain(l_cur_gt->in_keypart_->offsets_, r_cur_gt->pos_.offset_)) {
4922
                if (OB_FAIL(do_gt_and(l_cur_gt, r_cur_gt, tmp_result))) {
O
obdev 已提交
4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933
                  LOG_WARN("failed to do in key part and", K(ret));
                }
              } else if (l_cur_gt->in_keypart_->get_min_offset() < r_cur_gt->pos_.offset_) {
                tmp_result = l_cur_gt;
                r_and_next = r_cur_gt;
              } else {
                tmp_result = r_cur_gt;
                l_and_next = l_cur_gt;
              }
            } else if (r_cur_gt->is_in_key()) {
              if (is_contain(r_cur_gt->in_keypart_->offsets_, l_cur_gt->pos_.offset_)) {
4934
                if (OB_FAIL(do_gt_and(l_cur_gt, r_cur_gt, tmp_result))) {
O
obdev 已提交
4935 4936 4937 4938 4939 4940 4941 4942 4943 4944
                  LOG_WARN("failed to do in key part and", K(ret));
                }
              } else if (l_cur_gt->pos_.offset_ < r_cur_gt->in_keypart_->get_min_offset()) {
                tmp_result = l_cur_gt;
                r_and_next = r_cur_gt;
              } else {
                tmp_result = r_cur_gt;
                l_and_next = l_cur_gt;
              }
            } else if (l_cur_gt->pos_.offset_ < r_cur_gt->pos_.offset_) {
O
oceanbase-admin 已提交
4945 4946
              tmp_result = l_cur_gt;
              r_and_next = r_cur_gt;
O
obdev 已提交
4947
            } else if (r_cur_gt->pos_.offset_ < l_cur_gt->pos_.offset_) {
O
oceanbase-admin 已提交
4948 4949
              tmp_result = r_cur_gt;
              l_and_next = l_cur_gt;
O
obdev 已提交
4950
            } else { // l_cur_gt and r_cur_gt belongs to same key
O
oceanbase-admin 已提交
4951
              if (OB_FAIL(do_gt_and(l_cur_gt, r_cur_gt, tmp_result))) {
K
Klawz 已提交
4952
                LOG_WARN("Do AND of general term failed", K(ret));
O
oceanbase-admin 已提交
4953 4954
              }
            }
O
obdev 已提交
4955
            if (OB_FAIL(ret)) {
O
oceanbase-admin 已提交
4956 4957 4958 4959 4960 4961 4962 4963 4964
              // do nothing
            } else if (OB_ISNULL(tmp_result)) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("tmp_result is null.", K(ret));
            } else {
              tmp_result->and_next_ = NULL;

              // 2. recursive do rest part keys
              if (tmp_result->is_always_false() || tmp_result->is_always_true()) {
W
wangzelin.wzl 已提交
4965
                //no need to do rest part
O
oceanbase-admin 已提交
4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980
              } else {
                ObKeyPartList and_storage;
                if (NULL == l_and_next) {
                  rest_result = r_and_next;
                } else if (NULL == r_and_next) {
                  rest_result = l_and_next;
                } else if (!and_storage.add_last(l_and_next) || !and_storage.add_last(r_and_next)) {
                  ret = OB_ERR_UNEXPECTED;
                  LOG_WARN("Add ObKeyPart to list failed", K(ret));
                } else if (OB_FAIL(and_range_graph(and_storage, rest_result))) {
                  LOG_WARN("And range graph failed", K(ret));
                } else {
                  // do nothing
                }
                // 3. AND head and rest
4981
                if (OB_SUCC(ret) && !is_reach_mem_limit_) {
O
oceanbase-admin 已提交
4982
                  if (NULL != rest_result && rest_result->is_always_false()) {
O
obdev 已提交
4983
                    // not contain row, if rest result is false, then whole result is false
O
oceanbase-admin 已提交
4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998
                    if (!contain_row_) {
                      tmp_result = rest_result;
                    }
                  } else if (NULL != rest_result && rest_result->is_always_true()) {
                    // no need to link rest part
                  } else {
                    tmp_result->link_gt(rest_result);
                  }
                }
              }
            }
          }
        }

        // 4. add current result to result array
4999
        if (OB_SUCC(ret) && !is_reach_mem_limit_) {
O
oceanbase-admin 已提交
5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027
          // and the result to result array
          if (OB_ISNULL(tmp_result)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("tmp_result is null.", K(ret));
          } else {
            if (tmp_result->is_always_false()) {
              // ignore false
              if (!find_false) {
                find_false = tmp_result;
              }
            } else if (tmp_result->is_always_true()) {
              // no need to do any more
              always_true = true;
              res_array.clear();
              if (!res_array.add_last(tmp_result)) {
                ret = OB_ERR_UNEXPECTED;
                LOG_WARN("res_array added tmp_result failed.", K(ret));
              }
            } else {
              if (!res_array.add_last(tmp_result)) {
                ret = OB_ERR_UNEXPECTED;
                LOG_WARN("res_array added tmp_result failed.", K(ret));
              }
            }
          }
        }
      }
    }
5028
    if (OB_SUCC(ret) && res_array.get_size() <= 0 && !is_reach_mem_limit_) {
O
oceanbase-admin 已提交
5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045
      // all false ranges
      if (OB_ISNULL(find_false)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("find_false is null.", K(ret));
      } else if (!res_array.add_last(find_false)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("res_array added find_false failed.", K(ret));
      }
    }
  }
  return ret;
}

//  And all query range graph
//  the initial ranges must come from add_and_item (), that ensure only 1 real-true graph in array
//  and no part false in graph

W
wangzelin.wzl 已提交
5046
int ObQueryRange::and_range_graph(ObKeyPartList &ranges, ObKeyPart  *&out_key_part)
O
oceanbase-admin 已提交
5047 5048 5049 5050 5051 5052 5053 5054
{
  int ret = OB_SUCCESS;
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to do stack overflow check", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack overflow", K(ret));
O
obdev 已提交
5055
  } else if (OB_UNLIKELY(ranges.get_size() <= 0)) {
O
oceanbase-admin 已提交
5056
    ret = OB_INVALID_ARGUMENT;
W
wangzelin.wzl 已提交
5057
    LOG_WARN("AND array can not be empty",
O
obdev 已提交
5058
             K(ret), K(ranges.get_size()));
5059 5060
  } else if (is_reach_mem_limit_) {
    // do nothing
O
oceanbase-admin 已提交
5061 5062 5063 5064 5065
  } else if (1 == ranges.get_size()) {
    out_key_part = ranges.get_first();
    ranges.remove(out_key_part);
  } else {

W
wangzelin.wzl 已提交
5066
    //each graph may have many or_next_
O
oceanbase-admin 已提交
5067 5068
    //    we split them to a single and list, then and each of two,
    //    at last do or of all the result
W
wangzelin.wzl 已提交
5069
    //E.g.
O
oceanbase-admin 已提交
5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083
    //    l_graph: ((A1 and B1) or (A2 and B2)) and other_cnd1
    //                 AND
    //    r_graph: ((A3 and B3) or (A4 and B4)) and other_cnd2
    //    Equal to:
    //                 ((A1 and B1) and (A3 and B3)) and (other_cnd1 and other_cnd2)
    //                 OR
    //                 ((A1 and B1) and (A4 and B4)) and (other_cnd1 and other_cnd2)
    //                 OR
    //                 ((A2 and B2) and (A3 and B3)) and (other_cnd1 and other_cnd2)
    //                 OR
    //                 ((A2 and B2) and (A4 and B4)) and (other_cnd1 and other_cnd2)

    ObKeyPartList res_storage1;
    ObKeyPartList res_storage2;
W
wangzelin.wzl 已提交
5084
    ObKeyPart *cur = ranges.get_first();
5085
    ranges.remove_first();
O
oceanbase-admin 已提交
5086 5087 5088
    if (OB_ISNULL(cur)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("cur is null.", K(ret));
5089 5090 5091 5092
    } else if (cur->is_always_true() || cur->is_always_false()) {
      cur->and_next_ = NULL;
      cur->or_next_ = NULL;
      if (!res_storage1.add_last(cur)) {
O
oceanbase-admin 已提交
5093
        ret = OB_ERR_UNEXPECTED;
5094
        LOG_WARN("res_storage1 added cur failed.", K(ret));
O
oceanbase-admin 已提交
5095
      }
5096 5097
    } else if (OB_FAIL(split_general_or(cur, res_storage1))) {
      LOG_WARN("split general or key part failed", K(ret));
O
oceanbase-admin 已提交
5098
    }
W
wangzelin.wzl 已提交
5099 5100
    ObKeyPartList *l_array = &res_storage1;
    ObKeyPartList *res_array = &res_storage2;
O
oceanbase-admin 已提交
5101
    int i = 0;
5102
    while (OB_SUCC(ret) && ranges.get_size() > 0 && !is_reach_mem_limit_) {
W
wangzelin.wzl 已提交
5103
      ObKeyPart *other = ranges.get_first();
O
oceanbase-admin 已提交
5104 5105 5106 5107 5108 5109 5110 5111 5112 5113
      ranges.remove_first();
      ++i;
      if (i % 2) {
        l_array = &res_storage1;
        res_array = &res_storage2;
      } else {
        l_array = &res_storage2;
        res_array = &res_storage1;
      }
      ObKeyPartList r_array;
5114
      if (OB_ISNULL(other)) {
O
oceanbase-admin 已提交
5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("other is null.", K(ret));
      } else if (other->is_always_true() || other->is_always_false()) {
        if (!r_array.add_last(other)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("r_array added other failed", K(ret));
        }
      } else if (OB_FAIL(split_general_or(other, r_array))) {
        LOG_WARN("split general or key part failed", K(ret));
      }
      if (OB_FAIL(ret)) {
      } else if (OB_FAIL(SMART_CALL(and_single_gt_head_graphs(*l_array, r_array, *res_array)))) {
        LOG_WARN("And single general term head graphs failed", K(ret));
      }
    }
5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143
    if (OB_FAIL(ret) || is_reach_mem_limit_) {
    } else if (OB_FAIL(link_or_graphs(*res_array, out_key_part))) {
      LOG_WARN("And single general term head graphs failed",
                K(ret), K(res_array->get_size()));
    }
  }
  if (OB_SUCC(ret) && is_reach_mem_limit_ && query_range_ctx_ != NULL) {
    GET_ALWAYS_TRUE_OR_FALSE(true, out_key_part);
    contain_in_ = false;
    contain_row_ = false;
    has_exec_param_ = false;
    query_range_ctx_->precise_range_exprs_.reset();
    query_range_ctx_->final_exprs_.reset();
    LOG_WARN("use too much memory", K(is_reach_mem_limit_), K(query_range_ctx_->range_optimizer_max_mem_size_));
O
oceanbase-admin 已提交
5144 5145 5146 5147 5148 5149
  }
  return ret;
}

// Link all graphs of OR relation

W
wangzelin.wzl 已提交
5150
int ObQueryRange::link_or_graphs(ObKeyPartList &storage, ObKeyPart  *&out_key_part)
O
oceanbase-admin 已提交
5151 5152
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5153
  ObKeyPart *last_gt_tail = NULL;
O
oceanbase-admin 已提交
5154 5155 5156 5157
  if (OB_UNLIKELY(storage.get_size() <= 0)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("Or storage is empty", K(ret), "query range", to_cstring(*this));
  } else {
W
wangzelin.wzl 已提交
5158 5159
    ObKeyPart *first_key_part = storage.get_first();
    bool b_flag  = false;
O
oceanbase-admin 已提交
5160
    while (OB_SUCC(ret) && !b_flag && storage.get_size() > 0) {
W
wangzelin.wzl 已提交
5161
      ObKeyPart *cur = storage.get_first();
O
oceanbase-admin 已提交
5162
      storage.remove_first();
O
obdev 已提交
5163
      if (OB_LIKELY(NULL != cur)) {
O
oceanbase-admin 已提交
5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176
        if (cur == first_key_part) {
          out_key_part = first_key_part;
          last_gt_tail = first_key_part;
        } else if (cur->is_always_true()) {
          // return ture
          out_key_part = cur;
          b_flag = true;
        } else if (cur->is_always_false()) {
          // ignore false
          // if the first is always_false_, out_key_part has already pointed to it
        } else {
          // we have record the first always_false_,
          // replace it to the first following none-always_false_ key part
O
obdev 已提交
5177
          if (OB_ISNULL(out_key_part)) {
O
oceanbase-admin 已提交
5178 5179 5180 5181 5182
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("out_key_part is null.", K(ret));
          } else if (out_key_part->is_always_false()) {
            out_key_part = cur;
          } else {
O
obdev 已提交
5183
            if (OB_ISNULL(last_gt_tail)) {
O
oceanbase-admin 已提交
5184 5185 5186 5187 5188 5189 5190 5191 5192 5193
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("last_gt_tail is null.", K(ret));
            } else {
              // link the key part to previous or_next_
              last_gt_tail->or_next_ = cur;
            }
          }
        }
        if (OB_SUCC(ret)) {
          // find the last item in gt
W
wangzelin.wzl 已提交
5194 5195 5196
          for (last_gt_tail = cur;
               NULL != last_gt_tail && last_gt_tail->or_next_ != NULL;
               last_gt_tail = last_gt_tail->or_next_);
O
oceanbase-admin 已提交
5197 5198 5199 5200 5201 5202 5203 5204 5205 5206
        }
      }
    }
  }
  return ret;
}

// Replace unknown value in item_next_ list,
// and intersect them.

L
Larry955 已提交
5207
int ObQueryRange::definite_key_part(ObKeyPart *key_part, ObExecContext &exec_ctx,
L
Larry955 已提交
5208 5209
                                    const ObDataTypeCastParams &dtc_params,
                                    bool &is_bound_modified)
O
oceanbase-admin 已提交
5210 5211 5212
{
  int ret = OB_SUCCESS;
  if (NULL != key_part) {
W
wangzelin.wzl 已提交
5213 5214 5215
    for (ObKeyPart *cur = key_part;
         OB_SUCC(ret) && NULL != cur;
         cur = cur->item_next_) {
L
Larry955 已提交
5216
      if (OB_FAIL(replace_unknown_value(cur, exec_ctx, dtc_params, is_bound_modified))) {
O
oceanbase-admin 已提交
5217
        LOG_WARN("Replace unknown value failed", K(ret));
W
wangzelin.wzl 已提交
5218
      } else if (cur->is_always_false()) { // set key_part false
5219 5220 5221 5222
        if (key_part->is_in_key()) {
          key_part->id_ = cur->id_;
          key_part->pos_ = cur->pos_;
        }
O
oceanbase-admin 已提交
5223 5224
        key_part->normal_keypart_ = cur->normal_keypart_;
        key_part->key_type_ = T_NORMAL_KEY;
5225
        // key_part = cur; cause bug ->
O
oceanbase-admin 已提交
5226
        break;
O
obdev 已提交
5227 5228
      } else if (cur->is_always_true()) {
        // do nothing
O
oceanbase-admin 已提交
5229
      } else if (key_part != cur) {
O
obdev 已提交
5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240
        if (key_part->is_in_key() && cur->is_in_key()) {
          ObSEArray<int64_t, 16> common_offsets;
          if (OB_FAIL(ObOptimizerUtil::intersect(key_part->in_keypart_->offsets_,
                                                 cur->in_keypart_->offsets_,
                                                 common_offsets))) {
            LOG_WARN("failed to do intersect", K(ret));
          } else if (OB_FAIL(key_part->intersect_two_in_keys(cur, common_offsets))) {
            LOG_WARN("failed to intersect two in keys", K(ret));
          }
        } else if (key_part->is_in_key()) {
          if (cur->is_phy_rowid_key_part_) {
L
Larry955 已提交
5241 5242 5243 5244
            // in and rowid, always make the result becomes rowid
            if (OB_FAIL(key_part->shallow_node_copy(*cur))) {
              LOG_WARN("failed to shallow copy cur", K(ret));
            }
O
obdev 已提交
5245 5246 5247 5248 5249 5250 5251 5252 5253
          } else if (OB_FAIL(key_part->intersect_in(cur))) {
            LOG_WARN("failed to intersect in", K(ret));
          }
        } else if (cur->is_in_key()) {
          if (key_part->is_phy_rowid_key_part_) {
            // do nothing
            // in and rowid, always make the result becomes rowid
          } else if (OB_FAIL(cur->intersect_in(key_part))) {
            LOG_WARN("failed to intersect in", K(ret));
L
Larry955 已提交
5254 5255
          } else if (OB_FAIL(key_part->shallow_node_copy(*cur))) {
            LOG_WARN("failed to shallow copy cur", K(ret));
O
obdev 已提交
5256 5257
          }
        } else if (OB_FAIL(key_part->intersect(cur, contain_row_))) {
O
oceanbase-admin 已提交
5258
          LOG_WARN("Intersect key part failed", K(ret));
O
obdev 已提交
5259 5260
        }
        if (OB_SUCC(ret) && key_part->is_always_false()) {
O
oceanbase-admin 已提交
5261 5262 5263 5264 5265 5266 5267 5268 5269
          break;
        }
      }
    }
    key_part->item_next_ = NULL;
  }
  return ret;
}

O
obdev 已提交
5270
int ObQueryRange::union_single_equal_cond(ObExecContext *exec_ctx,
W
wangzelin.wzl 已提交
5271 5272 5273
                                          const ObDataTypeCastParams &dtc_params,
                                          ObKeyPart *cur1,
                                          ObKeyPart *cur2)
O
oceanbase-admin 已提交
5274 5275 5276 5277 5278 5279
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(cur1) || OB_ISNULL(cur2)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("cur1 or cur2 is null", K(ret), K(cur1), K(cur2));
  } else if (cur1->and_next_ && cur2->and_next_) {
W
wangzelin.wzl 已提交
5280
    ObKeyPart *next_key_part = NULL;
O
oceanbase-admin 已提交
5281 5282 5283 5284
    ObKeyPartList next_or_list;
    if (!next_or_list.add_last(cur1->and_next_) || !next_or_list.add_last(cur2->and_next_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("Do merge Or graph failed", K(ret));
W
wangzelin.wzl 已提交
5285
    } else if (OB_FAIL(or_range_graph(next_or_list, exec_ctx, next_key_part, dtc_params))) {
O
oceanbase-admin 已提交
5286
      LOG_WARN("Do merge Or graph failed", K(ret));
L
Larry955 已提交
5287 5288
    } else if (next_key_part->is_always_true()) {
      cur1->and_next_ = NULL;
O
oceanbase-admin 已提交
5289 5290 5291 5292 5293 5294 5295
    } else {
      cur1->and_next_ = next_key_part;
    }
  } else {
    if (query_range_ctx_ != NULL && query_range_ctx_->cur_expr_is_precise_) {
      query_range_ctx_->cur_expr_is_precise_ = (NULL == cur1->and_next_ && NULL == cur2->and_next_);
    }
O
obdev 已提交
5296 5297 5298
    int64_t removed_offset = cur1->is_in_key() ? cur1->in_keypart_->get_max_offset() + 1:
                                                 cur1->pos_.offset_ + 1;
    if (OB_FAIL(remove_precise_range_expr(removed_offset))) {
O
oceanbase-admin 已提交
5299
      LOG_WARN("remove precise range expr failed", K(ret));
O
obdev 已提交
5300 5301
    } else {
      cur1->and_next_ = NULL;
O
oceanbase-admin 已提交
5302 5303 5304 5305 5306 5307
    }
  }
  return ret;
}

// do two path and operation
W
wangzelin.wzl 已提交
5308 5309
int ObQueryRange::or_single_head_graphs(ObKeyPartList &or_list,
                                        ObExecContext *exec_ctx,
L
Larry955 已提交
5310
                                        const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324
{
  int ret = OB_SUCCESS;
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to do stack overflow check", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack overflow", K(ret));
  } else if (or_list.get_size() <= 0) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("And array can not be empty", K(ret));
  } else {
    // 1. replace unknown value, and refresh the graph
    if (NEED_PREPARE_PARAMS == state_) {
W
wangzelin.wzl 已提交
5325 5326 5327
      ObKeyPart *find_true = NULL;
      ObKeyPart *cur = or_list.get_first();
      if (OB_ISNULL(exec_ctx)) {
O
oceanbase-admin 已提交
5328
        ret = OB_INVALID_ARGUMENT;
W
wangzelin.wzl 已提交
5329
        LOG_WARN("exec_ctx is needed to extract question mark");
O
oceanbase-admin 已提交
5330 5331 5332
      } else if (OB_ISNULL(cur)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("cur is null.", K(ret));
W
wangzelin.wzl 已提交
5333
      } else {}
O
oceanbase-admin 已提交
5334 5335
      bool part_is_true = false;
      while (!part_is_true && OB_SUCC(ret) && cur != or_list.get_header()) {
W
wangzelin.wzl 已提交
5336 5337 5338
        ObKeyPart *old_tmp = cur;
        ObKeyPart *new_tmp = cur;
        ObKeyPart *and_next = cur->and_next_;
O
oceanbase-admin 已提交
5339
        cur = cur->get_next();
L
Larry955 已提交
5340
        bool is_bound_modified = false;
O
oceanbase-admin 已提交
5341
        // replace undefinited value
L
Larry955 已提交
5342
        if (OB_FAIL(definite_key_part(new_tmp, *exec_ctx, dtc_params, is_bound_modified))) {
O
oceanbase-admin 已提交
5343 5344 5345 5346 5347 5348 5349 5350
          LOG_WARN("Fill unknown value failed", K(ret));
        } else if (new_tmp != old_tmp) {
          old_tmp->replace_by(new_tmp);
        } else {
          // do nothing
        }
        if (OB_FAIL(ret)) {
          // do nothing
O
obdev 已提交
5351
        } else if (OB_ISNULL(new_tmp)) {
O
oceanbase-admin 已提交
5352
          ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
5353
          LOG_WARN("new_tmp is null.", K(ret));
O
oceanbase-admin 已提交
5354
        } else {
W
wangzelin.wzl 已提交
5355
        // check result keypart
O
oceanbase-admin 已提交
5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369
          if (new_tmp->is_always_true()) {
            if (!find_true) {
              find_true = new_tmp;
              new_tmp->and_next_ = NULL;
            }
            or_list.remove(new_tmp);
            part_is_true = true;
          } else if (new_tmp->is_always_false()) {
            new_tmp->and_next_ = NULL;
            if (or_list.get_size() > 1) {
              or_list.remove(new_tmp);
            }
          } else {
            // handle the rest of the graph recursively
L
Larry955 已提交
5370 5371 5372 5373
            if (contain_row_ && is_bound_modified) {
              and_next = NULL;
              new_tmp->and_next_ = NULL;
            } else if (NULL != and_next) {
O
oceanbase-admin 已提交
5374 5375 5376 5377
              // recursively process following and key part
              ObKeyPartList sub_or_list;
              if (OB_FAIL(split_or(and_next, sub_or_list))) {
                LOG_WARN("Split OR failed", K(ret));
O
obdev 已提交
5378
              } else if (OB_FAIL(or_range_graph(sub_or_list, exec_ctx, new_tmp->and_next_,
L
Larry955 已提交
5379
                                                dtc_params))) {
O
oceanbase-admin 已提交
5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393
                LOG_WARN("Do OR of range graphs failed", K(ret));
              }
            }
          }
        }
      }
      if (OB_SUCC(ret) && NULL != find_true) {
        or_list.clear();
        if (!or_list.add_last(find_true)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Add true keypart graph failed", K(ret));
        }
      }
    }
W
wangzelin.wzl 已提交
5394 5395
    if (OB_SUCC(ret) && or_list.get_size() > 1) { // 2. do OR of the heads of range graphs
      ObKeyPart *cur1 = or_list.get_first();
O
oceanbase-admin 已提交
5396 5397 5398
      while (OB_SUCC(ret) && cur1 != or_list.get_last() && cur1 != or_list.get_header()) {
        bool has_union = false;
        // Union key part who have intersection from next
W
wangzelin.wzl 已提交
5399
        ObKeyPart *cur2 = NULL;
O
obdev 已提交
5400
        if (OB_ISNULL(cur1) || OB_ISNULL(cur1->get_next())) {//yeti2
O
oceanbase-admin 已提交
5401 5402 5403 5404 5405 5406
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("keypart is null.", K(ret));
        } else {
          cur2 = cur1->get_next();
        }
        while (OB_SUCC(ret) && cur2 != or_list.get_header()) {
O
obdev 已提交
5407
          ObKeyPart *cur1_next = cur1->get_next();
W
wangzelin.wzl 已提交
5408
          ObKeyPart *cur2_next = cur2->get_next();
O
obdev 已提交
5409
          if (cur1->is_in_key() && cur2->is_in_key()) {
L
Larry955 已提交
5410 5411 5412 5413 5414 5415 5416
            if (cur1->and_next_ != NULL || cur2->and_next_ != NULL) {
              if (OB_FAIL(remove_precise_range_expr(cur1->in_keypart_->get_min_offset() + 1))) {
                LOG_WARN("remove precise range expr failed", K(ret));
              } else if (query_range_ctx_ != NULL) {
                query_range_ctx_->cur_expr_is_precise_ = false;
              }
            }
5417 5418
            if (OB_SUCC(ret) && !cur1->is_question_mark() && !cur2->is_question_mark() &&
                cur1->item_next_ == NULL && cur2->item_next_ == NULL) {
O
obdev 已提交
5419 5420 5421 5422 5423 5424 5425 5426 5427 5428
              if (OB_FAIL(union_in_with_in(or_list,
                                           cur1, cur2,
                                           exec_ctx,
                                           dtc_params,
                                           has_union))) {
                LOG_WARN("failed to union two in keys", K(ret));
              } else if (cur1->is_always_false()) {
                or_list.remove(cur1);
                cur1 = cur1_next;
              }
O
oceanbase-admin 已提交
5429
            }
O
obdev 已提交
5430
          } else if (cur1->is_in_key()) {
L
Larry955 已提交
5431 5432 5433 5434 5435 5436 5437 5438 5439
            if ((!cur1->in_keypart_->is_single_in()) &&
                 cur2->and_next_ != NULL && cur2->and_next_->is_in_key()) {
              // (c1,c2) in or (c1 and c2 in ) is regarded as not precise
              if (OB_FAIL(remove_precise_range_expr(cur1->in_keypart_->get_min_offset() + 1))) {
                LOG_WARN("remove precise range expr failed", K(ret));
              } else if (query_range_ctx_ != NULL) {
                query_range_ctx_->cur_expr_is_precise_ = false;
              }
            }
O
obdev 已提交
5440
            bool need_remove_normal = false;
5441 5442
            if (OB_SUCC(ret) && !cur1->is_question_mark() && !cur2->is_question_mark() &&
                cur1->item_next_ == NULL && cur2->item_next_ == NULL) {
O
obdev 已提交
5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459
              if (OB_FAIL(union_in_with_normal(cur1, cur2,
                                               exec_ctx,
                                               dtc_params,
                                               has_union,
                                               need_remove_normal))) {
                LOG_WARN("failed to union in param with key part", K(ret));
              } else if (cur1->is_always_false()) {
                or_list.remove(cur1);
                cur1 = cur1_next;
              }
              if (OB_SUCC(ret) && need_remove_normal) {
                or_list.remove(cur2);
              }
            }
          } else if (cur2->is_in_key()) {
            ObKeyPart *cur1_next = cur1->get_next();
            bool need_remove_normal = false;
L
Larry955 已提交
5460 5461 5462 5463 5464 5465 5466 5467
            if ((!cur2->in_keypart_->is_single_in()) &&
                 cur1->and_next_ != NULL && cur1->and_next_->is_in_key()) {
              if (OB_FAIL(remove_precise_range_expr(cur2->in_keypart_->get_min_offset() + 1))) {
                LOG_WARN("remove precise range expr failed", K(ret));
              } else if (query_range_ctx_ != NULL) {
                query_range_ctx_->cur_expr_is_precise_ = false;
              }
            }
5468 5469
            if (OB_SUCC(ret) && !cur1->is_question_mark() && !cur2->is_question_mark() &&
                cur1->item_next_ == NULL && cur2->item_next_ == NULL) {
O
obdev 已提交
5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482
              if (OB_FAIL(union_in_with_normal(cur2, cur1,
                                               exec_ctx,
                                               dtc_params,
                                               has_union,
                                               need_remove_normal))) {
                LOG_WARN("failed to union in param with key part", K(ret));
              } else if (cur2->is_always_false()) {
                or_list.remove(cur2);
              }
              if (OB_SUCC(ret) && need_remove_normal) {
                or_list.remove(cur1);
                cur1 = cur1_next;
              }
O
oceanbase-admin 已提交
5483
            }
O
obdev 已提交
5484 5485 5486
          } else if (cur1->key_node_is_equal(cur2)) {
            if (OB_FAIL(union_single_equal_cond(exec_ctx, dtc_params, cur1, cur2))) {
              LOG_WARN("union single equal cond failed", K(ret));
O
oceanbase-admin 已提交
5487
            }
O
obdev 已提交
5488 5489 5490
            or_list.remove(cur2);
          } else if (cur1->union_key(cur2)) {
            has_union = true;
O
oceanbase-admin 已提交
5491 5492 5493 5494 5495 5496 5497 5498
            if (cur1->and_next_ && cur1->and_next_->equal_to(cur2->and_next_)) {
              // keep and_next_
            } else {
              if (query_range_ctx_ != NULL && query_range_ctx_->cur_expr_is_precise_) {
                query_range_ctx_->cur_expr_is_precise_ = (NULL == cur1->and_next_ && NULL == cur2->and_next_);
              }
              if (OB_FAIL(remove_precise_range_expr(cur1->pos_.offset_ + 1))) {
                LOG_WARN("remove precise range expr failed", K(ret));
O
obdev 已提交
5499 5500
              } else {
                cur1->and_next_ = NULL;
O
oceanbase-admin 已提交
5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519
              }
            }
            or_list.remove(cur2);
          }
          if (OB_SUCC(ret)) {
            cur2 = cur2_next;
          }
        }
        if (OB_SUCC(ret)) {
          if (!has_union) {
            cur1 = cur1->get_next();
          }
        }
      }
    }
  }
  return ret;
}

O
obdev 已提交
5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531
int ObQueryRange::union_in_with_in(ObKeyPartList &or_list,
                                   ObKeyPart *cur1,
                                   ObKeyPart *cur2,
                                   ObExecContext *exec_ctx,
                                   const ObDataTypeCastParams &dtc_params,
                                   bool &has_union)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(cur1) || OB_ISNULL(cur2) ||
      OB_UNLIKELY(!cur1->is_in_key() || !cur2->is_in_key())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get invalid argument", K(ret), K(*cur1), K(*cur2));
5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543
  } else if (OB_UNLIKELY(!cur1->in_keypart_->offsets_same_to(cur2->in_keypart_))) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("union in keys with not aligned offset is not allowed!", K(ret), K(*cur1), K(*cur2));
  } else if (cur1->key_node_is_equal(cur2)) {
    if (OB_FAIL(union_single_equal_cond(exec_ctx, dtc_params, cur1, cur2))) {
      LOG_WARN("failed to union single or equal cond", K(ret));
    }
  } else if (OB_FAIL(cur1->in_keypart_->union_in_key(cur2->in_keypart_))) {
    LOG_WARN("failed to union in key", K(ret));
  } else if (cur1->and_next_ != NULL && cur1->and_next_->equal_to(cur2->and_next_)) {
    // keep and_next_
  } else {
O
obdev 已提交
5544
    cur1->and_next_ = NULL;
5545 5546
  }
  if (OB_SUCC(ret)) {
O
obdev 已提交
5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680
    has_union = true;
    or_list.remove(cur2);
  }
  return ret;
}

int ObQueryRange::union_in_with_normal(ObKeyPart *cur1,
                                       ObKeyPart *cur2,
                                       ObExecContext *exec_ctx,
                                       const ObDataTypeCastParams &dtc_params,
                                       bool &is_unioned,
                                       bool &need_remove_normal)
{
  int ret = OB_SUCCESS;
  InParamMeta *param_meta = NULL;
  need_remove_normal = false;
  if (OB_ISNULL(cur1) || OB_ISNULL(cur2) || OB_UNLIKELY(!cur1->is_in_key() || cur2->is_in_key())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(cur1), K(cur2));
  } else if (OB_UNLIKELY(!cur1->in_keypart_->find_param(cur2->pos_.offset_, param_meta))) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("should found same key part", K(ret));
  } else {
    ObSEArray<int64_t, 16> removed_val_idx;
    for (int64_t i = 0; OB_SUCC(ret) && i < param_meta->vals_.count(); ++i) {
      const ObObj &val = param_meta->vals_.at(i);
      int s_cmp = cur2->normal_keypart_->start_.compare(val);
      int e_cmp = cur2->normal_keypart_->end_.compare(val);
      bool in_has_next = !cur1->in_keypart_->is_single_in() || cur1->and_next_ != NULL;
      bool need_remove_val = false;
      if (s_cmp > 0 || e_cmp < 0) {
        // do nothing
      } else if (s_cmp == 0 && e_cmp == 0) {
        if (cur2->and_next_ == NULL) {
          // c1 in (1,2) or c1 = 1 --> c1 in (2) or c1 = 1
          // c1 in (1,2) and c2 = 1 or c1 = 1 --> (c1 in (2) and c2 = 1) or c1 = 1
          // cur1->and_next_ = NULL;
          need_remove_val = true;
        } else if (!in_has_next) {
          // c1 in (1,2) or c1 = 1 and c2 = 1 --> c1 in (1,2)
          need_remove_normal = true;
        } else if (OB_FAIL(union_single_equal_cond(cur1,
                                                   cur2,
                                                   val,
                                                   exec_ctx,
                                                   dtc_params,
                                                   need_remove_val,
                                                   need_remove_normal))) {
          LOG_WARN("failed to union next key", K(ret));
        }
        is_unioned = true;
      } else if (s_cmp == 0) {
        // c1 in (1, 2) or c1 > 2             -> c1 in (1) or c1 >= 2
        // c1 in (1, 2) or c1 >= 2            -> c1 in (1) or c1 >= 2
        // c1 in (1, 2) and c2 = 1 or c1 >= 2 -> c1 in (1) and c2 = 1 or c1 >= 2
        // c1 in (1, 2) or c1 > 2 and c2 = 1 x-> can not convert to c1 in (1) or c1 >= 2 and c2 = 1
        //                                       so do nothing
        // need check and next
        // c1 in (1, 2) and c2 = 1 or c1 > 2 and c2 = 1 -> c1 in (1) or c1 >= 2 and c2 = 1
        // c1 in (1, 2) and c2 = 1 or c1 >= 2 and c2 = 1 --> c1 in (2) or c1 >= 2 and c2 = 1
        // c1 in (1, 2) or c1 >= 2 and c2 = 1 --> c1 in (1) or c1 >= 2
        if (cur2->normal_keypart_->include_start_ || (cur2->and_next_ == NULL && !in_has_next)) {
          is_unioned = true;
          need_remove_val = true;
          // case below no need to remove precise:
          // 1. both cur1 and cur2 not have and next;
          // 2. cur2 include start and not has and next
          bool no_need_remove_precise = (cur2->and_next_ == NULL && !in_has_next) ||
                                        (cur2->normal_keypart_->include_start_ && cur2->and_next_ == NULL);
          if (no_need_remove_precise) {
            // do nothing
          } else if (OB_FAIL(remove_precise_range_expr(cur2->pos_.offset_))) {
            LOG_WARN("failed to remove precise expr", K(ret));
          } else if (query_range_ctx_ != NULL) {
            // for correctness, set expr to be not precise
            query_range_ctx_->cur_expr_is_precise_ = false;
          }
          cur2->and_next_ = NULL;
          cur2->normal_keypart_->include_start_ = true;
        }
      } else if (e_cmp == 0) {
        if (cur2->normal_keypart_->include_end_ || (cur2->and_next_ == NULL && !in_has_next)) {
          is_unioned = true;
          need_remove_val = true;
          bool no_need_remove_precise = (cur2->and_next_ == NULL && !in_has_next) ||
                                        (cur2->normal_keypart_->include_end_ && cur2->and_next_ == NULL);
          if (no_need_remove_precise) {
            // do nothing
          } else if (OB_FAIL(remove_precise_range_expr(cur2->pos_.offset_))) {
            LOG_WARN("failed to remove precise expr", K(ret));
          } else if (query_range_ctx_ != NULL) {
            // for correctness, set expr to be not precise
            query_range_ctx_->cur_expr_is_precise_ = false;
          }
          cur2->and_next_ = NULL;
          cur2->normal_keypart_->include_end_ = true;
        }
      } else {
        is_unioned = true;
        need_remove_val = true;
        if (cur2->and_next_ == NULL) {
          // do nothing
        } else {
          cur2->and_next_ = NULL;
          if (OB_FAIL(remove_precise_range_expr(cur2->pos_.offset_))) {
            LOG_WARN("failed to remove precise expr", K(ret));
          } else if (query_range_ctx_ != NULL) {
            query_range_ctx_->cur_expr_is_precise_ = false;
          }
        }
      }
      if (OB_SUCC(ret) && need_remove_val && OB_FAIL(removed_val_idx.push_back(i))) {
        LOG_WARN("failed to push back removed value idx", K(ret));
      }
    }
    if (OB_SUCC(ret) && OB_FAIL(cur1->remove_in_params_vals(removed_val_idx))) {
      LOG_WARN("failed to adjust param values", K(ret));
    }
  }
  return ret;
}

int ObQueryRange::union_single_equal_cond(ObKeyPart *cur1,
                                          ObKeyPart *cur2,
                                          const ObObj &val,
                                          ObExecContext *exec_ctx,
                                          const ObDataTypeCastParams &dtc_params,
                                          bool &need_remove_val,
                                          bool &need_remove_normal)
{
  int ret = OB_SUCCESS;
  ObKeyPart *cur2_and_next = NULL;
  ObKeyPartList or_list;
  ObKeyPart *new_next = NULL;
5681
  bool need_remove_precise = false;
O
obdev 已提交
5682 5683 5684 5685
  if (OB_ISNULL(cur1) || OB_ISNULL(cur2) ||
      OB_ISNULL(cur2_and_next = cur2->and_next_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(cur1), K(cur2), K(cur2_and_next));
5686 5687 5688 5689
  } else if (OB_UNLIKELY(!cur1->in_keypart_->is_single_in())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("union row in with normal key is not supported!", K(ret), K(*cur1));
  } else {
O
obdev 已提交
5690 5691 5692 5693 5694 5695 5696 5697
    // case 1: c1 in (x) and c2    or c1 and c2
    // case 2: c1 in (x) and c2    or c1 and c2 in
    // case 3: c1 in (x) and c2 in or c1 and c2
    // case 4: c1 in (x) and c2 in or c1 and c2 in
    // others: c1 in (x) and cX or c1 and cY
    ObKeyPart *new_cur1 = NULL;
    if (OB_FAIL(deep_copy_range_graph(cur1, new_cur1))) {
      LOG_WARN("failed to deep copy range", K(ret));
5698 5699 5700
    } else if (is_reach_mem_limit_) {
      cur2->and_next_ = NULL;
      need_remove_precise = true;
O
obdev 已提交
5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718
    } else if (OB_ISNULL(new_cur1) || OB_ISNULL(new_cur1->and_next_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("get unexpected null", K(ret), K(new_cur1));
    } else if (new_cur1->and_next_->equal_to(cur2_and_next)) {
      need_remove_normal = true;
    } else if (!or_list.add_last(new_cur1->and_next_) ||
               !or_list.add_last(cur2_and_next)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("failed to add in key", K(ret));
    } else if (OB_FAIL(SMART_CALL(or_range_graph(or_list, exec_ctx,
                                                 new_next, dtc_params)))) {
      LOG_WARN("failed to or next key part", K(ret));
    } else {
      // c1 in (1,2) and c2 = 1 or c1 = 1 and c2 < 0 -> c1 in (2) and c2 = 1 or c1 = 1 and (c2 < 0 or c2 = 1)
      // c1 in (1,2) and c2 = 1 or c1 = 1 and c2 > 0 -> c1 in (2) and c2 = 1 or c1 = 1 and c2 > 0
      need_remove_val = true;
      cur2->and_next_ = new_next->is_always_true() ? NULL : new_next;
    }
5719 5720 5721 5722 5723 5724
  }
  if (OB_FAIL(ret) || !need_remove_precise) {
  } else if (OB_FAIL(remove_precise_range_expr(cur2->pos_.offset_))) {
    LOG_WARN("failed to remove precise range expr", K(ret));
  } else if (query_range_ctx_ != NULL) {
    query_range_ctx_->cur_expr_is_precise_ = false;
O
obdev 已提交
5725 5726 5727 5728
  }
  return ret;
}

W
wangzelin.wzl 已提交
5729 5730 5731 5732
int ObQueryRange::definite_in_range_graph(ObExecContext &exec_ctx,
                                          ObKeyPart *&root,
                                          bool &has_scan_key,
                                          const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
5733 5734
{
  int ret = OB_SUCCESS;
5735 5736 5737 5738 5739 5740 5741 5742 5743 5744
  int64_t cnt = 0;
  for (ObKeyPart *cur_part = root; OB_SUCC(ret) && cur_part != NULL; cur_part = cur_part->or_next_) {
    bool is_bound_modified = false;
    if (++cnt % 1000 == 0 && OB_FAIL(THIS_WORKER.check_status())) {
      LOG_WARN("check status fail", K(ret));
    } else if (OB_FAIL(definite_key_part(cur_part, exec_ctx, dtc_params, is_bound_modified))) {
      LOG_WARN("definite key part failed", K(ret));
    } else {
      if (contain_row_ && is_bound_modified) {
        cur_part->and_next_ = NULL;
O
oceanbase-admin 已提交
5745
      }
5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756
      //如果graph中某个节点不是严格的等值条件,那么这个节点是一个scan key,需要做or合并
      //如果有恒false条件,也需要走到or去做去除处理
      if (!cur_part->is_equal_condition()) {
        has_scan_key = true;
      }
      if (NULL != cur_part->and_next_ &&
          (NULL == cur_part->or_next_ || cur_part->or_next_->and_next_ != cur_part->and_next_)) {
        if (OB_FAIL(SMART_CALL(definite_in_range_graph(exec_ctx, cur_part->and_next_,
                                                       has_scan_key, dtc_params)))) {
          LOG_WARN("definite and_next_ key part failed", K(ret));
        }
O
oceanbase-admin 已提交
5757 5758 5759 5760 5761 5762
      }
    }
  }
  return ret;
}

O
obdev 已提交
5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776
#define ALLOC_TRUE_KEYPART(find_true, min_offset) \
do { \
  if (NULL == find_true) { \
    if (OB_FAIL(alloc_full_key_part(find_true))) { \
      LOG_WARN("Get full key part failed", K(ret)); \
    } else if (query_range_ctx_ != NULL) { \
      query_range_ctx_->cur_expr_is_precise_ = false; \
      if (OB_FAIL(remove_precise_range_expr(min_offset))) { \
        LOG_WARN("remove precise range expr failed", K(ret)); \
      } \
    } \
  } \
} while (0) \

W
wangzelin.wzl 已提交
5777 5778 5779
int ObQueryRange::or_range_graph(ObKeyPartList &ranges,
                                 ObExecContext *exec_ctx,
                                 ObKeyPart *&out_key_part,
L
Larry955 已提交
5780
                                 const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
5781 5782 5783 5784 5785 5786 5787 5788
{
  int ret = OB_SUCCESS;
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to do stack overflow check", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack overflow", K(ret));
O
obdev 已提交
5789
  } else if (OB_UNLIKELY(ranges.get_size() <= 0)) {
O
oceanbase-admin 已提交
5790 5791 5792
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("OR array can not be empty", K(ranges.get_size()), K_(query_range_ctx));
  } else {
O
obdev 已提交
5793
    bool need_geo_rebuild = false;
W
wangzelin.wzl 已提交
5794 5795
    ObKeyPart *find_false = NULL;
    ObKeyPart *find_true = NULL;
O
oceanbase-admin 已提交
5796
    ObKeyPartList or_list;
W
wangzelin.wzl 已提交
5797
    ObKeyPart *head_key_part = ranges.get_first();
5798 5799
    bool find_phy_row_id = false;
    bool find_not_phy_row_id = false;
O
oceanbase-admin 已提交
5800 5801 5802 5803
    if (OB_ISNULL(head_key_part)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("head_key_part is null.", K(ret));
    } else {
O
obdev 已提交
5804 5805 5806 5807 5808 5809 5810
      uint64_t table_id = head_key_part->is_in_key() ?
                          head_key_part->in_keypart_->table_id_ :
                          head_key_part->id_.table_id_;
      int64_t head_offset = head_key_part->is_in_key() ?
                            head_key_part->in_keypart_->get_min_offset() :
                            head_key_part->pos_.offset_;
      int64_t min_offset = head_offset; // used to remove precise expr if needed
W
wangzelin.wzl 已提交
5811
      ObKeyPart *cur = NULL;
O
oceanbase-admin 已提交
5812 5813 5814
      while (OB_SUCC(ret) && ranges.get_size() > 0) {
        cur = ranges.get_first();
        ranges.remove_first();
O
obdev 已提交
5815
        if (OB_ISNULL(cur)) {
O
oceanbase-admin 已提交
5816 5817
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("cur is null.", K(ret));
5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834
        } else {
          need_geo_rebuild |= cur->is_geo_key();
          if (cur->is_phy_rowid_key_part()) {
            find_phy_row_id = true;
          } else {
            find_not_phy_row_id = true;
          }
        }
        if (OB_FAIL(ret)) {
        } else if (find_phy_row_id && find_not_phy_row_id) {
          // rowid = 'xxx' or c1 = 1
          // physical rowid won't transform to rowkey at final stage. Then physical rowid node and
          // other type node can't connected by or_next. Because final stage may compare node value
          // with different or node.
          min_offset = std::min(min_offset, cur->pos_.offset_);
          ALLOC_TRUE_KEYPART(find_true, min_offset);
          break;
O
oceanbase-admin 已提交
5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845
        } else if (cur->is_always_false() && NULL == cur->or_next_) {
          if (!find_false) {
            cur->and_next_ = NULL;
            find_false = cur;
          }
        } else if (cur->is_always_true() && NULL == cur->and_next_) {
          if (!find_true) {
            cur->or_next_ = NULL;
            find_true = cur;
          }
          break;
O
obdev 已提交
5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862
        } else if (cur == head_key_part) {
          if (OB_FAIL(split_or(cur, or_list))) {
            LOG_WARN("failed to split or", K(ret));
          }
        } else if (cur->is_in_key() && head_key_part->is_in_key()) {
          int64_t cur_min_offset = cur->in_keypart_->get_min_offset();
          bool is_first_same = cur_min_offset == head_offset;
          if (is_first_same) {
            if (OB_FAIL(split_or(cur, or_list))) {
              LOG_WARN("failed to split or", K(ret));
            }
          } else {
            min_offset = std::min(min_offset, cur_min_offset);
            ALLOC_TRUE_KEYPART(find_true, min_offset);
            break;
          }
        } else if (head_key_part->is_in_key()) {
L
Larry955 已提交
5863
          if (cur->pos_.offset_ == head_offset) {
O
obdev 已提交
5864 5865 5866 5867 5868 5869 5870 5871 5872
            if (OB_FAIL(split_or(cur, or_list))) {
              LOG_WARN("failed to split or", K(ret));
            }
          } else {
            min_offset = std::min(min_offset, cur->pos_.offset_);
            ALLOC_TRUE_KEYPART(find_true, min_offset);
            break;
          }
        } else if (cur->is_in_key()) {
L
Larry955 已提交
5873
          if (head_key_part->pos_.offset_ == cur->in_keypart_->get_min_offset()) {
O
obdev 已提交
5874 5875
            if (OB_FAIL(split_or(cur, or_list))) {
              LOG_WARN("failed to split or", K(ret));
O
oceanbase-admin 已提交
5876
            }
O
obdev 已提交
5877 5878 5879 5880
          } else {
            min_offset = std::min(min_offset, cur->in_keypart_->get_min_offset());
            ALLOC_TRUE_KEYPART(find_true, min_offset);
            break;
O
oceanbase-admin 已提交
5881
          }
O
obdev 已提交
5882 5883 5884 5885
        } else if (cur->pos_.offset_ != head_offset) {
          // E.g. (k1>0 and k2>0) or (k2<5) ==> (min, max)
          min_offset = std::min(min_offset, cur->pos_.offset_);
          ALLOC_TRUE_KEYPART(find_true, min_offset);
O
oceanbase-admin 已提交
5886 5887 5888 5889 5890 5891 5892
          break;
        } else if (OB_FAIL(split_or(cur, or_list))) {
          LOG_WARN("Split OR graph failed", K(ret));
        } else {
          // do nothing
        }
      }
O
obdev 已提交
5893 5894 5895
      if (OB_SUCC(ret)) {
        if (find_true) {
          find_true->id_.table_id_ = table_id;
W
wangzelin.wzl 已提交
5896
          out_key_part = find_true;
O
obdev 已提交
5897 5898 5899 5900 5901 5902 5903 5904
        } else if (or_list.get_size() <= 0) {
          // all false
          if (OB_ISNULL(find_false)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("find_false is null.", K(ret));
          } else {
            out_key_part = find_false;
          }
L
Larry955 已提交
5905
        } else if (OB_FAIL(SMART_CALL(or_single_head_graphs(or_list, exec_ctx, dtc_params)))) {
O
obdev 已提交
5906 5907
          LOG_WARN("Or single head graphs failed", K(ret));
        } else {
O
obdev 已提交
5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922
          bool has_geo_key = false;
          ObKeyPart *cur = or_list.get_first();
          for (int64_t i = 0; i < or_list.get_size(); i++) {
            has_geo_key |= cur->is_geo_key();
            cur = cur->get_next();
          }
          need_geo_rebuild &= !has_geo_key;
          // if contain ObGeoKeyPart, need do or_range_graph for deduplication with different spatial filters
          if (!need_geo_rebuild && OB_FAIL(link_or_graphs(or_list, out_key_part))) {
            LOG_WARN("Or single head graphs failed", K(ret));
          } else if (need_geo_rebuild && OB_FAIL(or_range_graph(or_list, exec_ctx, out_key_part, dtc_params))) {
            LOG_WARN("Or single head graphs failed", K(ret));
          } else {
            // do nothing
          }
O
obdev 已提交
5923
        }
O
oceanbase-admin 已提交
5924 5925 5926 5927 5928 5929
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944
int ObQueryRange::get_result_value(ObObj &val, ObExecContext &exec_ctx, ObIAllocator *allocator) const
{
  int ret = OB_SUCCESS;
  if (val.is_unknown()) {
    int64_t expr_idx = OB_INVALID_ID;
    ObPhysicalPlanCtx *phy_ctx = NULL;
    ObTempExpr *temp_expr = NULL;
    ObNewRow tmp_row;
    ObObj result;
    ObIAllocator &res_allocator = allocator != NULL ? *allocator : allocator_;
    if (OB_ISNULL(phy_ctx = exec_ctx.get_physical_plan_ctx())) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected null", K(ret));
    } else if (OB_FAIL(val.get_unknown(expr_idx))) {
      LOG_WARN("failed to get question mark value", K(ret), K(val));
O
obdev 已提交
5945
    } else if (OB_UNLIKELY(expr_idx < 0 || expr_idx >= expr_final_infos_.count())) {
W
wangzelin.wzl 已提交
5946 5947 5948 5949 5950 5951 5952 5953 5954 5955
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("invalid expr idx", K(expr_idx), K(ret));
    } else if (expr_final_infos_.at(expr_idx).cnt_exec_param_ &&
               phy_ctx->get_param_store().count() <= phy_ctx->get_original_param_cnt()) {
      // do nothing for exec param
    } else if (expr_final_infos_.at(expr_idx).is_param_) {
      int64_t param_idx = expr_final_infos_.at(expr_idx).param_idx_;
      if (OB_UNLIKELY(param_idx < 0 || param_idx >= phy_ctx->get_param_store().count())) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("invalid param idx", K(param_idx), K(ret));
O
oceanbase-admin 已提交
5956
      } else {
W
wangzelin.wzl 已提交
5957 5958 5959
        val = phy_ctx->get_param_store().at(param_idx);
        if (val.is_nop_value()) {
          ret = OB_ERR_NOP_VALUE;
O
obdev 已提交
5960 5961 5962 5963
        } else if (val.is_lob_storage()) {
          if (OB_FAIL(ObTextStringIter::convert_outrow_lob_to_inrow_templob(val, val, NULL, &res_allocator, true))) {
            LOG_WARN("fail to convert to inrow lob", K(ret), K(val));
          }
O
oceanbase-admin 已提交
5964 5965
        }
      }
W
wangzelin.wzl 已提交
5966 5967 5968 5969 5970 5971 5972
    } else if (OB_ISNULL(temp_expr = expr_final_infos_.at(expr_idx).temp_expr_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected null temp expr", K(expr_idx), K(ret));
    } else if (OB_FAIL(temp_expr->eval(exec_ctx, tmp_row, result))) {
      LOG_WARN("failed to eval temp expr", K(ret));
    } else if (result.is_nop_value()) {
      ret = OB_ERR_NOP_VALUE;
O
obdev 已提交
5973 5974 5975 5976
    } else if (result.is_lob_storage()) {
      if (OB_FAIL(ObTextStringIter::convert_outrow_lob_to_inrow_templob(result, val, NULL, &res_allocator, true, true))) {
        LOG_WARN("fail to convert to inrow lob", K(ret), K(result));
      }
W
wangzelin.wzl 已提交
5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024
    } else if (OB_FAIL(ob_write_obj(res_allocator, result, val))) {
      LOG_WARN("failed to write obj", K(result), K(ret));
    }
  }
  return ret;
}

int ObQueryRange::get_result_value_with_rowid(const ObKeyPart &key_part,
                                              ObObj &val,
                                              ObExecContext &exec_ctx,
                                              bool &is_inconsistent_rowid,
                                              ObIAllocator *allocator /* =NULL */ ) const
{
  int ret = OB_SUCCESS;
  int64_t param_idx = OB_INVALID_ID;
  is_inconsistent_rowid = false;

  if (OB_FAIL(get_result_value(val, exec_ctx, allocator))) {
    LOG_WARN("get param value failed", K(ret));
  } else if (!val.is_unknown() && key_part.is_rowid_key_part()) {
    if (val.is_urowid()) {
      uint64_t pk_cnt;
      ObArray<ObObj> pk_vals;
      const ObURowIDData &urowid_data = val.get_urowid();
      if ((urowid_data.is_physical_rowid() && key_part.is_logical_rowid_key_part()) ||
          (!urowid_data.is_physical_rowid() && key_part.is_phy_rowid_key_part())) {
        is_inconsistent_rowid = true;
        val.set_null();
        LOG_TRACE("Occur inconsistent rowid", K(urowid_data), K(key_part.is_rowid_key_part()));
      } else if (urowid_data.is_physical_rowid()) {//not convert, will convert in table scan.
        //do nothing
      } else if (OB_FAIL(urowid_data.get_pk_vals(pk_vals))) {
        LOG_WARN("failed to get pk values", K(ret));
      } else if ((pk_cnt = urowid_data.get_real_pk_count(pk_vals)) <= key_part.rowid_column_idx_) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("invalid key_part", K(ret), K(pk_cnt), K(key_part.rowid_column_idx_));
      } else {
        val = pk_vals.at(key_part.rowid_column_idx_);
      }
    }
  }
  return ret;
}

OB_INLINE int ObQueryRange::gen_simple_get_range(const ObKeyPart &root,
                                                 ObIAllocator &allocator,
                                                 ObExecContext &exec_ctx,
                                                 ObQueryRangeArray &ranges,
6025
                                                 bool &all_single_value_ranges,
W
wangzelin.wzl 已提交
6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067
                                                 const ObDataTypeCastParams &dtc_params) const
{
  int ret = OB_SUCCESS;
  ObObj *start = nullptr;
  ObObj *end = nullptr;
  ObNewRange *range = nullptr;
  bool always_false = false;
  bool always_true = false;
  size_t rowkey_size = sizeof(ObObj) * column_count_ * 2;
  size_t range_size = sizeof(ObNewRange) + rowkey_size;
  void *range_buffer = nullptr;
  bool contain_phy_rowid_key = false;
  if (OB_ISNULL(range_buffer = allocator.alloc(range_size))) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_WARN("allocate memory for ObNewRange failed", K(ret));
  } else {
    range = new(range_buffer) ObNewRange();
    start = reinterpret_cast<ObObj*>(static_cast<char*>(range_buffer) + sizeof(ObNewRange));
    end = start + column_count_;
    //init obj
    for (int64_t i = 0; i < column_count_; ++i) {
      (start + i)->set_min_value();
      (end + i)->set_max_value();
    }
  }
  const ObKeyPart *cur = &root;
  bool b_flag = false;
  for (int64_t i = 0; OB_SUCC(ret) && NULL != cur && !b_flag && i < column_count_; ++i) {
    contain_phy_rowid_key = cur->is_phy_rowid_key_part();
    if (OB_UNLIKELY(cur->normal_keypart_->always_false_)) {
      always_false = true;
    } else {
      ObObj *cur_val = start + i;
      new (cur_val) ObObj(cur->normal_keypart_->start_);
      bool is_inconsistent_rowid = false;
      if (OB_FAIL(get_result_value_with_rowid(*cur, *cur_val, exec_ctx, is_inconsistent_rowid, &allocator))) {
        LOG_WARN("get end param value failed", K(ret));
      } else if (is_inconsistent_rowid) {
        always_false = true;
      } else if (OB_UNLIKELY(cur_val->is_unknown())) {
        //下推的?
        always_true = true;
C
chaser-ch 已提交
6068 6069 6070
      } else if (OB_LIKELY(ObSQLUtils::is_same_type_for_compare(
                             cur_val->get_meta(), cur->pos_.column_type_.get_obj_meta())
                           && !cur_val->get_meta().is_decimal_int())) {
W
wangzelin.wzl 已提交
6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084
        cur_val->set_collation_type(cur->pos_.column_type_.get_collation_type());
        //copy end
        new(end + i) ObObj(*cur_val);
      } else if (OB_LIKELY(cur_val->get_meta().get_type() == ObURowIDType)) {
        new(end + i) ObObj(*cur_val);
      } else if (OB_LIKELY(!cur_val->is_overflow_integer(cur->pos_.column_type_.get_type()))) {
        //fast cast with integer value
        cur_val->set_meta_type(cur->pos_.column_type_);
        new(end + i) ObObj(*cur_val);
      } else if (OB_FAIL(cold_cast_cur_node(cur, allocator, dtc_params, *cur_val, always_false))) {
        LOG_WARN("cold fill cur node failed", K(ret));
      } else if (OB_LIKELY(!always_false)) {
        new(end + i) ObObj(*cur_val);
      }
O
oceanbase-admin 已提交
6085 6086
    }
    if (OB_SUCC(ret) && always_false) {
W
wangzelin.wzl 已提交
6087
      //set whole range max to min
O
oceanbase-admin 已提交
6088 6089 6090 6091 6092 6093 6094
      for (int64_t j = 0; j < column_count_; ++j) {
        (start + j)->set_max_value();
        (end + j)->set_min_value();
      }
      b_flag = true;
    }
    if (OB_SUCC(ret) && always_true) {
W
wangzelin.wzl 已提交
6095
      //set whole range max to min
O
oceanbase-admin 已提交
6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107
      for (int64_t j = 0; j < column_count_; ++j) {
        (start + j)->set_min_value();
        (end + j)->set_max_value();
      }
      b_flag = true;
    }

    if (OB_SUCC(ret) && !b_flag) {
      cur = cur->and_next_;
    }
  }
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
6108 6109 6110 6111 6112 6113
    range->table_id_ = root.id_.table_id_;
    range->start_key_.assign(start, column_count_);
    range->end_key_.assign(end, column_count_);
    if (!always_false && !always_true) {
      range->border_flag_.set_inclusive_start();
      range->border_flag_.set_inclusive_end();
O
oceanbase-admin 已提交
6114
    } else {
W
wangzelin.wzl 已提交
6115 6116 6117 6118 6119 6120
      range->border_flag_.unset_inclusive_start();
      range->border_flag_.unset_inclusive_end();
    }
    range->is_physical_rowid_range_ = contain_phy_rowid_key;
    if (OB_FAIL(ranges.push_back(range))) {
      LOG_WARN("push back range to array failed", K(ret));
6121 6122
    } else if (always_false) {
      all_single_value_ranges = false;
W
wangzelin.wzl 已提交
6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146
    }
  }
  return ret;
}

OB_NOINLINE int ObQueryRange::cold_cast_cur_node(const ObKeyPart *cur,
                                                 ObIAllocator &allocator,
                                                 const ObDataTypeCastParams &dtc_params,
                                                 ObObj &cur_val,
                                                 bool &always_false) const
{
  int ret = OB_SUCCESS;
  const ObObj *dest_val = NULL;
  if (OB_UNLIKELY(cur_val.is_null()) && !cur->is_rowid_key_part() && !cur->null_safe_) {
    always_false = true;
  } else if (!cur_val.is_min_value() && !cur_val.is_max_value()) {
    ObCastCtx cast_ctx(&allocator,
                       &dtc_params,
                       CM_WARN_ON_FAIL,
                       cur->pos_.column_type_.get_collation_type());
    ObExpectType expect_type;
    expect_type.set_type(cur->pos_.column_type_.get_type());
    expect_type.set_collation_type(cur->pos_.column_type_.get_collation_type());
    expect_type.set_type_infos(&cur->pos_.get_enum_set_values());
C
chaser-ch 已提交
6147 6148 6149
    ObAccuracy res_acc;
    if (cur->pos_.column_type_.is_decimal_int()) {
      res_acc = cur->pos_.column_type_.get_accuracy();
O
obdev 已提交
6150 6151 6152 6153 6154 6155 6156 6157
      ObScale in_scale = cur_val.get_scale();
      int32_t in_bytes = cur_val.get_int_bytes();
      ObScale out_scale = res_acc.get_scale();
      int32_t out_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(res_acc.get_precision());
      if (ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes)) {
        // simply get range, using eq const mode
        cast_ctx.cast_mode_ |= CM_CONST_TO_DECIMAL_INT_EQ;
      }
C
chaser-ch 已提交
6158 6159
      cast_ctx.res_accuracy_ = &res_acc;
    }
W
wangzelin.wzl 已提交
6160 6161 6162 6163 6164 6165
    EXPR_CAST_OBJ_V2(expect_type, cur_val, dest_val);
    if (OB_FAIL(ret)) {
      // do nothing
    } else if (OB_ISNULL(dest_val)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("cast failed.", K(ret));
6166 6167 6168 6169
    } else if (ob_is_double_tc(expect_type.get_type())) {
      const_cast<ObObj *>(dest_val)->set_scale(cur->pos_.column_type_.get_accuracy().get_scale());
    }
    if (OB_SUCC(ret)) { // 下面这个比较是目的是检查上面的cast有没有丢失数值的精度
W
wangzelin.wzl 已提交
6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182
      int64_t cmp = 0;
      ObObjType cmp_type = ObMaxType;
      if (OB_FAIL(ObExprResultTypeUtil::get_relational_cmp_type(cmp_type,
                                                                cur_val.get_type(),
                                                                dest_val->get_type()))) {
        LOG_WARN("get compare type failed", K(ret));
      } else if (OB_FAIL(ObRelationalExprOperator::compare_nullsafe(cmp, cur_val, *dest_val,
                                                                    cast_ctx, cmp_type,
                                                                    cur->pos_.column_type_.get_collation_type()))) {
        LOG_WARN("compare obj value failed", K(ret));
      } else if (0 == cmp) {
        cur_val = *dest_val;
        cur_val.set_collation_type(cur->pos_.column_type_.get_collation_type());
O
oceanbase-admin 已提交
6183
      } else {
W
wangzelin.wzl 已提交
6184 6185
        //always false
        always_false = true;
O
oceanbase-admin 已提交
6186 6187 6188 6189 6190 6191
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6192 6193 6194 6195
//generate always true range or always false range.
int ObQueryRange::generate_true_or_false_range(const ObKeyPart *cur,
                                               ObIAllocator &allocator,
                                               ObNewRange *&range) const
O
oceanbase-admin 已提交
6196 6197
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
6198 6199
  ObObj *start = NULL;
  ObObj *end = NULL;
O
oceanbase-admin 已提交
6200 6201 6202
  if (OB_ISNULL(cur)) {
    ret = OB_NOT_INIT;
    LOG_WARN("cur is null", K(ret));
W
wangzelin.wzl 已提交
6203
  } else if (OB_ISNULL(start = static_cast<ObObj *>(allocator.alloc(sizeof(ObObj) * column_count_)))) {
O
oceanbase-admin 已提交
6204 6205
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for start_obj failed", K(ret));
W
wangzelin.wzl 已提交
6206
  } else if(OB_ISNULL(end = static_cast<ObObj *>(allocator.alloc(sizeof(ObObj) * column_count_)))) {
O
oceanbase-admin 已提交
6207 6208 6209
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for end_obj failed", K(ret));
  } else {
W
wangzelin.wzl 已提交
6210 6211
    new(start) ObObj();
    new(end) ObObj();
O
oceanbase-admin 已提交
6212 6213 6214
    if (cur->is_always_false()) {
      start[0].set_max_value();
      end[0].set_min_value();
W
wangzelin.wzl 已提交
6215
    } else { //  always true or whole range
O
oceanbase-admin 已提交
6216 6217 6218
      start[0].set_min_value();
      end[0].set_max_value();
    }
W
wangzelin.wzl 已提交
6219 6220 6221
    for (int i = 1 ; i < column_count_ ; i++) {
      new(start + i) ObObj();
      new(end + i) ObObj();
O
oceanbase-admin 已提交
6222 6223 6224 6225 6226
      start[i] = start[0];
      end[i] = end[0];
    }
  }
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
6227 6228
    if (OB_ISNULL(range =
        static_cast<ObNewRange *>(allocator.alloc(sizeof(ObNewRange))))) {
O
oceanbase-admin 已提交
6229 6230 6231
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_ERROR("alloc memory failed", K(ret));
    } else {
W
wangzelin.wzl 已提交
6232
      new(range) ObNewRange();
O
obdev 已提交
6233
      range->table_id_ = cur->is_in_key() ? cur->in_keypart_->table_id_ : cur->id_.table_id_;
O
oceanbase-admin 已提交
6234 6235 6236 6237 6238 6239 6240 6241 6242 6243
      range->border_flag_.unset_inclusive_start();
      range->border_flag_.unset_inclusive_end();
      range->start_key_.assign(start, column_count_);
      range->end_key_.assign(end, column_count_);
    }
  }
  return ret;
}

// copy existing key parts to range, and fill in the missing key part
W
wangzelin.wzl 已提交
6244 6245 6246 6247
int ObQueryRange::generate_single_range(ObSearchState &search_state,
                                        int64_t column_num,
                                        ObNewRange *&range,
                                        bool &is_get_range) const
O
oceanbase-admin 已提交
6248 6249
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
6250 6251
  ObObj *start = NULL;
  ObObj *end = NULL;
O
obdev 已提交
6252 6253
  if (OB_UNLIKELY(column_num <= 0 || search_state.max_exist_index_ < 0
      || !search_state.start_ || !search_state.end_)) {
O
oceanbase-admin 已提交
6254 6255
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("Wrong argument", K(ret));
W
wangzelin.wzl 已提交
6256
  } else if (OB_ISNULL(start = static_cast<ObObj *>(search_state.allocator_.alloc(sizeof(ObObj) * column_num)))) {
O
oceanbase-admin 已提交
6257 6258
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for start_obj failed", K(ret));
W
wangzelin.wzl 已提交
6259
  } else if(OB_ISNULL(end = static_cast<ObObj *>(search_state.allocator_.alloc(sizeof(ObObj) * column_num)))) {
O
oceanbase-admin 已提交
6260 6261 6262 6263
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for end_obj failed", K(ret));
  } else {
    int64_t max_pred_index = search_state.max_exist_index_;
K
Klawz 已提交
6264
    column_num = search_state.is_phy_rowid_range_ ? 1 : column_num;//physical rowid range just use only one column
O
oceanbase-admin 已提交
6265
    for (int i = 0; OB_SUCC(ret) && i < column_num; i++) {
W
wangzelin.wzl 已提交
6266 6267
      new(start + i) ObObj();
      new(end + i) ObObj();
O
oceanbase-admin 已提交
6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294
      if (i < max_pred_index) {
        // exist key part, deep copy it
        if (OB_FAIL(ob_write_obj(search_state.allocator_, *(search_state.start_ + i), *(start + i)))) {
          LOG_WARN("deep copy start obj failed", K(ret), K(i));
        } else if (OB_FAIL(ob_write_obj(search_state.allocator_, *(search_state.end_ + i), *(end + i)))) {
          LOG_WARN("deep copy end obj failed", K(ret), K(i));
        }
      } else {
        // fill in the missing key part as (min, max)

        // If the start key is included in the range, then we should set
        // min to the rest of the index keys; otherwise, we should set
        // max to the rest of the index keys in order to skip any values
        // in (.. start_key, min:max, min:max ).
        //
        // For example:
        // sql> create table t1(c1 int, c2 int, c3 int, primary key(c1, c2, c3));
        // sql> select * from t1 where c1 > 1 and c1 < 7;
        //
        // The range we get should be (1, max, max) to (7, min, min)
        // and if the condition become c1 >= 1 and c1<= 7, we should get
        // (1, min, min) to (7, max, max) instead.
        //
        // This should be done always with the exception of start_key being
        // min or max, in which case, we should set min to the rest all the
        // time.
        // Same logic applies to the end key as well.
W
wangzelin.wzl 已提交
6295 6296 6297
        if (max_pred_index > 0
            && !(search_state.start_[max_pred_index - 1]).is_min_value()
            && search_state.last_include_start_ == false) {
O
oceanbase-admin 已提交
6298 6299 6300 6301 6302 6303
          start[i].set_max_value();
        } else {
          start[i].set_min_value();
        }

        // See above
W
wangzelin.wzl 已提交
6304 6305 6306
        if (max_pred_index > 0
            && !(search_state.end_[max_pred_index - 1]).is_max_value()
            && search_state.last_include_end_ == false) {
O
oceanbase-admin 已提交
6307 6308 6309 6310 6311 6312
          end[i].set_min_value();
        } else {
          end[i].set_max_value();
        }
      }
    }
O
obdev 已提交
6313 6314 6315 6316 6317 6318 6319 6320
    if (OB_FAIL(ret)) {
    } else if (OB_ISNULL(range = static_cast<ObNewRange *>(search_state.allocator_.alloc(sizeof(ObNewRange))))) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_ERROR("alloc memory failed", K(ret));
    } else {
      new(range) ObNewRange();
      range->table_id_ = search_state.table_id_;
      range->is_physical_rowid_range_ = search_state.is_phy_rowid_range_;
O
oceanbase-admin 已提交
6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332
      if (search_state.max_exist_index_ == column_num && search_state.last_include_start_) {
        range->border_flag_.set_inclusive_start();
      } else {
        range->border_flag_.unset_inclusive_start();
      }
      if (search_state.max_exist_index_ == column_num && search_state.last_include_end_) {
        range->border_flag_.set_inclusive_end();
      } else {
        range->border_flag_.unset_inclusive_end();
      }
      range->start_key_.assign(start, column_num);
      range->end_key_.assign(end, column_num);
W
wangzelin.wzl 已提交
6333 6334 6335
      is_get_range = (range->start_key_ == range->end_key_)
                     && range->border_flag_.inclusive_start()
                     && range->border_flag_.inclusive_end();
O
oceanbase-admin 已提交
6336 6337 6338 6339 6340
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6341 6342 6343 6344
int ObQueryRange::store_range(ObNewRange *range,
                              bool is_get_range,
                              ObSearchState &search_state,
                              ObQueryRangeArray &ranges,
6345
                              bool &all_single_value_ranges)
O
oceanbase-admin 已提交
6346 6347 6348
{
  int ret = OB_SUCCESS;
  bool is_duplicate = false;
6349 6350 6351 6352 6353 6354 6355 6356
  ObRangeWrapper range_wrapper;
  range_wrapper.range_ = range;
  if (OB_HASH_EXIST == (ret = search_state.range_set_.set_refactored(range_wrapper, 0))) {
    is_duplicate = true;
    ret = OB_SUCCESS;
  } else if (OB_UNLIKELY(OB_SUCCESS != ret)) {
    LOG_WARN("failed to set range", K(ret));
  } else { /* OB_SUCCESS */ }
O
oceanbase-admin 已提交
6357 6358 6359
  if (OB_SUCC(ret) && !is_duplicate) {
    if (OB_FAIL(ranges.push_back(range))) {
      LOG_WARN("push back range failed", K(ret));
6360 6361
    } else if(!is_get_range) {
      all_single_value_ranges = false;
O
oceanbase-admin 已提交
6362 6363 6364 6365 6366
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6367 6368 6369
int ObQueryRange::and_first_search(ObSearchState &search_state,
                                   ObKeyPart *cur,
                                   ObQueryRangeArray &ranges,
6370
                                   bool &all_single_value_ranges,
W
wangzelin.wzl 已提交
6371
                                   const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
6372 6373
{
  int ret = OB_SUCCESS;
Z
zs0 已提交
6374 6375
  if (OB_UNLIKELY(THIS_WORKER.check_status())) {
    LOG_WARN("check status fail", K(ret));
W
wangzelin.wzl 已提交
6376 6377
  } else if (OB_ISNULL(search_state.start_) || OB_ISNULL(search_state.end_)
      || OB_ISNULL(search_state.include_start_) || OB_ISNULL(search_state.include_end_)
O
obdev 已提交
6378
      || OB_ISNULL(cur)) {
O
oceanbase-admin 已提交
6379
    ret = OB_INVALID_ARGUMENT;
O
obdev 已提交
6380 6381
    LOG_WARN("invalid argument", K(ret), K_(search_state.start), K_(search_state.end), K(cur));
  } else if (cur->is_in_key()) {
6382
    if (OB_FAIL(and_first_in_key(search_state, cur, ranges, all_single_value_ranges, dtc_params))) {
O
obdev 已提交
6383 6384
      LOG_WARN("failed to and in key range", K(ret));
    }
O
oceanbase-admin 已提交
6385 6386 6387 6388 6389
  } else {
    int copy_depth = search_state.depth_;
    bool copy_produce_range = search_state.produce_range_;

    // 1. generate current key part range, fill missing part as (min, max)
O
obdev 已提交
6390 6391 6392
    int64_t i = cur->pos_.offset_;
    if (!cur->is_always_true() && !cur->is_always_false() && search_state.depth_ < i) {
      for (int64_t j = search_state.depth_; j < i; ++j) {
W
wangzelin.wzl 已提交
6393 6394
        if (lib::is_oracle_mode()) {
          // Oracle 存储层使用 NULL Last
O
obdev 已提交
6395 6396
          search_state.start_[j].set_min_value();
          search_state.end_[j].set_max_value();
O
oceanbase-admin 已提交
6397
        } else {
O
obdev 已提交
6398 6399
          search_state.start_[j].set_min_value();
          search_state.end_[j].set_max_value();
O
oceanbase-admin 已提交
6400
        }
O
obdev 已提交
6401 6402
        search_state.include_start_[j] = false;
        search_state.include_end_[j] = false;
O
oceanbase-admin 已提交
6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423
      }
    }
    if (search_state.max_exist_index_ >= search_state.depth_ + 1) {
      // get the larger scope
      if (search_state.start_[i] > cur->normal_keypart_->start_) {
        search_state.start_[i] = cur->normal_keypart_->start_;
        search_state.include_start_[i] = cur->normal_keypart_->include_start_;
      }
      if (search_state.end_[i] < cur->normal_keypart_->end_) {
        search_state.end_[i] = cur->normal_keypart_->end_;
        search_state.include_end_[i] = cur->normal_keypart_->include_end_;
      }
    } else {
      search_state.start_[i] = cur->normal_keypart_->start_;
      search_state.end_[i] = cur->normal_keypart_->end_;
      search_state.max_exist_index_ = search_state.depth_ + 1;
      search_state.include_start_[i] = cur->normal_keypart_->include_start_;
      search_state.include_end_[i] = cur->normal_keypart_->include_end_;
    }

    // 2. process next and key part
O
obdev 已提交
6424 6425 6426 6427 6428 6429 6430
    bool need_process_and_next = false;
    if (NULL != cur->and_next_ && i >= 0) {
      need_process_and_next = cur->and_next_->is_in_key() ?
                             (i + 1 == cur->and_next_->in_keypart_->get_min_offset()) :
                             (i + 1 == cur->and_next_->pos_.offset_);
    }
    if (need_process_and_next) {
O
oceanbase-admin 已提交
6431 6432 6433 6434 6435 6436
      // current key part is not equal value
      // include_start_/include_end_ is ignored
      if (cur->normal_keypart_->start_ != cur->normal_keypart_->end_) {
        search_state.produce_range_ = false;
      }
      search_state.depth_++;
W
wangzelin.wzl 已提交
6437 6438 6439
      if (OB_FAIL(SMART_CALL(and_first_search(search_state,
                                              cur->and_next_,
                                              ranges,
6440
                                              all_single_value_ranges,
W
wangzelin.wzl 已提交
6441
                                              dtc_params)))) {
O
oceanbase-admin 已提交
6442 6443 6444 6445 6446 6447
      } else {
        search_state.depth_ = copy_depth;
      }
    }

    // 3. to check if need to  output
K
Klawz 已提交
6448
    //copy_produce_range的作用是控制range能不能够输出,不是所有递归到最后都能输出
W
wangzelin.wzl 已提交
6449 6450 6451 6452 6453
    //例如:a>1 and a<=2 and ((b>1 and b < 2) or (b > 4, and b < 5))
    //这个例子不能抽成两段range,只能抽成一段range
    //因为如果抽成两段range->(1, max;2, 2) or (1, max;2, 5)这两段区间是有重叠的
    //如果前缀是一个范围的时候,后缀的范围只能用来确定边界值,所以应该只记录后缀所有区间的总的起始边界和结束边界
    //这个range应该是(1, max; 2, 5)
O
oceanbase-admin 已提交
6454 6455 6456 6457 6458 6459
    if (OB_SUCC(ret)) {
      // several case need to output:
      // that previous key parts are all equal value is necessary,
      // 1. current key part is not equal value;
      // 2. current key part is equal value and and_next_ is NULL,
      // 3. current key part is equal value and and_next_ is not NULL, but consequent key does not exist.
O
obdev 已提交
6460 6461
      bool not_consequent = false;
      if (NULL != cur->and_next_) {
L
Larry955 已提交
6462 6463
        not_consequent = cur->and_next_->is_in_key() ?
                         !is_contain(cur->and_next_->in_keypart_->offsets_, i + 1) :
O
obdev 已提交
6464 6465
                         i + 1 != cur->and_next_->pos_.offset_;
      }
W
wangzelin.wzl 已提交
6466
      if (copy_produce_range
O
obdev 已提交
6467 6468 6469 6470 6471 6472 6473
          && (NULL == cur->and_next_ ||
              cur->normal_keypart_->start_ != cur->normal_keypart_->end_ ||
              not_consequent)) {
        if (OB_FAIL(generate_cur_range(search_state,
                                       copy_depth,
                                       copy_produce_range,
                                       ranges,
6474
                                       all_single_value_ranges,
O
obdev 已提交
6475 6476 6477 6478 6479 6480 6481 6482 6483
                                       cur->is_phy_rowid_key_part()))) {
          LOG_WARN("failed to generate cur range", K(ret));
        }
      }
    }
  }
  if (OB_SUCC(ret) && cur->or_next_ != NULL) {
    // 4. has or item
    if (contain_in_) {
C
chaser-ch 已提交
6484 6485 6486 6487
      if (OB_ISNULL(search_state.valid_offsets_)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("invalid null offsets", K(ret));
      } else if (OB_FAIL(remove_and_next_offset(cur, *search_state.valid_offsets_))) {
O
obdev 已提交
6488 6489 6490 6491 6492 6493 6494
        LOG_WARN("failed to revert offsets", K(ret));
      } else if (OB_FAIL(set_valid_offsets(cur->or_next_, search_state.valid_offsets_))) {
        LOG_WARN("failed to get valid offsets", K(ret));
      }
    }
    cur = cur->or_next_;
    if (OB_SUCC(ret) &&
6495
        OB_FAIL(SMART_CALL(and_first_search(search_state, cur, ranges, all_single_value_ranges, dtc_params)))) {
O
obdev 已提交
6496 6497 6498 6499 6500 6501 6502 6503 6504
      LOG_WARN("failed to do and first search", K(ret));
    }
  }
  return ret;
}

int ObQueryRange::and_first_in_key(ObSearchState &search_state,
                                   ObKeyPart *cur,
                                   ObQueryRangeArray &ranges,
6505
                                   bool &all_single_value_ranges,
O
obdev 已提交
6506 6507 6508
                                   const ObDataTypeCastParams &dtc_params)
{
  int ret = OB_SUCCESS;
C
chaser-ch 已提交
6509 6510 6511 6512 6513
  int64_t max_valid_off = -1;
  if (OB_ISNULL(cur)
      || OB_UNLIKELY(!cur->is_in_key() || OB_ISNULL(search_state.valid_offsets_)
                     || (max_valid_off = get_max_valid_offset(*search_state.valid_offsets_))
                          == -1)) {
O
obdev 已提交
6514 6515 6516 6517 6518 6519 6520 6521
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(cur), K(max_valid_off));
  } else {
    int64_t param_val_cnt = cur->in_keypart_->get_param_val_cnt();
    int64_t valid_off_cnt = cur->in_keypart_->get_valid_offset_cnt(max_valid_off);
    for (int64_t or_depth = 0; OB_SUCC(ret) && or_depth < param_val_cnt; ++or_depth) {
      int copy_depth = search_state.depth_;
      bool copy_produce_range = search_state.produce_range_;
L
Larry955 已提交
6522
      int64_t copy_max_exist_index = search_state.max_exist_index_;
O
obdev 已提交
6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554
      for (int64_t i = 0; OB_SUCC(ret) && i < cur->in_keypart_->in_params_.count(); ++i) {
        const InParamMeta *param_meta = cur->in_keypart_->in_params_.at(i);
        const ObObj &val = param_meta->vals_.at(or_depth);
        int64_t offset = param_meta->pos_.offset_;
        if (offset <= max_valid_off) {
          if (search_state.max_exist_index_ >= search_state.depth_ + 1) {
            // get the larger scope
            if (search_state.start_[offset] > val) {
              search_state.start_[offset] = val;
            }
            if (search_state.end_[offset] < val) {
              search_state.end_[offset] = val;
            }
          } else {
            search_state.start_[offset] = val;
            search_state.end_[offset] = val;
            search_state.max_exist_index_ = search_state.depth_ + 1;
            // the next in param is not existed or not valid, no need to add depth
            if (i < valid_off_cnt - 1) {
              ++search_state.depth_;
            }
          }
          search_state.include_start_[offset] = true;
          search_state.include_end_[offset] = true;
        }
      }
      if (OB_FAIL(ret)) {
      } else if (cur->and_next_ != NULL) {
        ++search_state.depth_;
        if (OB_FAIL(SMART_CALL(and_first_search(search_state,
                                                cur->and_next_,
                                                ranges,
6555
                                                all_single_value_ranges,
O
obdev 已提交
6556 6557
                                                dtc_params)))) {
          LOG_WARN("failed to do and first search", K(ret));
O
oceanbase-admin 已提交
6558 6559 6560 6561
        } else {
          // reset search_state
          search_state.depth_ = copy_depth;
          search_state.produce_range_ = copy_produce_range;
O
obdev 已提交
6562 6563 6564 6565 6566 6567
        }
      } else if (copy_produce_range) {
        if (OB_FAIL(generate_cur_range(search_state,
                                       copy_depth,
                                       copy_produce_range,
                                       ranges,
6568
                                       all_single_value_ranges,
O
obdev 已提交
6569 6570
                                       cur->is_phy_rowid_key_part()))) {
          LOG_WARN("failed to generate cur range", K(ret));
O
oceanbase-admin 已提交
6571 6572 6573
        }
      }
    }
O
obdev 已提交
6574 6575 6576
  }
  return ret;
}
O
oceanbase-admin 已提交
6577

O
obdev 已提交
6578 6579 6580 6581
int ObQueryRange::generate_cur_range(ObSearchState &search_state,
                                     const int64_t copy_depth,
                                     const bool copy_produce_range,
                                     ObQueryRangeArray &ranges,
6582
                                     bool &all_single_value_ranges,
O
obdev 已提交
6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601
                                     const bool is_phy_rowid_range)
{
  int ret = OB_SUCCESS;
  ObNewRange *range = NULL;
  bool is_get_range = false;
  search_state.last_include_start_ = true;
  search_state.last_include_end_ = true;
  search_state.is_phy_rowid_range_ = is_phy_rowid_range;
  if (OB_FAIL(search_state.tailor_final_range(column_count_))) {
    LOG_WARN("tailor final range failed", K(ret));
  } else if (OB_FAIL(generate_single_range(search_state,
                                           column_count_,
                                           range,
                                           is_get_range))) {
    LOG_WARN("Get single range failed", K(ret));
  } else if (OB_FAIL(store_range(range,
                                 is_get_range,
                                 search_state,
                                 ranges,
6602
                                 all_single_value_ranges))) {
O
obdev 已提交
6603 6604 6605 6606 6607 6608 6609
    LOG_WARN("store range failed", K(ret));
  } else {
    /* reset search_state  */
    search_state.depth_ = copy_depth;
    search_state.max_exist_index_ = 0;
    search_state.produce_range_ = copy_produce_range;
    search_state.is_phy_rowid_range_ = false;
O
oceanbase-admin 已提交
6610 6611 6612 6613
  }
  return ret;
}

W
wangzelin.wzl 已提交
6614 6615 6616 6617 6618
int ObQueryRange::get_tablet_ranges(common::ObIAllocator &allocator,
                                    ObExecContext &exec_ctx,
                                    ObQueryRangeArray &ranges,
                                    bool &all_single_value_ranges,
                                    const ObDataTypeCastParams &dtc_params) const
O
oceanbase-admin 已提交
6619 6620 6621
{
  int ret = OB_SUCCESS;
  if (OB_LIKELY(!need_deep_copy())) {
6622
    if (OB_FAIL(direct_get_tablet_ranges(allocator, exec_ctx, ranges, all_single_value_ranges, dtc_params))) {
O
oceanbase-admin 已提交
6623 6624 6625
      LOG_WARN("get tablet ranges without deep copy failed", K(ret));
    }
  } else {
W
wangzelin.wzl 已提交
6626
    //need to deep copy
O
oceanbase-admin 已提交
6627
    ObQueryRange tmp_query_range(allocator);
W
wangzelin.wzl 已提交
6628
    if (OB_FAIL(tmp_query_range.deep_copy(*this, true))) {
O
oceanbase-admin 已提交
6629
      LOG_WARN("deep copy query range failed", K(ret));
W
wangzelin.wzl 已提交
6630
    } else if (OB_FAIL(tmp_query_range.final_extract_query_range(exec_ctx, dtc_params))) {
O
oceanbase-admin 已提交
6631
      LOG_WARN("final extract query range failed", K(ret));
6632
    } else if (OB_FAIL(tmp_query_range.get_tablet_ranges(ranges, all_single_value_ranges, dtc_params))) {
O
oceanbase-admin 已提交
6633 6634 6635 6636 6637 6638
      LOG_WARN("get tablet range with deep copy failed", K(ret));
    }
  }
  return ret;
}

6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663
int ObQueryRange::get_ss_tablet_ranges(common::ObIAllocator &allocator,
                                       ObExecContext &exec_ctx,
                                       ObQueryRangeArray &ss_ranges,
                                       const ObDataTypeCastParams &dtc_params) const
{
  int ret = OB_SUCCESS;
  ss_ranges.reuse();
  const ObKeyPart *ss_head = get_ss_key_part_head();
  if (NULL == ss_head) {
    /* is not skip scan range */
  } else if (OB_UNLIKELY(table_graph_.skip_scan_offset_ < 0
                         || table_graph_.skip_scan_offset_ >= column_count_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected skip scan range", K(ret), K(table_graph_.skip_scan_offset_),
                                           K(column_count_));
  } else if (OB_FAIL(gen_skip_scan_range(allocator, exec_ctx, dtc_params, ss_head,
                                         column_count_ - table_graph_.skip_scan_offset_,
                                         ss_ranges))) {
    LOG_WARN("get skip scan ranges failed", K(ret));
  } else {
    LOG_DEBUG("get skip range success", K(ss_ranges));
  }
  return ret;
}

O
oceanbase-admin 已提交
6664 6665 6666 6667 6668 6669 6670 6671 6672 6673
int ObQueryRange::ObSearchState::tailor_final_range(int64_t column_count)
{
  int ret = OB_SUCCESS;
  bool skip_start = false;
  bool skip_end = false;
  if (OB_ISNULL(include_start_) || OB_ISNULL(include_end_) || OB_ISNULL(start_) || OB_ISNULL(end_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("search state is not init", K_(include_start), K_(include_end), K_(start), K_(end));
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < max_exist_index_ && !is_empty_range_; ++i) {
W
wangzelin.wzl 已提交
6674
    //确定最后的边界并裁剪掉一些无用的range节点
O
oceanbase-admin 已提交
6675 6676 6677
    if (!skip_start) {
      last_include_start_ = (last_include_start_ && include_start_[i]);
      if (!start_[i].is_min_value() && !include_start_[i]) {
W
wangzelin.wzl 已提交
6678
        //左边界是有效值并且是开区间,表示这个有效值永远取不到,那么后缀的值也没有意义,取MAX
O
oceanbase-admin 已提交
6679 6680 6681 6682 6683 6684 6685 6686 6687 6688
        for (int64_t j = i + 1; OB_SUCC(ret) && j < column_count; ++j) {
          start_[j].set_max_value();
        }
        last_include_start_ = false;
        skip_start = true;
      }
    }
    if (!skip_end) {
      last_include_end_ = (last_include_end_ && include_end_[i]);
      if (!end_[i].is_max_value() && !include_end_[i]) {
W
wangzelin.wzl 已提交
6689
        //右边界是有效值并且是开区间,表示这个有效值永远取不到,所以后缀的值没有意义,取MIN
O
oceanbase-admin 已提交
6690 6691 6692 6693 6694 6695 6696 6697
        for (int64_t j = i + 1; OB_SUCC(ret) && j < column_count; ++j) {
          end_[j].set_min_value();
        }
        last_include_end_ = false;
        skip_end = true;
      }
    }
    if (start_[i].is_min_value() && end_[i].is_max_value()) {
W
wangzelin.wzl 已提交
6698
      //当前节点是(MIN, MAX),后缀没有实际意义裁剪掉
O
oceanbase-admin 已提交
6699 6700 6701 6702 6703 6704 6705 6706 6707
      last_include_start_ = false;
      last_include_end_ = false;
      max_exist_index_ = i + 1;
      break;
    }
  }
  return ret;
}

O
obdev 已提交
6708 6709
int ObQueryRange::ObSearchState::init_search_state(int64_t column_count,
                                                   bool init_as_full_range,
C
chaser-ch 已提交
6710 6711
                                                   uint64_t table_id,
                                                   bool contain_in_expr)
6712 6713 6714 6715
{
  int ret = OB_SUCCESS;
  void *start_ptr = NULL;
  void *end_ptr = NULL;
C
chaser-ch 已提交
6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726
  if (contain_in_expr) {
    void *buf = allocator_.alloc(sizeof(ObSqlBitSet<>));
    if (OB_ISNULL(buf)) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_WARN("failed to allocate memory", K(ret));
    } else {
      valid_offsets_ = new(buf) ObSqlBitSet<>();
    }
  }
  if (OB_FAIL(ret)) { // do nothing
  } else if (OB_UNLIKELY(column_count <= 0)) {
6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected column count when init search state", K(ret), K(column_count));
  } else if (OB_ISNULL(start_ptr = allocator_.alloc(sizeof(ObObj) * column_count))) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for start_ptr failed", K(ret));
  } else if(OB_ISNULL(end_ptr = allocator_.alloc(sizeof(ObObj) * column_count))) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for end_ptr failed", K(ret));
  } else if (OB_ISNULL(include_start_ = static_cast<bool*>(allocator_.alloc(sizeof(bool) * column_count)))) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for search state start failed", K(ret));
  } else if (OB_ISNULL(include_end_ = static_cast<bool*>(allocator_.alloc(sizeof(bool) * column_count)))) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc memory for search state end failed", K(ret));
  } else {
    start_ = new(start_ptr) ObObj[column_count];
    end_ = new(end_ptr) ObObj[column_count];
O
obdev 已提交
6744
    table_id_ = table_id;
6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769
    if (init_as_full_range) {
      max_exist_index_ = column_count;
      last_include_start_ = true;
      last_include_end_ = true;
      for (int64_t i = 0; i < column_count; ++i) {
        start_[i].set_min_value();
        end_[i].set_max_value();
        include_start_[i] = false;
        include_end_[i] = false;
      }
    } else {
      max_exist_index_ = 0;
      last_include_start_ = false;
      last_include_end_ = false;
      for (int64_t i = 0; i < column_count; ++i) {
        start_[i].set_min_value();
        end_[i].set_max_value();
        include_start_[i] = false;
        include_end_[i] = false;
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6770
// @notice 调用这个接口之前必须调用need_deep_copy()来判断是否可以不用拷贝就进行final extract
6771 6772 6773 6774 6775
int ObQueryRange::direct_get_tablet_ranges(ObIAllocator &allocator,
                                          ObExecContext &exec_ctx,
                                          ObQueryRangeArray &ranges,
                                          bool &all_single_value_ranges,
                                          const ObDataTypeCastParams &dtc_params) const
O
oceanbase-admin 已提交
6776 6777
{
  int ret = OB_SUCCESS;
O
obdev 已提交
6778 6779
  if (OB_UNLIKELY(table_graph_.key_part_head_->is_always_true() ||
                  table_graph_.key_part_head_->is_always_false())) {
W
wangzelin.wzl 已提交
6780 6781 6782 6783 6784 6785
    ObNewRange *range = NULL;
    bool is_get_range = false;
    if (OB_FAIL(generate_true_or_false_range(table_graph_.key_part_head_, allocator, range))) {
     LOG_WARN("get true_or_false range failed", K(ret));
    } else if (OB_FAIL(ranges.push_back(range))) {
     LOG_WARN("push back range failed", K(ret));
6786 6787 6788
    } else if (!is_get_range) {
      all_single_value_ranges = false;
    }
W
wangzelin.wzl 已提交
6789 6790 6791 6792 6793
  } else if (OB_LIKELY(table_graph_.is_precise_get_)) {
    if (OB_FAIL(gen_simple_get_range(*table_graph_.key_part_head_,
                                     allocator,
                                     exec_ctx,
                                     ranges,
6794
                                     all_single_value_ranges,
W
wangzelin.wzl 已提交
6795 6796
                                     dtc_params))) {
      LOG_WARN("gen simple get range failed", K(ret));
O
oceanbase-admin 已提交
6797
    }
W
wangzelin.wzl 已提交
6798
  } else {
6799
    OZ(gen_simple_scan_range(allocator, exec_ctx, ranges, all_single_value_ranges, dtc_params));
O
oceanbase-admin 已提交
6800
  }
L
Larry955 已提交
6801
  LOG_TRACE("get range success", K(ret), K(table_graph_.is_precise_get_), K(ranges));
O
oceanbase-admin 已提交
6802 6803 6804
  return ret;
}

6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834
// for standard range, check is skip scan range
const ObKeyPart *ObQueryRange::get_ss_key_part_head() const
{
  const ObKeyPart *ss_head = NULL;
  if (is_ss_range()) {
    const ObKeyPart *cur = table_graph_.key_part_head_;
    while (NULL != cur && cur->pos_.offset_ < table_graph_.skip_scan_offset_) {
      cur = cur->and_next_;
    }
    if (NULL != cur && cur->pos_.offset_ == table_graph_.skip_scan_offset_) {
      ss_head = cur;
    }
  }
  return ss_head;
}

OB_NOINLINE int ObQueryRange::gen_skip_scan_range(ObIAllocator &allocator,
                                                  ObExecContext &exec_ctx,
                                                  const ObDataTypeCastParams &dtc_params,
                                                  const ObKeyPart *ss_root,
                                                  int64_t post_column_count,
                                                  ObQueryRangeArray &ss_ranges) const
{
  int ret = OB_SUCCESS;
  bool is_get_range = false;
  ObSearchState search_state(allocator);
  ObNewRange *ss_range = NULL;
  if (OB_ISNULL(ss_root) || OB_UNLIKELY(1 > post_column_count)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected skip scan range", K(ret), K(ss_root), K(post_column_count));
C
chaser-ch 已提交
6835 6836
  } else if (OB_FAIL(search_state.init_search_state(
               post_column_count, true, table_graph_.key_part_head_->id_.table_id_, contain_in_))) {
6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858
    LOG_WARN("failed to init postfix search state", K(ret));
  }
  for (const ObKeyPart *cur = ss_root; OB_SUCC(ret) && NULL != cur && !search_state.is_empty_range_;
       cur = cur->and_next_) {
    if (OB_FAIL(get_single_key_value(cur, exec_ctx, search_state, dtc_params,
                                     table_graph_.skip_scan_offset_))) {
      LOG_WARN("get single key value failed", K(ret));
    }
  }

  if (OB_FAIL(ret)) {
  } else if(OB_FAIL(search_state.tailor_final_range(post_column_count))) {
    LOG_WARN("tailor final range failed", K(ret));
  } else if (OB_FAIL(generate_single_range(search_state, post_column_count,
                                           ss_range, is_get_range))) {
    LOG_WARN("generate single range failed", K(ret));
  } else if (OB_FAIL(ss_ranges.push_back(ss_range))) {
    LOG_WARN("push back range to array failed", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
6859 6860 6861
OB_NOINLINE int ObQueryRange::gen_simple_scan_range(ObIAllocator &allocator,
                                                    ObExecContext &exec_ctx,
                                                    ObQueryRangeArray &ranges,
6862
                                                    bool &all_single_value_ranges,
W
wangzelin.wzl 已提交
6863
                                                    const ObDataTypeCastParams &dtc_params) const
O
oceanbase-admin 已提交
6864 6865
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
6866
  ObSearchState search_state(allocator);
C
chaser-ch 已提交
6867 6868
  if (OB_FAIL(search_state.init_search_state(
        column_count_, true, table_graph_.key_part_head_->id_.table_id_, contain_in_))) {
6869
    LOG_WARN("failed to init search state", K(ret));
W
wangzelin.wzl 已提交
6870 6871 6872 6873 6874 6875 6876 6877
  }
  for (ObKeyPart *cur = table_graph_.key_part_head_;
       OB_SUCC(ret) && NULL != cur && !search_state.is_empty_range_;
       cur = cur->and_next_) {
    if (OB_FAIL(get_single_key_value(cur, exec_ctx, search_state, dtc_params))) {
      LOG_WARN("get single key value failed", K(ret));
    }
  }
O
obdev 已提交
6878 6879 6880 6881
  ObNewRange *range = NULL;
  bool is_get_range = false;
  if (OB_FAIL(ret)) {
  } else if (OB_FAIL(search_state.tailor_final_range(column_count_))) {
W
wangzelin.wzl 已提交
6882
    LOG_WARN("tailor final range failed", K(ret));
O
obdev 已提交
6883 6884 6885 6886 6887
  } else if (OB_FAIL(generate_single_range(search_state, column_count_,
                                           range, is_get_range))) {
    LOG_WARN("generate single range failed", K(ret));
  } else if (OB_FAIL(ranges.push_back(range))) {
    LOG_WARN("push back range to array failed", K(ret));
6888 6889
  } else if (!is_get_range) {
    all_single_value_ranges = false;
O
oceanbase-admin 已提交
6890
  }
6891
  LOG_TRACE("get range success", K(ret), K(table_graph_.is_precise_get_), K(ranges));
O
oceanbase-admin 已提交
6892 6893 6894
  return ret;
}

C
chaser-ch 已提交
6895
#define CAST_VALUE_TYPE(expect_type, column_type, start, include_start, end, include_end, acc) \
W
wangzelin.wzl 已提交
6896 6897 6898 6899
if (OB_SUCC(ret) ) { \
  ObObj cast_obj; \
  const ObObj *dest_val = NULL; \
  if (!start.is_min_value() && !start.is_max_value() && !start.is_unknown() \
C
chaser-ch 已提交
6900
    && (!ObSQLUtils::is_same_type_for_compare(start.get_meta(), column_type.get_obj_meta()) || start.is_decimal_int())) { \
6901
    ObCastMode cm = CM_WARN_ON_FAIL;\
O
obdev 已提交
6902 6903 6904 6905 6906 6907 6908 6909
    if (ObDecimalIntType == expect_type.get_type() && start.is_decimal_int()) {\
      int32_t in_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(column_type.get_accuracy().get_precision());\
      ObScale in_scale = column_type.get_accuracy().get_scale();\
      int32_t out_bytes = start.get_int_bytes();\
      ObScale out_scale = start.get_scale();\
      if (ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes)) {\
        cm |= ObRelationalExprOperator::get_const_cast_mode(T_OP_GE, true);\
      }\
6910 6911
    }\
    ObCastCtx cast_ctx(&allocator, &dtc_params, cm, expect_type.get_collation_type()); \
C
chaser-ch 已提交
6912 6913 6914
    if (ObDecimalIntType == expect_type.get_type()) {\
      cast_ctx.res_accuracy_ = &acc;\
    }\
W
wangzelin.wzl 已提交
6915 6916 6917 6918 6919 6920 6921
    ObObj &tmp_start = start; \
    EXPR_CAST_OBJ_V2(expect_type, tmp_start, dest_val); \
    if (OB_FAIL(ret)) { \
      LOG_WARN("cast obj to dest type failed", K(ret), K(start), K(expect_type)); \
    } else if (OB_ISNULL(dest_val)) { \
      ret = OB_ERR_UNEXPECTED; \
      LOG_WARN("dest_val is null.", K(ret)); \
6922 6923 6924 6925
    } else if (ob_is_double_tc(expect_type.get_type())) { \
      const_cast<ObObj *>(dest_val)->set_scale(column_type.get_accuracy().get_scale()); \
    } \
    if (OB_SUCC(ret)) { /* 下面这个比较是目的是检查上面的cast有没有丢失数值的精度 */ \
W
wangzelin.wzl 已提交
6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937
      int64_t cmp = 0; \
      ObObjType cmp_type = ObMaxType; \
      if (OB_FAIL(ObExprResultTypeUtil::get_relational_cmp_type(cmp_type, start.get_type(), dest_val->get_type()))) { \
        LOG_WARN("get compare type failed", K(ret)); \
      } else if (OB_FAIL(ObRelationalExprOperator::compare_nullsafe(cmp, start, *dest_val, cast_ctx, \
                                                                    cmp_type, column_type.get_collation_type()))) { \
        LOG_WARN("compare obj value failed", K(ret)); \
      } else if (cmp < 0) { \
        /* 转换后精度发生变化,结果更大,需要将原来的开区间变为闭区间 */ \
        include_start = true; \
      } else if (cmp > 0) { \
        include_start = false; \
6938 6939 6940 6941 6942 6943
      } else if (is_oracle_mode() && \
                 ((column_type.get_type() == ObCharType && start.get_type() == ObVarcharType) || \
                  (column_type.get_type() == ObNCharType && start.get_type() == ObNVarchar2Type))) { \
        /* when char compare with varchar, same string may need return due to padding blank. \
           e.g. c1(char(3)) > '1'(varchar(1)) will return '1  ' */ \
        include_start = true; \
W
wangzelin.wzl 已提交
6944 6945 6946 6947 6948 6949
      } \
      start = *dest_val; \
    } \
  } \
  if (OB_SUCC(ret)) { \
    if (!end.is_min_value() && !end.is_max_value() && !end.is_unknown() \
C
chaser-ch 已提交
6950
      && (!ObSQLUtils::is_same_type_for_compare(end.get_meta(), column_type.get_obj_meta()) || end.is_decimal_int())) { \
6951
      ObCastMode cm = CM_WARN_ON_FAIL;\
O
obdev 已提交
6952 6953 6954 6955 6956 6957 6958 6959
      if (ObDecimalIntType == expect_type.get_type() && end.is_decimal_int()) {\
        int32_t in_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(column_type.get_accuracy().get_precision());\
        ObScale in_scale = column_type.get_accuracy().get_scale();\
        int32_t out_bytes = start.get_int_bytes();\
        ObScale out_scale = start.get_scale();\
        if (ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes)) {\
          cm |= ObRelationalExprOperator::get_const_cast_mode(T_OP_LE, true);\
        }\
6960 6961
      }\
      ObCastCtx cast_ctx(&allocator, &dtc_params, cm, expect_type.get_collation_type()); \
C
chaser-ch 已提交
6962 6963 6964 6965 6966
      if (ObDecimalIntType == expect_type.get_type()) {\
        cast_ctx.res_accuracy_ = &acc;\
      }\
      ObObj &tmp_end = end; \
      EXPR_CAST_OBJ_V2(expect_type, tmp_end, dest_val); \
W
wangzelin.wzl 已提交
6967 6968
      if (OB_FAIL(ret)) { \
        LOG_WARN("cast obj to dest type failed", K(ret), K(end), K(expect_type)); \
6969 6970 6971 6972
      } else if (ob_is_double_tc(expect_type.get_type())) { \
        const_cast<ObObj *>(dest_val)->set_scale(column_type.get_accuracy().get_scale()); \
      } \
      if (OB_SUCC(ret)) { \
W
wangzelin.wzl 已提交
6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998
        int64_t cmp = 0; \
        ObObjType cmp_type = ObMaxType; \
        if (OB_FAIL(ObExprResultTypeUtil::get_relational_cmp_type(cmp_type, end.get_type(), dest_val->get_type()))) { \
          LOG_WARN("get compare type failed", K(ret)); \
        } else if (OB_FAIL(ObRelationalExprOperator::compare_nullsafe(cmp, end, *dest_val, cast_ctx, \
                                                                      cmp_type, column_type.get_collation_type()))) { \
          LOG_WARN("compare obj value failed", K(ret)); \
        } else if (cmp > 0) { \
          /* 转换后精度发生变化,结果变为更小,需要将原来的开区间变为闭区间 */ \
          include_end = true; \
        } else if (cmp < 0) { \
          include_end = false; \
        } \
        end = *dest_val; \
      } \
    } \
  } \
  if (OB_SUCC(ret)) { \
    start.set_collation_type(expect_type.get_collation_type()); \
    end.set_collation_type(expect_type.get_collation_type()); \
  } \
}

inline int ObQueryRange::get_single_key_value(const ObKeyPart *key,
                                              ObExecContext &exec_ctx,
                                              ObSearchState &search_state,
6999 7000
                                              const ObDataTypeCastParams &dtc_params,
                                              int64_t skip_offset /* default 0 */ ) const
O
oceanbase-admin 已提交
7001 7002
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
7003 7004
  for (const ObKeyPart *cur = key;
       OB_SUCC(ret) && NULL != cur && cur->is_normal_key() && !search_state.is_empty_range_;
O
oceanbase-admin 已提交
7005 7006 7007 7008 7009 7010 7011 7012 7013
       cur = cur->item_next_) {
    ObObj start = cur->normal_keypart_->start_;
    ObObj end = cur->normal_keypart_->end_;
    bool include_start = cur->normal_keypart_->include_start_;
    bool include_end = cur->normal_keypart_->include_end_;
    ObExpectType expect_type;
    expect_type.set_type(cur->pos_.column_type_.get_type());
    expect_type.set_collation_type(cur->pos_.column_type_.get_collation_type());
    expect_type.set_type_infos(&cur->pos_.get_enum_set_values());
W
wangzelin.wzl 已提交
7014
    ObIAllocator &allocator = search_state.allocator_;
O
oceanbase-admin 已提交
7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025
    if (cur->normal_keypart_->always_false_) {
      start.set_max_value();
      end.set_min_value();
      include_start = false;
      include_end = false;
    } else if (cur->normal_keypart_->always_true_) {
      start.set_min_value();
      end.set_max_value();
      include_start = false;
      include_end = false;
    } else {
W
wangzelin.wzl 已提交
7026
      bool is_inconsistent_rowid = false;
O
oceanbase-admin 已提交
7027
      if (start.is_unknown()) {
W
wangzelin.wzl 已提交
7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038
        if (OB_FAIL(get_result_value_with_rowid(*cur, start, exec_ctx, is_inconsistent_rowid, &search_state.allocator_))) {
          LOG_WARN("get result value failed", K(ret));
        } else if (is_inconsistent_rowid) {
          if (key->is_phy_rowid_key_part()) {//phy rowid query get a logical rowid, can't parse.
            start.set_min_value();
          } else {//logical rowid query get a phy rowid, can't parse.
            start.set_max_value();
            end.set_min_value();
            include_start = false;
            include_end = false;
          }
O
oceanbase-admin 已提交
7039 7040 7041 7042 7043 7044
        } else if (!cur->null_safe_ && start.is_null()) {
          start.set_max_value();
          end.set_min_value();
          include_start = false;
          include_end = false;
        } else if (start.is_unknown()) {
W
wangzelin.wzl 已提交
7045
          //条件下推的?的range是[min, max]
O
oceanbase-admin 已提交
7046 7047 7048 7049 7050 7051 7052
          start.set_min_value();
          include_start = false;
          end.set_max_value();
          include_end = false;
        }
      }
      if (OB_SUCC(ret) && end.is_unknown()) {
W
wangzelin.wzl 已提交
7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063
        if (OB_FAIL(get_result_value_with_rowid(*cur, end, exec_ctx, is_inconsistent_rowid, &search_state.allocator_))) {
          LOG_WARN("get result value failed", K(ret));
        } else if (is_inconsistent_rowid) {
          if (key->is_phy_rowid_key_part()) {//phy rowid query get a logical rowid, can't parse.
            start.set_max_value();
            end.set_min_value();
            include_start = false;
            include_end = false;
          } else {//logical rowid query get a phy rowid, can't parse.
            end.set_max_value();
          }
O
oceanbase-admin 已提交
7064 7065 7066 7067 7068 7069
        } else if (!cur->null_safe_ && end.is_null()) {
          start.set_max_value();
          end.set_min_value();
          include_start = false;
          include_end = false;
        } else if (end.is_unknown()) {
W
wangzelin.wzl 已提交
7070
          //条件下推的?的range是[min, max]
O
oceanbase-admin 已提交
7071 7072 7073 7074 7075 7076 7077
          start.set_min_value();
          include_start = false;
          end.set_max_value();
          include_end = false;
        }
      }
    }
W
wangzelin.wzl 已提交
7078 7079 7080 7081
    //为了性能,减少函数跳转,所以用宏来代替
    if (OB_SUCC(ret) && cur->is_phy_rowid_key_part()) {
      //physical rowid range no need cast, it's will be transformed in table scan phase.
    } else {
C
chaser-ch 已提交
7082 7083
      ObAccuracy acc(cur->pos_.column_type_.get_accuracy());
      CAST_VALUE_TYPE(expect_type, cur->pos_.column_type_, start, include_start, end, include_end, acc);
W
wangzelin.wzl 已提交
7084
    }
O
oceanbase-admin 已提交
7085
    if (OB_SUCC(ret)) {
7086
      search_state.depth_ = static_cast<int>(cur->pos_.offset_ - skip_offset);
W
wangzelin.wzl 已提交
7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097
      if (search_state.is_phy_rowid_range_ != cur->is_phy_rowid_key_part()) {
        if (search_state.is_phy_rowid_range_) {
          //do nothing
        } else {//just only see the physical rowid key part.
          search_state.start_[search_state.depth_]= start;
          search_state.end_[search_state.depth_] = end;
          search_state.include_start_[search_state.depth_] = include_start;
          search_state.include_end_[search_state.depth_] = include_end;
          search_state.is_phy_rowid_range_ = true;
        }
      } else if (OB_FAIL(search_state.intersect(start, include_start, end, include_end))) {
O
oceanbase-admin 已提交
7098 7099 7100 7101 7102 7103 7104 7105
        LOG_WARN("intersect current key part failed", K(ret));
      }
    }
  }
  return ret;
}
#undef CAST_VALUE_TYPE

W
wangzelin.wzl 已提交
7106
OB_NOINLINE int ObQueryRange::get_tablet_ranges(ObQueryRangeArray &ranges,
7107
                                                bool &all_single_value_ranges,
W
wangzelin.wzl 已提交
7108
                                                const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
7109 7110
{
  int ret = OB_SUCCESS;
Z
zs0 已提交
7111 7112
  int64_t last_mem_usage = allocator_.total();
  int64_t query_range_mem_usage = 0;
O
oceanbase-admin 已提交
7113 7114
  ObSearchState search_state(allocator_);
  ranges.reset();
7115
  all_single_value_ranges = true;
O
obdev 已提交
7116 7117
  ObKeyPart *head_key = NULL;
  if (OB_UNLIKELY(CAN_READ != state_)) {
O
oceanbase-admin 已提交
7118 7119
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("Can not get query range before final extraction", K(ret), K_(state));
O
obdev 已提交
7120
  } else if (OB_ISNULL(head_key = table_graph_.key_part_head_)) {
O
oceanbase-admin 已提交
7121
    ret = OB_NOT_INIT;
O
obdev 已提交
7122
    LOG_WARN("table_graph_.key_part_head_ is not inited.", K(ret), K(head_key));
O
oceanbase-admin 已提交
7123
  } else {
O
obdev 已提交
7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134
    bool is_whole_range = head_key->is_in_key() ?
                          head_key->in_keypart_->get_min_offset() > 0 :
                          head_key->pos_.offset_ != 0;
    if (is_whole_range) {
      SQL_REWRITE_LOG(DEBUG, "get table range from index failed, whole range will returned", K(ret));
      ObNewRange *range = NULL;
      bool is_get_range = false;
      if (OB_FAIL(generate_true_or_false_range(head_key, allocator_, range))) {
        LOG_WARN("generate true_or_false range failed", K(ret));
      } else if (OB_FAIL(ranges.push_back(range))) {
        LOG_WARN("push back range failed", K(ret));
7135 7136 7137
      } else if (!is_get_range) {
        all_single_value_ranges = false;
      }
C
chaser-ch 已提交
7138 7139 7140 7141
    } else if (OB_FAIL(search_state.init_search_state(
                 column_count_, false,
                 head_key->is_in_key() ? head_key->in_keypart_->table_id_ : head_key->id_.table_id_,
                 contain_in_))) {
O
obdev 已提交
7142 7143 7144 7145 7146
      LOG_WARN("failed to init search state", K(ret));
    } else {
      search_state.depth_ = 0;
      search_state.produce_range_ = true;
      search_state.is_equal_range_ = table_graph_.is_equal_range_;
7147
      if (OB_FAIL(search_state.range_set_.create(range_size_ == 0 ? RANGE_BUCKET_SIZE : range_size_))) {
O
obdev 已提交
7148 7149 7150 7151 7152 7153 7154
        LOG_WARN("create range set bucket failed", K(ret));
      } else if (contain_in_ &&
                 OB_FAIL(set_valid_offsets(head_key, search_state.valid_offsets_))) {
        LOG_WARN("failed to get max valid offset", K(ret));
      } else if (OB_FAIL(SMART_CALL(and_first_search(search_state,
                                                     head_key,
                                                     ranges,
7155
                                                     all_single_value_ranges,
O
obdev 已提交
7156 7157
                                                     dtc_params)))) {
        LOG_WARN("and first search failed", K(ret));
7158
      } else {
O
obdev 已提交
7159 7160
        search_state.range_set_.destroy();
      }
O
oceanbase-admin 已提交
7161 7162 7163
    }
  }
  if (OB_SUCC(ret)) {
Z
zs0 已提交
7164
    query_range_mem_usage = allocator_.total() - last_mem_usage;
O
obdev 已提交
7165 7166 7167 7168 7169 7170 7171
    LOG_TRACE("[SQL MEM USAGE] query range memory usage",
        K(query_range_mem_usage), K(last_mem_usage));
    LOG_TRACE("get range success", K(ranges), K_(range_size));
  }
  return ret;
}

C
chaser-ch 已提交
7172
int ObQueryRange::set_valid_offsets(const ObKeyPart *cur, ObSqlBitSet<> *offsets) const
O
obdev 已提交
7173 7174
{
  int ret = OB_SUCCESS;
C
chaser-ch 已提交
7175
  if (OB_ISNULL(cur) || OB_ISNULL(offsets)) {
O
obdev 已提交
7176
    ret = OB_ERR_UNEXPECTED;
C
chaser-ch 已提交
7177
    LOG_WARN("get unexpected null", K(ret), K(cur), K(offsets));
O
obdev 已提交
7178 7179 7180 7181 7182 7183
  } else {
    for (const ObKeyPart *cur_and = cur; OB_SUCC(ret) && cur_and != NULL; cur_and = cur_and->and_next_) {
      if (cur_and->is_always_true() || cur_and->is_always_false()) {
        // do nothing
      } else if (cur_and->is_in_key()) {
        for (int64_t i = 0; OB_SUCC(ret) && i < cur_and->in_keypart_->offsets_.count(); ++i) {
C
chaser-ch 已提交
7184
          ret = offsets->add_member(cur_and->in_keypart_->offsets_.at(i));
O
obdev 已提交
7185
        }
C
chaser-ch 已提交
7186
      } else if (OB_FAIL(offsets->add_member(cur_and->pos_.offset_))) {
O
obdev 已提交
7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245
        LOG_WARN("failed to add offsets", K(ret));
      }
    }
  }
  return ret;
}

int64_t ObQueryRange::get_max_valid_offset(const ObSqlBitSet<> &offsets) const
{
  int64_t max_valid_off = -1;
  for (int64_t i = 0; i < offsets.num_members(); ++i) {
    if (!offsets.has_member(i)) {
      break;
    } else {
      max_valid_off = i;
    }
  }
  return max_valid_off;
}

int ObQueryRange::remove_cur_offset(const ObKeyPart *cur, ObSqlBitSet<> &offsets) const
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(cur)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else if (cur->is_always_true() || cur->is_always_false()) {
    // do nothing
  } else if (cur->is_in_key()) {
    for (int64_t i = 0; OB_SUCC(ret) && i < cur->in_keypart_->offsets_.count(); ++i) {
      if (OB_FAIL(offsets.del_member(cur->in_keypart_->offsets_.at(i)))) {
        LOG_WARN("failed to delete offset", K(ret));
      }
    }
  } else if (OB_FAIL(offsets.del_member(cur->pos_.offset_))) {
    LOG_WARN("failed to delete offset", K(ret));
  }
  return ret;
}

int ObQueryRange::remove_and_next_offset(ObKeyPart *cur, ObSqlBitSet<> &offsets) const
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(cur)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret));
  } else {
    for (ObKeyPart *and_next = cur; OB_SUCC(ret) && and_next != NULL; and_next = and_next->and_next_) {
      if (and_next->is_always_true() || and_next->is_always_false()) {
        // do nothing
      } else if (and_next->is_in_key()) {
        for (int64_t i = 0; OB_SUCC(ret) && i < and_next->in_keypart_->offsets_.count(); ++i) {
          if (OB_FAIL(offsets.del_member(and_next->in_keypart_->offsets_.at(i)))) {
            LOG_WARN("failed to delete offset", K(ret));
          }
        }
      } else if (OB_FAIL(offsets.del_member(and_next->pos_.offset_))) {
        LOG_WARN("failed to delete offset", K(ret));
      }
O
oceanbase-admin 已提交
7246 7247 7248 7249 7250
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
7251
int ObQueryRange::alloc_empty_key_part(ObKeyPart  *&out_key_part)
O
oceanbase-admin 已提交
7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269
{
  int ret = OB_SUCCESS;
  out_key_part = NULL;
  if (OB_ISNULL(out_key_part = create_new_key_part())) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc ObKeyPart failed", K(ret));
  } else if (OB_FAIL(out_key_part->create_normal_key())) {
    LOG_WARN("create normal key failed", K(ret));
  } else {
    out_key_part->normal_keypart_->start_.set_max_value();
    out_key_part->normal_keypart_->end_.set_min_value();
    out_key_part->normal_keypart_->always_false_ = true;
    out_key_part->normal_keypart_->include_start_ = false;
    out_key_part->normal_keypart_->include_end_ = false;
  }
  return ret;
}

W
wangzelin.wzl 已提交
7270
int ObQueryRange::alloc_full_key_part(ObKeyPart  *&out_key_part)
O
oceanbase-admin 已提交
7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288
{
  int ret = OB_SUCCESS;
  out_key_part = NULL;
  if (OB_ISNULL(out_key_part = create_new_key_part())) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("alloc ObKeyPart failed", K(ret));
  } else if (OB_FAIL(out_key_part->create_normal_key())) {
    LOG_WARN("create normal key failed", K(ret));
  } else {
    out_key_part->normal_keypart_->start_.set_min_value();
    out_key_part->normal_keypart_->end_.set_max_value();
    out_key_part->normal_keypart_->always_true_ = true;
    out_key_part->normal_keypart_->include_start_ = false;
    out_key_part->normal_keypart_->include_end_ = false;
  }
  return ret;
}

W
wangzelin.wzl 已提交
7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301
#define FINAL_EXTRACT(graph) \
  if (OB_SUCC(ret)) { \
    or_array.clear(); \
    if (!or_array.add_last(graph)) { \
      ret = OB_ERR_UNEXPECTED;  \
      LOG_WARN("Add query graph to list failed", K(ret));  \
    } else if (OB_FAIL(or_range_graph(or_array, &exec_ctx, graph, dtc_params))) { \
      LOG_WARN("Do OR of range graph failed", K(ret));  \
    } \
  }

OB_NOINLINE int ObQueryRange::final_extract_query_range(ObExecContext &exec_ctx,
                                                        const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
7302 7303
{
  int ret = OB_SUCCESS;
L
Larry955 已提交
7304 7305 7306
  SQL_REWRITE_LOG(TRACE, "final extract query range", KPC(table_graph_.key_part_head_),
                                                      K(table_graph_.is_equal_range_),
                                                      K(contain_in_), K(contain_row_));
O
oceanbase-admin 已提交
7307 7308 7309 7310 7311
  if (state_ == NEED_PREPARE_PARAMS && NULL != table_graph_.key_part_head_) {
    ObKeyPartList or_array;
    // find all key part path and do OR option
    bool has_scan_key = false;
    if (table_graph_.is_equal_range_) {
W
wangzelin.wzl 已提交
7312 7313
      if (OB_FAIL(definite_in_range_graph(exec_ctx, table_graph_.key_part_head_,
                                                     has_scan_key, dtc_params))) {
O
oceanbase-admin 已提交
7314 7315
        LOG_WARN("definite in range graph failed", K(ret));
      } else if (has_scan_key) {
W
wangzelin.wzl 已提交
7316
        //包含范围性的节点,所以需要做or合并
O
oceanbase-admin 已提交
7317 7318 7319 7320
        table_graph_.is_equal_range_ = false;
        FINAL_EXTRACT(table_graph_.key_part_head_);
      }
    } else {
O
obdev 已提交
7321
      FINAL_EXTRACT(table_graph_.key_part_head_);
O
oceanbase-admin 已提交
7322
    }
7323
    if (OB_SUCC(ret)) {
O
oceanbase-admin 已提交
7324 7325 7326 7327 7328 7329 7330
      state_ = CAN_READ;
    }
  }
  return ret;
}
#undef FINAL_EXTRACT

L
Larry955 已提交
7331 7332 7333
int ObQueryRange::replace_unknown_value(ObKeyPart *root, ObExecContext &exec_ctx,
                                        const ObDataTypeCastParams &dtc_params,
                                        bool &is_bound_modified)
O
oceanbase-admin 已提交
7334 7335
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
7336
  bool is_inconsistent_rowid = false;
O
oceanbase-admin 已提交
7337 7338 7339
  if (OB_ISNULL(root)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("root=null ", K(ret));
O
obdev 已提交
7340
  } else if (root->is_normal_key()) {
O
oceanbase-admin 已提交
7341
    if (root->normal_keypart_->start_.is_unknown()) {
W
wangzelin.wzl 已提交
7342 7343 7344 7345 7346 7347 7348 7349 7350
      if (OB_FAIL(get_result_value_with_rowid(*root, root->normal_keypart_->start_, exec_ctx, is_inconsistent_rowid))) {
        LOG_WARN("get result value failed", K(ret));
      } else if (is_inconsistent_rowid) {
        if (root->is_phy_rowid_key_part()) {//phy rowid query get a logical rowid, can't parse.
          root->normal_keypart_->start_.set_min_value();
        } else {//logical rowid query get a phy rowid, can't parse.
          root->normal_keypart_->always_false_ = true;
        }
      } else if (!root->null_safe_ &&
O
obdev 已提交
7351
                 !root->is_phy_rowid_key_part_ &&
W
wangzelin.wzl 已提交
7352
                 root->normal_keypart_->start_.is_null()) {
O
oceanbase-admin 已提交
7353 7354
        root->normal_keypart_->always_false_ = true;
      } else if (root->normal_keypart_->start_.is_unknown()) {
W
wangzelin.wzl 已提交
7355
        //条件下推的?,range为[min, max]
O
oceanbase-admin 已提交
7356 7357 7358 7359 7360
        root->normal_keypart_->start_.set_min_value();
        root->normal_keypart_->include_start_ = false;
      }
    }
    if (OB_SUCC(ret) && root->normal_keypart_->end_.is_unknown()) {
W
wangzelin.wzl 已提交
7361 7362 7363 7364 7365 7366 7367 7368 7369
      if (OB_FAIL(get_result_value_with_rowid(*root, root->normal_keypart_->end_, exec_ctx, is_inconsistent_rowid))) {
        LOG_WARN("get result value failed", K(ret));
      } else if (is_inconsistent_rowid) {
        if (root->is_phy_rowid_key_part()) {//phy rowid query get a logical rowid, can't parse.
          root->normal_keypart_->always_false_ = true;
        } else {//logical rowid query get a phy rowid, can't parse.
          root->normal_keypart_->end_.set_max_value();
        }
      } else if (!root->null_safe_ &&
O
obdev 已提交
7370
                 !root->is_phy_rowid_key_part_ &&
W
wangzelin.wzl 已提交
7371
                 root->normal_keypart_->end_.is_null()) {
O
oceanbase-admin 已提交
7372 7373
        root->normal_keypart_->always_false_ = true;
      } else if (root->normal_keypart_->end_.is_unknown()) {
W
wangzelin.wzl 已提交
7374
        //条件下推的?,range为[min, max]
O
oceanbase-admin 已提交
7375 7376 7377 7378 7379 7380 7381 7382 7383 7384
        root->normal_keypart_->end_.set_max_value();
        root->normal_keypart_->include_end_ = false;
      }
    }
    if (OB_SUCC(ret) && root->normal_keypart_->always_false_) {
      root->normal_keypart_->start_.set_max_value();
      root->normal_keypart_->end_.set_min_value();
      root->normal_keypart_->include_start_ = false;
      root->normal_keypart_->include_end_ = false;
    }
O
obdev 已提交
7385 7386 7387 7388 7389 7390 7391 7392 7393 7394
  } else if (root->is_geo_key()) {
    if (OB_FAIL(get_result_value_with_rowid(*root, root->geo_keypart_->wkb_, exec_ctx, is_inconsistent_rowid))) {
      LOG_WARN("get param wkb value failed", K(ret));
    } else if (OB_FAIL(get_result_value_with_rowid(*root, root->geo_keypart_->distance_, exec_ctx, is_inconsistent_rowid))) {
      LOG_WARN("get param distance value failed", K(ret));
    } else if (OB_FAIL(get_geo_range(root->geo_keypart_->wkb_,
                                     root->geo_keypart_->geo_type_,
                                     root))) {
      LOG_WARN("get geo range failed", K(ret));
    }
O
obdev 已提交
7395
  } else if (root->is_like_key()) {
W
wangzelin.wzl 已提交
7396 7397 7398 7399 7400 7401 7402 7403
    if (OB_FAIL(get_result_value_with_rowid(*root, root->like_keypart_->pattern_, exec_ctx, is_inconsistent_rowid))) {
      LOG_WARN("get result value failed", K(ret));
    } else if (OB_FAIL(get_result_value_with_rowid(*root, root->like_keypart_->escape_, exec_ctx, is_inconsistent_rowid))) {
      LOG_WARN("get result value failed", K(ret));
    } else if (OB_FAIL(get_like_range(root->like_keypart_->pattern_,
                                      root->like_keypart_->escape_,
                                      *root,
                                      dtc_params))) {
O
oceanbase-admin 已提交
7404 7405
      LOG_WARN("get like range failed", K(ret));
    }
O
obdev 已提交
7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449
  } else if (root->is_in_key()) {
    ObSEArray<int64_t, 16> invalid_param_idx;
    ObSEArray<int64_t, 16> invalid_val_idx;
    int64_t i = OB_INVALID_INDEX;
    for (i = 0; OB_SUCC(ret) && i < root->in_keypart_->in_params_.count(); ++i) {
      InParamMeta *cur_param = root->in_keypart_->in_params_.at(i);
      for (int64_t j = 0; OB_SUCC(ret) && j < cur_param->vals_.count(); ++j) {
        ObObj &val = cur_param->vals_.at(j);
        if (OB_FAIL(get_result_value(val, exec_ctx, &allocator_))) {
          LOG_WARN("get param value failed", K(ret));
        } else if (val.is_unknown()) {
          // ? that pushdown to in expr, should be set to (min:max)
          ret = invalid_param_idx.push_back(i);
          break;
        } else if (val.is_null() || val.is_ext()) {
          ret = add_var_to_array_no_dup(invalid_val_idx, j);
        } else if (root->rowid_column_idx_ != OB_INVALID_ID) {
          // never reach here
        }
        int64_t cmp = 0;
        if (OB_FAIL(ret)) {
        } else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params,
                                                     allocator_,
                                                     cur_param->pos_,
                                                     val,
                                                     cmp))) {
          LOG_WARN("failed to try cast value type", K(ret));
        } else if (cmp == 0) {
          val.set_collation_type(cur_param->pos_.column_type_.get_collation_type());
        } else {
          ret = add_var_to_array_no_dup(invalid_val_idx, j);
        }
      }
    }
    if (OB_SUCC(ret)) {
      root->in_keypart_->contain_questionmark_ = false;
      if (OB_FAIL(root->remove_in_params(invalid_param_idx, true))) {
        LOG_WARN("failed to remove in param", K(ret));
      } else if (OB_FAIL(root->remove_in_params_vals(invalid_val_idx))) {
        LOG_WARN("failed to remove in param vals", K(ret));
      } else if (OB_FAIL(root->formalize_keypart(contain_row_))) {
        LOG_WARN("failed to adjust param", K(ret));
      }
    }
O
oceanbase-admin 已提交
7450
  }
W
wangzelin.wzl 已提交
7451
  if (OB_SUCC(ret)) {
O
obdev 已提交
7452
    if (root->is_phy_rowid_key_part() || root->is_in_key()) {
W
wangzelin.wzl 已提交
7453
      ////physical rowid no need cast, it's will be transformed in table scan phase.
L
Larry955 已提交
7454
    } else if (OB_FAIL(root->cast_value_type(dtc_params, contain_row_, is_bound_modified))) {
W
wangzelin.wzl 已提交
7455 7456
      LOG_WARN("cast value type failed", K(ret));
    }
O
oceanbase-admin 已提交
7457 7458 7459 7460
  }
  return ret;
}

W
wangzelin.wzl 已提交
7461 7462 7463 7464
int ObQueryRange::get_like_range(const ObObj &pattern,
                                 const ObObj &escape,
                                 ObKeyPart &out_key_part,
                                 const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
7465 7466 7467 7468 7469 7470
{
  int ret = OB_SUCCESS;
  ObString pattern_str;
  ObString escape_str;
  ObObj start;
  ObObj end;
W
wangzelin.wzl 已提交
7471 7472
  void *min_str_buf = NULL;
  void *max_str_buf = NULL;
O
oceanbase-admin 已提交
7473 7474 7475 7476 7477 7478
  int32_t col_len = out_key_part.pos_.column_type_.get_accuracy().get_length();
  ObCollationType cs_type = out_key_part.pos_.column_type_.get_collation_type();
  size_t min_str_len = 0;
  size_t max_str_len = 0;
  ObObj pattern_buf_obj;
  ObObj escape_buf_obj;
W
wangzelin.wzl 已提交
7479
  const ObObj *pattern_val = NULL;
O
oceanbase-admin 已提交
7480
  // const ObObj *escape_val = NULL;
W
wangzelin.wzl 已提交
7481
  //like expr抽取后转化成normal key
O
oceanbase-admin 已提交
7482 7483 7484
  if (OB_FAIL(out_key_part.create_normal_key())) {
    LOG_WARN("create normal key failed", K(ret));
  } else if (pattern.is_null()) {
W
wangzelin.wzl 已提交
7485
    //a like null return empty range
O
oceanbase-admin 已提交
7486 7487 7488 7489 7490 7491
    out_key_part.normal_keypart_->start_.set_max_value();
    out_key_part.normal_keypart_->end_.set_min_value();
    out_key_part.normal_keypart_->include_start_ = false;
    out_key_part.normal_keypart_->include_end_ = false;
    out_key_part.normal_keypart_->always_false_ = true;
    out_key_part.normal_keypart_->always_true_ = false;
W
wangzelin.wzl 已提交
7492 7493 7494 7495
  } else if (!pattern.is_string_type()
             || (!escape.is_string_type() && !escape.is_null())
             || col_len <= 0) {
    //1 like 1 return whole range
O
oceanbase-admin 已提交
7496 7497 7498 7499 7500 7501
    out_key_part.normal_keypart_->start_.set_min_value();
    out_key_part.normal_keypart_->end_.set_max_value();
    out_key_part.normal_keypart_->include_start_ = false;
    out_key_part.normal_keypart_->include_end_ = false;
    out_key_part.normal_keypart_->always_false_ = false;
    out_key_part.normal_keypart_->always_true_ = true;
W
wangzelin.wzl 已提交
7502 7503
  } else if (OB_FAIL(cast_like_obj_if_needed(pattern, pattern_buf_obj, pattern_val,
                                             out_key_part, dtc_params))) {
O
oceanbase-admin 已提交
7504 7505 7506 7507 7508 7509
    LOG_WARN("failed to cast like obj if needed", K(ret));
  } else if (OB_FAIL(pattern_val->get_string(pattern_str))) {
    LOG_WARN("get varchar failed", K(ret), K(pattern));
  } else {
    int64_t mbmaxlen = 1;
    ObString escape_val;
W
wangzelin.wzl 已提交
7510
    if (escape.is_null()) {  //如果escape是null,则给默认的'\\'
O
oceanbase-admin 已提交
7511 7512 7513 7514
      escape_str.assign_ptr("\\", 1);
    } else if (ObCharset::is_cs_nonascii(escape.get_collation_type())) {
      if (OB_FAIL(escape.get_string(escape_val))) {
        LOG_WARN("failed to get escape string", K(escape), K(ret));
W
wangzelin.wzl 已提交
7515 7516 7517
      } else if (OB_FAIL(ObCharset::charset_convert(allocator_, escape_val,
                                     escape.get_collation_type(),
                                     CS_TYPE_UTF8MB4_GENERAL_CI, escape_str, true))) {
O
oceanbase-admin 已提交
7518 7519 7520 7521
        LOG_WARN("failed to do charset convert", K(ret), K(escape_val));
      }
    } else if (OB_FAIL(escape.get_string(escape_str))) {
      LOG_WARN("failed to get escape string", K(escape), K(ret));
O
obdev 已提交
7522 7523
    } else if (escape_str.empty()) {
      escape_str.assign_ptr("\\", 1);
W
wangzelin.wzl 已提交
7524
    } else { /* do nothing */ }
O
oceanbase-admin 已提交
7525 7526 7527 7528 7529 7530 7531
    if (OB_FAIL(ret)) {
      // do nothing;
    } else if (OB_FAIL(ObCharset::get_mbmaxlen_by_coll(cs_type, mbmaxlen))) {
      LOG_WARN("fail to get mbmaxlen", K(ret), K(cs_type), K(pattern), K(escape));
    } else if (OB_ISNULL(escape_str.ptr())) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("Escape str should not be NULL", K(ret));
S
sdc 已提交
7532
    } else if (OB_UNLIKELY(1 > escape_str.length())) {
O
oceanbase-admin 已提交
7533 7534 7535
      ret = OB_INVALID_ARGUMENT;
      LOG_WARN("failed to check escape length", K(escape_str), K(escape_str.length()));
      LOG_USER_ERROR(OB_INVALID_ARGUMENT, "ESCAPE");
W
wangzelin.wzl 已提交
7536
    } else { }
O
oceanbase-admin 已提交
7537 7538

    if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
7539
      //convert character counts to len in bytes
O
oceanbase-admin 已提交
7540 7541 7542 7543 7544 7545 7546 7547 7548 7549
      col_len = static_cast<int32_t>(col_len * mbmaxlen);
      min_str_len = col_len;
      max_str_len = col_len;
      if (OB_ISNULL(min_str_buf = allocator_.alloc(min_str_len))) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_ERROR("alloc memory failed", K(min_str_len));
      } else if (OB_ISNULL(max_str_buf = allocator_.alloc(max_str_len))) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_ERROR("alloc memory failed", K(max_str_len));
      } else if (escape_str.length() > 1 || OB_FAIL(ObCharset::like_range(cs_type,
W
wangzelin.wzl 已提交
7550 7551 7552 7553 7554 7555 7556
                                               pattern_str,
                                               *(escape_str.ptr()),
                                               static_cast<char*>(min_str_buf),
                                               &min_str_len,
                                               static_cast<char*>(max_str_buf),
                                               &max_str_len))) {
        //set whole range
O
oceanbase-admin 已提交
7557 7558 7559 7560 7561 7562 7563 7564
        out_key_part.normal_keypart_->start_.set_min_value();
        out_key_part.normal_keypart_->end_.set_max_value();
        out_key_part.normal_keypart_->include_start_ = false;
        out_key_part.normal_keypart_->include_end_ = false;
        out_key_part.normal_keypart_->always_false_ = false;
        out_key_part.normal_keypart_->always_true_ = true;
        ret = OB_SUCCESS;
      } else {
W
wangzelin.wzl 已提交
7565 7566
        ObObj &start = out_key_part.normal_keypart_->start_;
        ObObj &end = out_key_part.normal_keypart_->end_;
O
oceanbase-admin 已提交
7567 7568
        start.set_collation_type(out_key_part.pos_.column_type_.get_collation_type());
        start.set_string(out_key_part.pos_.column_type_.get_type(),
W
wangzelin.wzl 已提交
7569
                         static_cast<char*>(min_str_buf), static_cast<int32_t>(min_str_len));
O
oceanbase-admin 已提交
7570 7571
        end.set_collation_type(out_key_part.pos_.column_type_.get_collation_type());
        end.set_string(out_key_part.pos_.column_type_.get_type(),
W
wangzelin.wzl 已提交
7572
                       static_cast<char*>(max_str_buf), static_cast<int32_t>(max_str_len));
O
oceanbase-admin 已提交
7573 7574 7575 7576 7577 7578
        out_key_part.normal_keypart_->include_start_ = true;
        out_key_part.normal_keypart_->include_end_ = true;
        out_key_part.normal_keypart_->always_false_ = false;
        out_key_part.normal_keypart_->always_true_ = false;

        /// check if is precise
W
wangzelin.wzl 已提交
7579 7580 7581 7582 7583 7584
        if (NULL != query_range_ctx_) {
          query_range_ctx_->cur_expr_is_precise_ =
                                            ObQueryRange::check_like_range_precise(pattern_str,
                                                              static_cast<char *>(max_str_buf),
                                                             max_str_len, *(escape_str.ptr()));
        }
O
oceanbase-admin 已提交
7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598
      }
      if (NULL != min_str_buf) {
        allocator_.free(min_str_buf);
        min_str_buf = NULL;
      }
      if (NULL != max_str_buf) {
        allocator_.free(max_str_buf);
        max_str_buf = NULL;
      }
    }
  }
  return ret;
}

K
Klawz 已提交
7599
// General term: if one or more same key parts with OR relation have same and_next_,
O
oceanbase-admin 已提交
7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622
//                        we call them general term(GT)
// E.g.
//       A and B, A is GT
//       A and (B1 or B2) and C, (B1 or B2) is GT.
//       A and (((B1 or B2) and C1) or (B3 and c2)) and D,
//       (((B1 or B2) and C1) or (B3 and c2)) is not GT.
//
// Our query range graph must abide by following rules:
// 1. on key part is pointed to by more than one key parts, except they are GT.
// 2. a key part can only point to the first member of a GT.
//
// So, we do not generate following graph:
//       A--B1--C1--D
//             |
//             B2(points to D too)
// but generate
//       A--B1--C1--D1
//             |
//             B2--D2
//       (key part D1 is equal to D2, but has different storage)
// '--', means and_next_;
// '|', means or_next_;

W
wangzelin.wzl 已提交
7623 7624


O
oceanbase-admin 已提交
7625 7626
// Out of usage, ObKeyPart is free by key_part_store_

W
wangzelin.wzl 已提交
7627

O
oceanbase-admin 已提交
7628 7629
// maybe use later

W
wangzelin.wzl 已提交
7630
//void ObQueryRange::free_range_graph(ObKeyPart *&graph)
O
oceanbase-admin 已提交
7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651
//{
//  ObKeyPart *next_gt = NULL;
//  for (ObKeyPart *cur_gt = graph; cur_gt != NULL; cur_gt = next_gt) {
//    next_gt = cur_gt->general_or_next();
//    free_range_graph(cur_gt->and_next_);
//    ObKeyPart *next_or = NULL;
//    for (ObKeyPart *cur_or = cur_gt;
//         cur_or != NULL && cur_or->and_next_ == cur_gt->and_next_;
//         cur_or = next_or) {
//      next_or = cur_or->or_next_;
//      ObKeyPart *next_item = NULL;
//      for (ObKeyPart *item = cur_or->item_next_; item != NULL; item = next_item) {
//        next_item = item->item_next_;
//        ObKeyPart::free(item);
//      }
//      ObKeyPart::free(cur_or);
//    }
//  }
//  graph = NULL;
//}

W
wangzelin.wzl 已提交
7652
ObKeyPart *ObQueryRange::create_new_key_part()
O
oceanbase-admin 已提交
7653
{
W
wangzelin.wzl 已提交
7654 7655
  void *ptr = NULL;
  ObKeyPart *key_part = NULL;
O
obdev 已提交
7656
  if (OB_NOT_NULL(ptr = allocator_.alloc(sizeof(ObKeyPart)))) {
W
wangzelin.wzl 已提交
7657
    key_part = new(ptr) ObKeyPart(allocator_);
O
obdev 已提交
7658
    if (OB_UNLIKELY(OB_SUCCESS != key_part_store_.store_obj(key_part))) {
O
oceanbase-admin 已提交
7659 7660
      key_part->~ObKeyPart();
      key_part = NULL;
7661
      LOG_WARN_RET(OB_ERR_UNEXPECTED, "Store ObKeyPart failed");
O
oceanbase-admin 已提交
7662 7663 7664 7665 7666 7667 7668
    }
  }
  return key_part;
}

// Deep copy this key part node only, not include any item in XXX_next_ list

W
wangzelin.wzl 已提交
7669
ObKeyPart *ObQueryRange::deep_copy_key_part(ObKeyPart *key_part)
O
oceanbase-admin 已提交
7670 7671
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
7672
  ObKeyPart *new_key_part = NULL;
O
oceanbase-admin 已提交
7673 7674 7675 7676
  if (key_part) {
    if (OB_ISNULL(new_key_part = create_new_key_part())) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_ERROR("Get new key part failed", K(ret));
O
obdev 已提交
7677
    } else if (OB_FAIL(new_key_part->deep_node_copy(*key_part))) {
O
oceanbase-admin 已提交
7678 7679 7680 7681 7682
      LOG_WARN("Copy key part node failed", K(ret));
    } else {
      // do nothing
    }
  }
O
obdev 已提交
7683 7684 7685 7686 7687 7688
  if (OB_FAIL(ret)) {
    new_key_part = NULL;
  }
  return new_key_part;
}

7689
int ObQueryRange::deserialize_range_graph(ObKeyPart *&cur,
O
obdev 已提交
7690 7691 7692 7693 7694
                                          const char *buf,
                                          int64_t data_len,
                                          int64_t &pos)
{
  int ret = OB_SUCCESS;
7695
  ObKeyPart *pre_key = NULL;
O
obdev 已提交
7696 7697 7698
  bool has_and_next = false;
  bool has_or_next = false;
  bool encode_and_next = false;
7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709
  do {
    ObKeyPart *and_next = NULL;
    ObKeyPart *cur_part = NULL;
    OB_UNIS_DECODE(has_and_next);
    OB_UNIS_DECODE(has_or_next);
    if (OB_SUCC(ret) && has_and_next) {
      OB_UNIS_DECODE(encode_and_next);
      if (OB_SUCC(ret) && encode_and_next) {
        if (OB_FAIL(SMART_CALL(deserialize_range_graph(and_next, buf, data_len, pos)))) {
          LOG_WARN("deserialize and_next_ child graph failed", K(ret));
        }
O
obdev 已提交
7710 7711
      }
    }
7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725
    if (OB_SUCC(ret) && OB_FAIL(SMART_CALL(deserialize_cur_keypart(cur_part, buf, data_len, pos)))) {
      LOG_WARN("deserialize current key part failed", K(ret));
    }
    //build and_next_ child grap and pre_key with current key part
    if (OB_SUCC(ret)) {
      if (encode_and_next) {
        cur_part->and_next_ = and_next;
      } else if (has_and_next) {
        if (OB_ISNULL(pre_key)) {
          ret = OB_INVALID_ARGUMENT;
          LOG_WARN("pre_key is null.", K(ret));
        } else {
          cur_part->and_next_ = pre_key->and_next_;
        }
O
obdev 已提交
7726
      } else {
7727 7728 7729 7730 7731 7732
        // do nothing
      }
      if (pre_key) {
        pre_key->or_next_ = cur_part;
      } else {
        cur = cur_part;
O
obdev 已提交
7733 7734
      }
    }
7735 7736 7737

    if (OB_SUCC(ret) && has_or_next) {
      pre_key = cur_part;
O
obdev 已提交
7738
    }
7739
  } while(OB_SUCC(ret) && has_or_next);
O
obdev 已提交
7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759
  return ret;
}

int ObQueryRange::deserialize_cur_keypart(ObKeyPart *&cur, const char *buf, int64_t data_len, int64_t &pos)
{
  int ret = OB_SUCCESS;
  bool has_item_next = false;
  if (OB_ISNULL(cur = create_new_key_part())) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    LOG_ERROR("create new key part failed", K(ret));
  } else {
    OB_UNIS_DECODE(*cur);
    OB_UNIS_DECODE(has_item_next);
    if (OB_SUCC(ret) && has_item_next) {
      if (OB_FAIL(SMART_CALL(deserialize_cur_keypart(cur->item_next_, buf, data_len, pos)))) {
        LOG_WARN("deserialize item next failed", K(ret));
      }
    }
  }
  return ret;
O
oceanbase-admin 已提交
7760 7761
}

W
wangzelin.wzl 已提交
7762 7763 7764 7765
int ObQueryRange::serialize_range_graph(const ObKeyPart *cur,
                                        char *buf,
                                        int64_t buf_len,
                                        int64_t &pos) const
O
oceanbase-admin 已提交
7766 7767
{
  int ret = OB_SUCCESS;
7768 7769 7770 7771
  const ObKeyPart *pre_and_next = NULL;
  for (const ObKeyPart *cur_part = cur; OB_SUCC(ret) && cur_part != NULL; cur_part = cur_part->or_next_) {
    bool has_and_next = cur_part->and_next_ ? true : false;
    bool has_or_next = cur_part->or_next_ ? true : false;
O
oceanbase-admin 已提交
7772 7773 7774 7775
    bool encode_and_next = false;
    OB_UNIS_ENCODE(has_and_next);
    OB_UNIS_ENCODE(has_or_next);
    if (OB_SUCC(ret) && has_and_next) {
7776
      encode_and_next = cur_part->and_next_ == pre_and_next ? false : true;
O
oceanbase-admin 已提交
7777
      OB_UNIS_ENCODE(encode_and_next);
O
obdev 已提交
7778 7779
    }
    if (OB_SUCC(ret) && encode_and_next) {
7780
      if (OB_FAIL(SMART_CALL(serialize_range_graph(cur_part->and_next_, buf, buf_len, pos)))) {
O
obdev 已提交
7781
        LOG_WARN("serialize and_next_ child graph failed", K(ret));
O
oceanbase-admin 已提交
7782 7783
      }
    }
7784
    if (OB_SUCC((ret)) && OB_FAIL(serialize_cur_keypart(*cur_part, buf, buf_len, pos))) {
O
oceanbase-admin 已提交
7785 7786 7787
      LOG_WARN("serialize current key part failed", K(ret));
    }
    if (OB_SUCC(ret) && has_or_next) {
7788
      pre_and_next = cur_part->and_next_;
O
oceanbase-admin 已提交
7789 7790 7791 7792 7793
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
7794
int ObQueryRange::serialize_cur_keypart(const ObKeyPart &cur, char *buf, int64_t buf_len, int64_t &pos) const
O
oceanbase-admin 已提交
7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815
{
  int ret = OB_SUCCESS;
  bool has_item_next = (cur.item_next_ != NULL);
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to do stack overflow check", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack overflow", K(ret));
  } else {
    OB_UNIS_ENCODE(cur);
    OB_UNIS_ENCODE(has_item_next);
    if (OB_SUCC(ret) && has_item_next) {
      if (OB_FAIL(SMART_CALL(serialize_cur_keypart(*cur.item_next_, buf, buf_len, pos)))) {
        LOG_WARN("serialize cur keypart failed", K(ret));
      }
    }
  }
  return ret;
}

O
obdev 已提交
7816 7817
int ObQueryRange::get_range_graph_serialize_size(const ObKeyPart *cur,
                                                 int64_t &all_size) const
O
oceanbase-admin 已提交
7818 7819 7820
{
  int ret = OB_SUCCESS;
  int64_t len = 0;
7821 7822 7823 7824
  const ObKeyPart *pre_and_next = NULL;
  for (const ObKeyPart *cur_part = cur; OB_SUCC(ret) && cur_part != NULL; cur_part = cur_part->or_next_) {
    bool has_and_next = cur_part->and_next_ ? true : false;
    bool has_or_next = cur_part->or_next_ ? true : false;
O
oceanbase-admin 已提交
7825 7826 7827
    bool encode_and_next = false;
    OB_UNIS_ADD_LEN(has_and_next);
    OB_UNIS_ADD_LEN(has_or_next);
7828

O
oceanbase-admin 已提交
7829
    if (has_and_next) {
7830
      encode_and_next = cur_part->and_next_ == pre_and_next ? false : true;
O
oceanbase-admin 已提交
7831
      OB_UNIS_ADD_LEN(encode_and_next);
O
obdev 已提交
7832
      if (encode_and_next &&
7833
          OB_FAIL(SMART_CALL(get_range_graph_serialize_size(cur_part->and_next_, all_size)))) {
O
obdev 已提交
7834
        LOG_WARN("failed to get and_next serialize size", K(ret));
O
oceanbase-admin 已提交
7835 7836
      }
    }
7837

O
obdev 已提交
7838 7839
    if (OB_SUCC(ret)) {
      all_size += len;
7840
      if (OB_FAIL(SMART_CALL(get_cur_keypart_serialize_size(*cur_part, all_size)))) {
O
obdev 已提交
7841 7842
        LOG_WARN("failed to get cur serialize size", K(ret));
      }
O
oceanbase-admin 已提交
7843
    }
7844 7845 7846
    if (OB_SUCC(ret) && has_or_next) {
      pre_and_next = cur_part->and_next_;
    }
O
oceanbase-admin 已提交
7847
  }
O
obdev 已提交
7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863
  return ret;
}

int ObQueryRange::get_cur_keypart_serialize_size(const ObKeyPart &cur, int64_t &all_size) const
{
  int ret = OB_SUCCESS;
  int64_t len = 0;
  bool has_item_next = (cur.item_next_ != NULL);
  OB_UNIS_ADD_LEN(cur);
  OB_UNIS_ADD_LEN(has_item_next);
  all_size += len;
  if (has_item_next &&
      OB_FAIL(SMART_CALL(get_cur_keypart_serialize_size(*cur.item_next_, all_size)))) {
    LOG_WARN("failed to get cur key serialize size", K(ret));
  }
  return ret;
O
oceanbase-admin 已提交
7864 7865
}

W
wangzelin.wzl 已提交
7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880
int ObQueryRange::serialize_expr_final_info(char *buf, int64_t buf_len, int64_t &pos) const
{
  int ret = OB_SUCCESS;
  OB_UNIS_ENCODE(expr_final_infos_.count());
  for (int64_t i = 0; OB_SUCC(ret) && i < expr_final_infos_.count(); ++i) {
    OB_UNIS_ENCODE(expr_final_infos_.at(i).flags_);
    if (expr_final_infos_.at(i).is_param_) {
      OB_UNIS_ENCODE(expr_final_infos_.at(i).param_idx_);
    } else if (expr_final_infos_.at(i).expr_exists_) {
      OB_UNIS_ENCODE(*expr_final_infos_.at(i).temp_expr_);
    }
  }
  return ret;
}

O
obdev 已提交
7881
int64_t ObQueryRange::get_expr_final_info_serialize_size() const
O
obdev 已提交
7882 7883
{
  int ret = OB_SUCCESS;
O
obdev 已提交
7884 7885 7886 7887 7888 7889 7890 7891 7892
  int64_t len = 0;
  OB_UNIS_ADD_LEN(expr_final_infos_.count());
  for (int64_t i = 0; i < expr_final_infos_.count(); ++i) {
    OB_UNIS_ADD_LEN(expr_final_infos_.at(i).flags_);
    if (expr_final_infos_.at(i).is_param_) {
      OB_UNIS_ADD_LEN(expr_final_infos_.at(i).param_idx_);
    } else if (expr_final_infos_.at(i).expr_exists_) {
      OB_UNIS_ADD_LEN(*expr_final_infos_.at(i).temp_expr_);
    }
O
obdev 已提交
7893
  }
O
obdev 已提交
7894
  return len;
O
obdev 已提交
7895 7896
}

W
wangzelin.wzl 已提交
7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929
int ObQueryRange::deserialize_expr_final_info(const char *buf, int64_t data_len, int64_t &pos)
{
  int ret = OB_SUCCESS;
  int64_t final_expr_count = 0;
  expr_final_infos_.reset();
  OB_UNIS_DECODE(final_expr_count);
  if (OB_SUCC(ret)) {
    if (OB_FAIL(expr_final_infos_.prepare_allocate(final_expr_count))) {
      LOG_WARN("failed to init array", K(ret));
    }
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < final_expr_count; ++i) {
    OB_UNIS_DECODE(expr_final_infos_.at(i).flags_);
    if (expr_final_infos_.at(i).is_param_) {
      OB_UNIS_DECODE(expr_final_infos_.at(i).param_idx_);
    } else if (expr_final_infos_.at(i).expr_exists_) {
      ObTempExpr *temp_expr = NULL;
      char *mem = static_cast<char *>(allocator_.alloc(sizeof(ObTempExpr)));
      if (OB_ISNULL(mem)) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_ERROR("alloc temp expr failed", K(ret));
      } else {
        temp_expr = new(mem)ObTempExpr(allocator_);
      }
      OB_UNIS_DECODE(*temp_expr);
      if (OB_SUCC(ret)) {
        expr_final_infos_.at(i).temp_expr_ = temp_expr;
      }
    }
  }
  return ret;
}

O
obdev 已提交
7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942
int ObQueryRange::serialize_srid_map(char *buf, int64_t buf_len, int64_t &pos) const
{
  int ret = OB_SUCCESS;
  ColumnIdInfoMap::const_iterator iter = columnId_map_.begin();
  while (OB_SUCC(ret) && iter != columnId_map_.end()) {
    OB_UNIS_ENCODE(iter->first);
    OB_UNIS_ENCODE(iter->second.srid_);
    OB_UNIS_ENCODE(iter->second.cellid_columnId_);
    iter++;
  }
  return ret;
}

O
obdev 已提交
7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975
int ObQueryRange::deserialize_srid_map(int64_t count, const char *buf, int64_t data_len, int64_t &pos)
{
  int ret = OB_SUCCESS;
  if (!columnId_map_.created()
      && OB_FAIL(columnId_map_.create(OB_DEFAULT_SRID_BUKER, &map_alloc_, &bucket_allocator_wrapper_))) {
    LOG_WARN("Init columnId_map_ failed", K(ret));
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < count; i++) {
    uint64_t columnID = 0;
    ObGeoColumnInfo column_info;
    OB_UNIS_DECODE(columnID);
    OB_UNIS_DECODE(column_info.srid_);
    OB_UNIS_DECODE(column_info.cellid_columnId_);
    if (OB_FAIL(columnId_map_.set_refactored(columnID, column_info))) {
      LOG_WARN("set srid map failed", K(ret), K(columnID));
    }
  }
  return ret;
}

int64_t ObQueryRange::get_columnId_map_size() const
{
  int64_t len = 0;
  ColumnIdInfoMap::const_iterator iter = columnId_map_.begin();
  while (iter != columnId_map_.end()) {
    OB_UNIS_ADD_LEN(iter->first);
    OB_UNIS_ADD_LEN(iter->second.srid_);
    OB_UNIS_ADD_LEN(iter->second.cellid_columnId_);
    iter++;
  }
  return len;
}

W
wangzelin.wzl 已提交
7976 7977 7978
OB_SERIALIZE_MEMBER(ObQueryRange::ObEqualOff,
                    only_pos_, param_idx_, pos_off_, pos_type_, pos_value_);

O
oceanbase-admin 已提交
7979 7980 7981 7982 7983 7984 7985 7986 7987
OB_DEF_SERIALIZE(ObQueryRange)
{
  int ret = OB_SUCCESS;
  int64_t graph_count = (NULL != table_graph_.key_part_head_ ? 1 : 0);

  OB_UNIS_ENCODE(static_cast<int64_t>(state_));
  OB_UNIS_ENCODE(column_count_);
  OB_UNIS_ENCODE(graph_count);
  if (1 == graph_count) {
7988
    if (OB_FAIL(serialize_range_graph(table_graph_.key_part_head_, buf, buf_len, pos))) {
O
oceanbase-admin 已提交
7989 7990 7991 7992 7993 7994
      LOG_WARN("serialize range graph failed", K(ret));
    }
    OB_UNIS_ENCODE(table_graph_.is_precise_get_);
    OB_UNIS_ENCODE(table_graph_.is_equal_range_);
    OB_UNIS_ENCODE(table_graph_.is_standard_range_);
  }
O
obdev 已提交
7995 7996

  //新增对contain_row_序列化
O
oceanbase-admin 已提交
7997
  OB_UNIS_ENCODE(contain_row_);
W
wangzelin.wzl 已提交
7998 7999 8000 8001 8002 8003 8004 8005 8006
  OB_UNIS_ENCODE(has_exec_param_);
  //新增 equal_query_range 序列化
  OB_UNIS_ENCODE(is_equal_and_);
  OB_UNIS_ENCODE(equal_offs_);
  if (OB_SUCC(ret)) {
    if (OB_FAIL(serialize_expr_final_info(buf, buf_len, pos))) {
      LOG_WARN("failed to serialize final exprs", K(ret));
    }
  }
O
obdev 已提交
8007 8008
  OB_UNIS_ENCODE(range_size_);
  OB_UNIS_ENCODE(contain_in_);
O
obdev 已提交
8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019

  //新增对geo谓词相关序列化
  OB_UNIS_ENCODE(contain_geo_filters_);
  OB_UNIS_ENCODE(mbr_filters_);
  int64_t map_count = columnId_map_.size();
  OB_UNIS_ENCODE(map_count);
  if (map_count > 0) {
    if (OB_FAIL(serialize_srid_map(buf, buf_len, pos))) {
      LOG_WARN("serialize srid map failed", K(ret));
    }
  }
8020
  OB_UNIS_ENCODE(table_graph_.skip_scan_offset_);
O
oceanbase-admin 已提交
8021 8022 8023 8024 8025 8026 8027
  return ret;
}

OB_DEF_SERIALIZE_SIZE(ObQueryRange)
{
  int64_t len = 0;
  int64_t graph_count = (NULL != table_graph_.key_part_head_ ? 1 : 0);
O
obdev 已提交
8028
  int ret = OB_SUCCESS;
O
oceanbase-admin 已提交
8029 8030 8031 8032
  OB_UNIS_ADD_LEN(static_cast<int64_t>(state_));
  OB_UNIS_ADD_LEN(column_count_);
  OB_UNIS_ADD_LEN(graph_count);
  if (1 == graph_count) {
8033
    if (OB_FAIL(SMART_CALL(get_range_graph_serialize_size(table_graph_.key_part_head_, len)))) {
O
obdev 已提交
8034 8035 8036 8037 8038 8039
      LOG_WARN("failed to get range graph size", K(ret));
    } else {
      OB_UNIS_ADD_LEN(table_graph_.is_precise_get_);
      OB_UNIS_ADD_LEN(table_graph_.is_equal_range_);
      OB_UNIS_ADD_LEN(table_graph_.is_standard_range_);
    }
O
oceanbase-admin 已提交
8040
  }
O
obdev 已提交
8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056
  if (OB_SUCC(ret)) {
    OB_UNIS_ADD_LEN(contain_row_);
    OB_UNIS_ADD_LEN(has_exec_param_);
    OB_UNIS_ADD_LEN(is_equal_and_);
    OB_UNIS_ADD_LEN(equal_offs_);
    len += get_expr_final_info_serialize_size();
    OB_UNIS_ADD_LEN(range_size_);
    OB_UNIS_ADD_LEN(contain_in_);
    //新增对geo谓词相关序列化
    OB_UNIS_ADD_LEN(contain_geo_filters_);
    OB_UNIS_ADD_LEN(mbr_filters_);
    int64_t map_count = columnId_map_.size();
    OB_UNIS_ADD_LEN(map_count);
    if (map_count > 0) {
      len += get_columnId_map_size();
    }
O
obdev 已提交
8057
  }
8058
  OB_UNIS_ADD_LEN(table_graph_.skip_scan_offset_);
O
oceanbase-admin 已提交
8059 8060 8061 8062 8063 8064 8065 8066
  return len;
}

OB_DEF_DESERIALIZE(ObQueryRange)
{
  int ret = OB_SUCCESS;
  int64_t state = 0;
  int64_t graph_count = 0;
O
obdev 已提交
8067
  int64_t map_count = 0;
O
oceanbase-admin 已提交
8068 8069

  OB_UNIS_DECODE(state);
O
obdev 已提交
8070

O
oceanbase-admin 已提交
8071 8072 8073
  OB_UNIS_DECODE(column_count_);
  OB_UNIS_DECODE(graph_count);
  if (1 == graph_count) {
8074
    if (OB_FAIL(deserialize_range_graph(table_graph_.key_part_head_, buf, data_len, pos))) {
O
oceanbase-admin 已提交
8075 8076 8077 8078 8079 8080 8081 8082 8083 8084
      LOG_WARN("deserialize range graph failed", K(ret));
    }
    OB_UNIS_DECODE(table_graph_.is_precise_get_);
    OB_UNIS_DECODE(table_graph_.is_equal_range_);
    OB_UNIS_DECODE(table_graph_.is_standard_range_);
  }
  OB_UNIS_DECODE(contain_row_);
  if (OB_SUCC(ret)) {
    state_ = static_cast<ObQueryRangeState>(state);
  }
W
wangzelin.wzl 已提交
8085 8086 8087 8088 8089 8090 8091 8092 8093
  OB_UNIS_DECODE(has_exec_param_);
  // 新增 equal_query_range 反序列化
  OB_UNIS_DECODE(is_equal_and_);
  OB_UNIS_DECODE(equal_offs_);
  if (OB_SUCC(ret)) {
    if (OB_FAIL(deserialize_expr_final_info(buf, data_len, pos))) {
      LOG_WARN("failed to deserialize final exprs", K(ret));
    }
  }
O
obdev 已提交
8094 8095
  OB_UNIS_DECODE(range_size_);
  OB_UNIS_DECODE(contain_in_);
O
obdev 已提交
8096 8097 8098 8099 8100 8101 8102 8103
  OB_UNIS_DECODE(contain_geo_filters_);
  OB_UNIS_DECODE(mbr_filters_);
  OB_UNIS_DECODE(map_count);
  if (map_count > 0) {
    if (OB_FAIL(deserialize_srid_map(map_count, buf, data_len, pos))) {
      LOG_WARN("deserialize range graph failed", K(ret));
    }
  }
8104
  OB_UNIS_DECODE(table_graph_.skip_scan_offset_);
O
oceanbase-admin 已提交
8105 8106 8107 8108
  return ret;
}

// Deep copy range graph of one index
W
wangzelin.wzl 已提交
8109
int ObQueryRange::deep_copy_range_graph(ObKeyPart *src, ObKeyPart  *&dest)
O
oceanbase-admin 已提交
8110 8111
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
8112
  ObKeyPart *prev_gt = NULL;
8113 8114
  for (ObKeyPart *cur_gt = src; OB_SUCC(ret) && NULL != cur_gt && !is_reach_mem_limit_;
       cur_gt = cur_gt->general_or_next()) {
W
wangzelin.wzl 已提交
8115 8116 8117 8118
    ObKeyPart *and_next = NULL;
    ObKeyPart *new_key_part = NULL;
    ObKeyPart *prev_key_part = NULL;
    ObKeyPart *new_cur_gt_head = NULL;
O
oceanbase-admin 已提交
8119 8120
    if (OB_FAIL(SMART_CALL(deep_copy_range_graph(cur_gt->and_next_, and_next)))) {
      LOG_WARN("Deep copy range graph failed", K(ret));
8121 8122
    } else if (is_reach_mem_limit_) {
      // do nothing
O
oceanbase-admin 已提交
8123
    } else {
W
wangzelin.wzl 已提交
8124
      for (ObKeyPart *cur_or = cur_gt;
8125
           OB_SUCC(ret) && NULL != cur_or && cur_or->and_next_ == cur_gt->and_next_ && !is_reach_mem_limit_;
O
oceanbase-admin 已提交
8126 8127 8128
           cur_or = cur_or->or_next_) {
        if (OB_FAIL(deep_copy_key_part_and_items(cur_or, new_key_part))) {
          LOG_WARN("Deep copy key part and items failed");
8129 8130
        } else if (is_reach_mem_limit_) {
          // do nothing
O
oceanbase-admin 已提交
8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142
        } else if (cur_or == cur_gt) {
          new_cur_gt_head = new_key_part;
        } else {
          if (OB_ISNULL(prev_key_part)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("prev_key_part is null.", K(ret));
          } else {
            prev_key_part->or_next_ = new_key_part;
          }
        }
        if (OB_SUCC(ret)) {
          prev_key_part = new_key_part;
W
wangzelin.wzl 已提交
8143
          if (OB_ISNULL(new_key_part)) { //yeti2
O
oceanbase-admin 已提交
8144 8145 8146 8147 8148 8149 8150 8151
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("new_key_part is null.", K(ret));
          } else {
            new_key_part->and_next_ = and_next;
          }
        }
      }
    }
8152
    if (OB_SUCC(ret) && !is_reach_mem_limit_) {
O
oceanbase-admin 已提交
8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166
      if (NULL != prev_gt) {
        prev_gt->or_next_ = new_cur_gt_head;
      } else {
        dest = new_cur_gt_head;
      }
      prev_gt = new_key_part;
    }
  }
  if (OB_FAIL(ret)) {
    dest = NULL;
  }
  return ret;
}

W
wangzelin.wzl 已提交
8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206
int ObQueryRange::deep_copy_expr_final_info(const ObIArray<ExprFinalInfo> &final_infos)
{
  int ret = OB_SUCCESS;
  expr_final_infos_.reset();
  if (OB_FAIL(expr_final_infos_.prepare_allocate(final_infos.count()))) {
    LOG_WARN("failed to init array", K(ret));
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < final_infos.count(); i++) {
    ObTempExpr *temp_expr = NULL;
    expr_final_infos_.at(i).flags_ = final_infos.at(i).flags_;
    if (final_infos.at(i).is_param_) {
      expr_final_infos_.at(i).param_idx_ = final_infos.at(i).param_idx_;
    } else if (!final_infos.at(i).expr_exists_) {
      // do nothing
    } else if (OB_ISNULL(final_infos.at(i).temp_expr_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected null expr", K(ret));
    } else if (OB_FAIL(final_infos.at(i).temp_expr_->deep_copy(allocator_, temp_expr))) {
      LOG_WARN("failed to deep copy temp expr failed", K(ret));
    } else {
      expr_final_infos_.at(i).temp_expr_ = temp_expr;
    }
  }
  return ret;
}

int ObQueryRange::shallow_copy_expr_final_info(const ObIArray<ExprFinalInfo> &final_infos)
{
  int ret = OB_SUCCESS;
  expr_final_infos_.reset();
  if (OB_FAIL(expr_final_infos_.prepare_allocate(final_infos.count()))) {
    LOG_WARN("failed to init array", K(ret));
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < final_infos.count(); i++) {
    expr_final_infos_.at(i).flags_ = final_infos.at(i).flags_;
    expr_final_infos_.at(i).param_idx_ = final_infos.at(i).param_idx_;
  }
  return ret;
}

O
oceanbase-admin 已提交
8207 8208
// Deep copy whole query range

W
wangzelin.wzl 已提交
8209 8210
OB_NOINLINE int ObQueryRange::deep_copy(const ObQueryRange &other,
                                        const bool copy_for_final /* = false*/)
O
oceanbase-admin 已提交
8211 8212
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
8213
  const ObRangeGraph &other_graph = other.table_graph_;
O
oceanbase-admin 已提交
8214
  state_ = other.state_;
O
obdev 已提交
8215
  range_size_ = other.range_size_;
O
oceanbase-admin 已提交
8216
  contain_row_ = other.contain_row_;
O
obdev 已提交
8217
  contain_in_ = other.contain_in_;
O
oceanbase-admin 已提交
8218
  column_count_ = other.column_count_;
O
obdev 已提交
8219
  contain_geo_filters_ = other.contain_geo_filters_;
W
wangzelin.wzl 已提交
8220 8221
  has_exec_param_ = other.has_exec_param_;
  is_equal_and_ = other.is_equal_and_;
O
oceanbase-admin 已提交
8222 8223
  if (OB_FAIL(range_exprs_.assign(other.range_exprs_))) {
    LOG_WARN("assign range exprs failed", K(ret));
8224 8225
  } else if (OB_FAIL(ss_range_exprs_.assign(other.ss_range_exprs_))) {
    LOG_WARN("assign range exprs failed", K(ret));
O
oceanbase-admin 已提交
8226 8227
  } else if (OB_FAIL(table_graph_.assign(other_graph))) {
    LOG_WARN("Deep copy range columns failed", K(ret));
W
wangzelin.wzl 已提交
8228 8229 8230 8231 8232 8233 8234 8235 8236 8237
  } else if (OB_FAIL(equal_offs_.assign(other.equal_offs_))) {
    LOG_WARN("Deep copy equal and offset failed", K(ret));
  } else if (OB_FAIL(deep_copy_range_graph(other_graph.key_part_head_, table_graph_.key_part_head_))) {
    LOG_WARN("Deep copy key part graph failed", K(ret));
  }
  if (OB_FAIL(ret)) {
  } else if (copy_for_final) {
    if (OB_FAIL(shallow_copy_expr_final_info(other.expr_final_infos_))) {
      LOG_WARN("Deep copy expr final info failed", K(ret));
    }
O
oceanbase-admin 已提交
8238
  } else {
W
wangzelin.wzl 已提交
8239 8240
    if (OB_FAIL(deep_copy_expr_final_info(other.expr_final_infos_))) {
      LOG_WARN("Deep copy expr final info failed", K(ret));
O
oceanbase-admin 已提交
8241 8242
    }
  }
O
obdev 已提交
8243 8244

  const ColumnIdInfoMap& input_srid = other.get_columnId_map();
8245
  if (input_srid.created()) {
O
obdev 已提交
8246 8247 8248 8249 8250 8251 8252
    ColumnIdInfoMap::const_iterator iter = input_srid.begin();
    if (!columnId_map_.created()) {
      if (OB_FAIL(columnId_map_.create(OB_DEFAULT_SRID_BUKER, &map_alloc_, &bucket_allocator_wrapper_))) {
        LOG_WARN("Init columnId_map_ failed", K(ret));
      }
    } else if (OB_FAIL(columnId_map_.reuse())) {
      LOG_WARN("reuse columnId_map_ failed", K(ret));
O
obdev 已提交
8253
    }
O
obdev 已提交
8254 8255 8256 8257 8258
    while (OB_SUCC(ret) && iter != input_srid.end()) {
      if (OB_FAIL(columnId_map_.set_refactored(iter->first, iter->second))) {
        LOG_WARN("set srid map failed", K(ret), K(iter->first));
      }
      iter++;
O
obdev 已提交
8259 8260
    }
  }
O
obdev 已提交
8261

O
obdev 已提交
8262 8263 8264 8265 8266
  FOREACH_X(it, other.mbr_filters_, OB_SUCC(ret) && it != other.mbr_filters_.end()) {
    if (OB_FAIL(mbr_filters_.push_back(*it))) {
      LOG_WARN("store mbr_filters_ failed", K(ret));
    }
  }
O
oceanbase-admin 已提交
8267 8268 8269 8270 8271 8272 8273 8274 8275 8276
  return ret;
}

DEF_TO_STRING(ObQueryRange)
{
  int64_t pos = 0;

  J_ARRAY_START();
  if (NULL != table_graph_.key_part_head_) {
    J_OBJ_START();
W
wangzelin.wzl 已提交
8277 8278 8279
    J_KV(N_IN, table_graph_.is_equal_range_,
         N_IS_GET, table_graph_.is_precise_get_,
         N_IS_STANDARD, table_graph_.is_standard_range_);
O
oceanbase-admin 已提交
8280 8281 8282 8283 8284 8285 8286 8287 8288 8289
    J_COMMA();
    J_NAME(N_RANGE_GRAPH);
    J_COLON();
    pos += range_graph_to_string(buf + pos, buf_len - pos, table_graph_.key_part_head_);
    J_OBJ_END();
  }
  J_ARRAY_END();
  return pos;
}

W
wangzelin.wzl 已提交
8290 8291 8292 8293
int64_t ObQueryRange::range_graph_to_string(
    char *buf,
    const int64_t buf_len,
    ObKeyPart *key_part) const
O
oceanbase-admin 已提交
8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330
{
  int64_t pos = 0;
  bool is_stack_overflow = false;
  int ret = OB_SUCCESS;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("failed to do stack overflow check", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack overflow", K(ret));
  } else {
    J_OBJ_START();
    if (NULL != key_part) {
      J_KV(N_KEY_PART_VAL, *key_part);
      if (key_part->item_next_) {
        J_COMMA();
        J_NAME(N_ITEM_KEY_PART);
        J_COLON();
        pos += range_graph_to_string(buf + pos, buf_len - pos, key_part->item_next_);
      }
      if (key_part->and_next_) {
        J_COMMA();
        J_NAME(N_AND_KEY_PART);
        J_COLON();
        pos += range_graph_to_string(buf + pos, buf_len - pos, key_part->and_next_);
      }
      if (key_part->or_next_) {
        J_COMMA();
        J_NAME(N_OR_KEY_PART);
        J_COLON();
        pos += range_graph_to_string(buf + pos, buf_len - pos, key_part->or_next_);
      }
    }
    J_OBJ_END();
  }
  return pos;
}

W
wangzelin.wzl 已提交
8331
inline bool ObQueryRange::is_standard_graph(const ObKeyPart *root) const
O
oceanbase-admin 已提交
8332 8333 8334 8335 8336
{
  bool bret = true;
  if (contain_row_) {
    bret = false;
  } else {
W
wangzelin.wzl 已提交
8337
    for (const ObKeyPart *cur = root; bret && NULL != cur; cur = cur->and_next_) {
O
obdev 已提交
8338
      if (NULL != cur->or_next_ || cur->is_like_key() || cur->is_in_key() || cur->is_geo_key()) {
O
oceanbase-admin 已提交
8339 8340
        bret = false;
      } else {
W
wangzelin.wzl 已提交
8341 8342
        for (const ObKeyPart *item_next = cur->item_next_;
             bret && NULL != item_next;
O
oceanbase-admin 已提交
8343
             item_next = item_next->item_next_) {
O
obdev 已提交
8344
          if (item_next->is_like_key() || item_next->is_in_key() || item_next->is_geo_key()) {
O
oceanbase-admin 已提交
8345 8346 8347 8348 8349 8350 8351 8352 8353
            bret = false;
          }
        }
      }
    }
  }
  return bret;
}

W
wangzelin.wzl 已提交
8354 8355 8356
// 判断是否可以免or
// 严格的等值node的graph
// 满足条件: KEY连续、对齐、等值条件
O
oceanbase-admin 已提交
8357
int ObQueryRange::is_strict_equal_graph(
W
wangzelin.wzl 已提交
8358
    const ObKeyPart *node,
8359
    const int64_t cur_pos,
W
wangzelin.wzl 已提交
8360 8361
    int64_t &max_pos,
    bool &is_strict_equal) const
O
oceanbase-admin 已提交
8362 8363
{
  int ret = OB_SUCCESS;
O
obdev 已提交
8364
  is_strict_equal = true;
8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378
  for (const ObKeyPart *cur_part = node;
       OB_SUCC(ret) && is_strict_equal && cur_part != NULL;
       cur_part = cur_part->or_next_) {
    int64_t next_pos = -1;
    if (cur_part->is_in_key()) {
     if (cur_part->in_keypart_->get_min_offset() != cur_pos ||
        !cur_part->in_keypart_->is_strict_in_) {
        is_strict_equal = false;
      } else {
        next_pos = cur_part->in_keypart_->get_max_offset() + 1;
      }
    } else if (cur_part->pos_.offset_ != cur_pos) { // check consequent
      is_strict_equal = false;
    } else if (!cur_part->is_equal_condition()) { // check equal
O
obdev 已提交
8379 8380
      is_strict_equal = false;
    } else {
8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394
      next_pos = cur_pos + 1;
    }
    if (is_strict_equal) {
      // and direction
      if (NULL != cur_part->and_next_) {
        if (NULL == cur_part->or_next_ || cur_part->or_next_->and_next_ != cur_part->and_next_) {
          if(SMART_CALL(is_strict_equal_graph(cur_part->and_next_, next_pos,
                                              max_pos, is_strict_equal))) {
            LOG_WARN("failed to check is strict equal graph");
          }
        }
      } else { // check align
        if (-1 == max_pos) {
          max_pos = next_pos - 1;
8395
        } else if (next_pos - 1 != max_pos) {
8396 8397
          is_strict_equal = false;
        }
O
oceanbase-admin 已提交
8398 8399 8400 8401 8402 8403
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414
// graph是严格的range的条件是抽取的range中只能包含一个in表达式
// 可以设定起始键的位置start_pos,默认是0.

// pos不为0时用来判断是不是整齐的graph时(硬解析时判断需不需要做or操作),主键c1,c2,c3
// (c2,c3) in ((1,2),(2,3)) -> 是整齐的graph,pos从1开始

// 普通情况例如:主键是c1, c2, c3
// (c1, c2, c3) in ((1, 2, 3), (4, 5, 6))  TRUE
// (c1, c3) in ((1, 3), (4, 6)) 主键不连续, FALSE
// (c2,c3) in ((1,1),(2,2)) 不是主键前缀 ,  FALSE
// (c1, c2, c3) in ((1, 2, 3), (4, (select 5), 6)) FALSE,主键有个位置的值是子查询,(min, max)覆盖了后面的范围
O
obdev 已提交
8415
bool ObQueryRange::is_strict_in_graph(const ObKeyPart *root, const int64_t start_pos /* = 0*/) const
O
oceanbase-admin 已提交
8416 8417
{
  bool bret = true;
O
obdev 已提交
8418
  if (OB_UNLIKELY(NULL == root) || OB_UNLIKELY(column_count_ < 1)) {
O
oceanbase-admin 已提交
8419
    bret = false;
O
obdev 已提交
8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449
  } else {
    int64_t first_len = -1;
    for (const ObKeyPart *cur_or = root; bret && NULL != cur_or; cur_or = cur_or->or_next_) {
      const ObKeyPart *cur_and = cur_or;
      int64_t j = start_pos;
      for (j = start_pos; bret && j < column_count_ && NULL != cur_and; ++j) {
        if (cur_and->is_in_key()) {
          if (!cur_and->in_keypart_->is_single_in() && cur_and->or_next_ != NULL) {
            ObKeyPart *cur_and_or = cur_and->or_next_;
            if (cur_and_or->pos_.offset_ == cur_and->in_keypart_->get_min_offset() &&
                cur_and_or->and_next_ != NULL) {
              bret = false;
            }
          }
          if (start_pos != j && NULL != cur_and->or_next_) {
            bret = false;
          } else if (cur_and->in_keypart_->is_strict_in_) {
            j = cur_and->in_keypart_->get_max_offset();
          } else {
            bret = false;
          }
        } else if (cur_and->pos_.offset_ != j) {
          //key graph is not strictly consequent
          bret = false;
        } else if (!cur_and->is_equal_condition()) {
          bret = false;
        } else if (start_pos != j && NULL != cur_and->or_next_) {
          // except the first item, others can't has or_next
          bret = false;
        }
O
oceanbase-admin 已提交
8450 8451
        cur_and = cur_and->and_next_;
      }
O
obdev 已提交
8452 8453 8454 8455 8456 8457
      if (bret) {
        if (first_len < 0) {
          first_len = j;
        } else if (j != first_len || NULL != cur_and) {
          bret = false;
        }
O
oceanbase-admin 已提交
8458 8459 8460 8461 8462 8463
      }
    }
  }
  return bret;
}

W
wangzelin.wzl 已提交
8464
int ObQueryRange::ObSearchState::intersect(const ObObj &start, bool include_start, const ObObj &end, bool include_end)
O
oceanbase-admin 已提交
8465 8466 8467 8468 8469
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(start_) || OB_ISNULL(end_) || OB_ISNULL(include_start_) || OB_ISNULL(include_end_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid argument", K_(start), K_(end), K_(include_start), K_(include_end), K_(depth));
O
obdev 已提交
8470
  } else if (OB_UNLIKELY(depth_ < 0)) {
O
oceanbase-admin 已提交
8471 8472
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("invalid depth", K(ret), K_(depth));
W
wangzelin.wzl 已提交
8473 8474
    //depth_允许小于0,但是depth_小于0,节点的值只可能会恒true或者恒false or whole key_part,在上面已经处理了这3种条件
    //不应该走到这里来
O
oceanbase-admin 已提交
8475
  } else {
W
wangzelin.wzl 已提交
8476 8477
    ObObj &s1 = start_[depth_];
    ObObj &e1 = end_[depth_];
O
oceanbase-admin 已提交
8478
    int cmp = start.compare(end);
W
wangzelin.wzl 已提交
8479 8480 8481
    if (cmp > 0 || (0 == cmp && (!include_start || !include_end)) //参数中的range范围是空集,所以结果为空集
        || !has_intersect(start, include_start, end, include_end)) {
      // 结果为空集
O
oceanbase-admin 已提交
8482
      for (int64_t i = 0; i < max_exist_index_; ++i) {
W
wangzelin.wzl 已提交
8483
        //and表达式中有一个键为false,那么整个range都是false
O
oceanbase-admin 已提交
8484 8485 8486 8487 8488 8489 8490
        start_[i].set_max_value();
        end_[i].set_min_value();
      }
      last_include_start_ = false;
      last_include_end_ = false;
      is_empty_range_ = true;
    } else if (start.is_min_value() && end.is_max_value()) {
W
wangzelin.wzl 已提交
8491
      //always true, true and A => the result's A, so ignore true
O
oceanbase-admin 已提交
8492
    } else {
W
wangzelin.wzl 已提交
8493
      //取大
O
oceanbase-admin 已提交
8494 8495 8496 8497 8498 8499 8500 8501 8502 8503
      cmp = s1.compare(start);
      if (cmp > 0) {
        // do nothing
      } else if (cmp < 0) {
        s1 = start;
        include_start_[depth_] = include_start;
      } else {
        include_start_[depth_] = (include_start_[depth_] && include_start);
      }

W
wangzelin.wzl 已提交
8504
      // 取小
O
oceanbase-admin 已提交
8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523
      cmp = e1.compare(end);
      if (cmp > 0) {
        e1 = end;
        include_end_[depth_] = include_end;
      } else if (cmp < 0) {
        // do nothing
      } else {
        include_end_[depth_] = (include_end_[depth_] && include_end);
      }
    }
  }
  return ret;
}

int ObQueryRange::remove_precise_range_expr(int64_t offset)
{
  int ret = OB_SUCCESS;
  if (query_range_ctx_ != NULL) {
    for (int64_t i = 0; OB_SUCC(ret) && i < query_range_ctx_->precise_range_exprs_.count(); ++i) {
W
wangzelin.wzl 已提交
8524 8525
      ObRangeExprItem &expr_item = query_range_ctx_->precise_range_exprs_.at(i);
      for (int64_t j = 0 ; j < expr_item.cur_pos_.count() ; ++j) {
O
oceanbase-admin 已提交
8526 8527 8528 8529 8530 8531 8532 8533 8534 8535
        if (expr_item.cur_pos_.at(j) >= offset) {
          expr_item.cur_expr_ = NULL;
          break;
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
8536
bool ObQueryRange::is_general_graph(const ObKeyPart &keypart) const
O
oceanbase-admin 已提交
8537 8538
{
  bool bret = true;
W
wangzelin.wzl 已提交
8539 8540
  const ObKeyPart *cur_key = &keypart;
  const ObKeyPart *cur_and_next = cur_key->and_next_;
O
obdev 已提交
8541 8542 8543 8544 8545
  for (const ObKeyPart *and_next = cur_key; bret && and_next != NULL; and_next = and_next->and_next_) {
    if (and_next->is_in_key() && !and_next->in_keypart_->is_single_in()) {
      bret = false;
    }
  }
W
wangzelin.wzl 已提交
8546
  for (const ObKeyPart *or_next = cur_key->or_next_; bret && or_next != NULL; or_next = or_next->or_next_) {
O
obdev 已提交
8547 8548 8549
    if (or_next->is_in_key() && !or_next->in_keypart_->is_single_in()) {
      bret = false;
    } else if (or_next->and_next_ != cur_and_next) {
O
oceanbase-admin 已提交
8550 8551 8552 8553 8554 8555
      bret = false;
    }
  }
  return bret;
}

W
wangzelin.wzl 已提交
8556
bool ObQueryRange::has_scan_key(const ObKeyPart &keypart) const
O
oceanbase-admin 已提交
8557 8558
{
  bool bret = false;
W
wangzelin.wzl 已提交
8559
  for (const ObKeyPart *or_next = &keypart; !bret && or_next != NULL; or_next = or_next->or_next_) {
O
oceanbase-admin 已提交
8560 8561 8562 8563 8564 8565 8566
    if (!or_next->is_equal_condition()) {
      bret = true;
    }
  }
  return bret;
}

W
wangzelin.wzl 已提交
8567 8568 8569 8570
bool ObQueryRange::check_like_range_precise(const ObString &pattern_str,
                                            const char *max_str_buf,
                                            const size_t max_str_len,
                                            const char escape)
O
oceanbase-admin 已提交
8571
{
W
wangzelin.wzl 已提交
8572
    const char *pattern_str_buf = pattern_str.ptr();
O
oceanbase-admin 已提交
8573 8574
    bool end_with_percent = false;
    bool find_first_percent = false;
W
wangzelin.wzl 已提交
8575
    bool is_precise = false;
O
oceanbase-admin 已提交
8576 8577 8578 8579 8580 8581
    int64_t i = 0;
    int64_t j = 0;
    int64_t last_equal_idx = -1;
    while (i < pattern_str.length() && j < max_str_len) {
      // handle escape
      if (pattern_str_buf[i] == escape) {
W
wangzelin.wzl 已提交
8582
        if (i == pattern_str.length() - 1){
O
oceanbase-admin 已提交
8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607
          // if escape is last character in pattern, then we will use its origin meaning
          // e.g. c1 like 'aa%' escape '%', % in pattern means match any
        } else {
          ++i;
        }
      }

      if (pattern_str_buf[i] == max_str_buf[j]) {
        last_equal_idx = i;
        ++i;
        ++j;
      } else if (pattern_str_buf[i] == '%') {
        if (find_first_percent) {
          if (pattern_str_buf[i - 1] == '%') {
            end_with_percent = (pattern_str.length() == i + 1);
          } else {
            end_with_percent = false;
            break;
          }
        } else {
          find_first_percent = true;
          end_with_percent = (pattern_str.length() == i + 1);
        }
        ++i;
      } else {
W
wangzelin.wzl 已提交
8608
        // 通配符'_'对于不同的字符集有不同的处理方式, 因此这里不处理'_'的情况, 如果遇到'_'直接认为不是一个精确匹配
O
oceanbase-admin 已提交
8609 8610 8611 8612
        break;
      }
    }
    bool match_without_wildcard = (i == pattern_str.length() && j == max_str_len);
W
wangzelin.wzl 已提交
8613
    // 以'%'结尾或pattern中不存在通配符,且上一个相等字符不是空格(即pattern中不含尾部空格)
O
oceanbase-admin 已提交
8614 8615 8616
    if ((end_with_percent || match_without_wildcard) &&
        (-1 == last_equal_idx || pattern_str_buf[last_equal_idx] != ' ')) {
      if (!is_oracle_mode() && match_without_wildcard) {
K
Klawz 已提交
8617
        // in mysql, all operator will ignore trailing spaces except like.
O
oceanbase-admin 已提交
8618 8619
        // for example, 'abc  ' = 'abc' is true, but 'abc  ' like 'abc' is false
      } else {
W
wangzelin.wzl 已提交
8620
        is_precise = true;
O
oceanbase-admin 已提交
8621 8622
      }
    }
W
wangzelin.wzl 已提交
8623
  return is_precise;
O
oceanbase-admin 已提交
8624 8625
}

W
wangzelin.wzl 已提交
8626 8627 8628 8629 8630
int ObQueryRange::cast_like_obj_if_needed(const ObObj &string_obj,
                                          ObObj &buf_obj,
                                          const ObObj *&obj_ptr,
                                          ObKeyPart &out_key_part,
                                          const ObDataTypeCastParams &dtc_params)
O
oceanbase-admin 已提交
8631 8632 8633
{
  int ret = OB_SUCCESS;
  obj_ptr = &string_obj;
W
wangzelin.wzl 已提交
8634
  ObExprResType &col_res_type = out_key_part.pos_.column_type_;
O
oceanbase-admin 已提交
8635 8636 8637 8638 8639 8640
  if (!ObSQLUtils::is_same_type_for_compare(string_obj.get_meta(), col_res_type.get_obj_meta())) {
    ObCastCtx cast_ctx(&allocator_, &dtc_params, CM_WARN_ON_FAIL, col_res_type.get_collation_type());
    ObExpectType expect_type;
    expect_type.set_type(col_res_type.get_type());
    expect_type.set_collation_type(col_res_type.get_collation_type());
    expect_type.set_type_infos(&out_key_part.pos_.get_enum_set_values());
C
chaser-ch 已提交
8641 8642 8643 8644 8645
    ObAccuracy res_acc;
    if (col_res_type.get_type() == ObDecimalIntType) {
      res_acc = col_res_type.get_accuracy();
      cast_ctx.res_accuracy_ = &res_acc;
    }
O
oceanbase-admin 已提交
8646 8647
    if (OB_FAIL(ObObjCaster::to_type(expect_type, cast_ctx, string_obj, buf_obj, obj_ptr))) {
      LOG_WARN("cast obj to dest type failed", K(ret), K(string_obj), K(col_res_type));
8648 8649
    } else if (ob_is_double_tc(expect_type.get_type())) {
      const_cast<ObObj *>(obj_ptr)->set_scale(col_res_type.get_accuracy().get_scale());
O
oceanbase-admin 已提交
8650 8651 8652 8653 8654
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740
// Notes:
// Since Mysql and Oracle think 0x00 and null is different, they think null is equivalent to '\\'
// but 0x00 is just 0x00. Therefore, before use this interface, PLEASE MAKE SURE escape is not null.
int ObQueryRange::is_precise_like_range(const ObObjParam &pattern, char escape, bool &is_precise)
{
  int ret = OB_SUCCESS;

  ObCollationType cs_type = pattern.get_collation_type();
  int64_t mbmaxlen = 1;
  is_precise = false;
  if (pattern.is_string_type()) {
    ObString pattern_str = pattern.get_string();
    if (cs_type == CS_TYPE_INVALID || cs_type >= CS_TYPE_MAX) {
    }else if (OB_FAIL(ObCharset::get_mbmaxlen_by_coll(cs_type, mbmaxlen))) {
      LOG_WARN("fail to get mbmaxlen", K(ret), K(cs_type), K(escape));
    } else {
      ObArenaAllocator allocator;
      size_t col_len = pattern.get_string_len();
      col_len = static_cast<int32_t>(col_len * mbmaxlen);
      size_t min_str_len = col_len;
      size_t max_str_len = col_len;
      char *min_str_buf = NULL;
      char *max_str_buf = NULL;

      if (col_len == 0) {
        is_precise = true;
      } else if (OB_ISNULL(min_str_buf = (char *)allocator.alloc(min_str_len))) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_WARN("no enough memory", K(ret), K(col_len), K(min_str_len));
      } else if (OB_ISNULL(max_str_buf = (char *)allocator.alloc(max_str_len))) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_WARN("no enough memory", K(ret));
      } else if (OB_FAIL(ObCharset::like_range(cs_type, pattern_str, escape,
                                       min_str_buf, &min_str_len,
                                       max_str_buf, &max_str_len))) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("failed to retrive like range", K(ret));
      } else {
        is_precise = ObQueryRange::check_like_range_precise(pattern_str,
                                                            static_cast<char*>(max_str_buf),
                                                            max_str_len, escape);
      }
    }
  }

  return ret;
}

int ObQueryRange::get_calculable_expr_val(const ObRawExpr *expr,
                                          ObObj &val,
                                          bool &is_valid,
                                          const bool ignore_error/*default true*/)
{
  int ret = OB_SUCCESS;
  ParamStore dummy_params;
  const ParamStore *params = NULL;
  bool ignore_failure = false;
  if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret));
  } else if (expr->has_flag(CNT_DYNAMIC_PARAM)) {
    is_valid = true;
  } else if (OB_FAIL(ObSQLUtils::calc_const_or_calculable_expr(query_range_ctx_->exec_ctx_,
                                            expr,
                                            val,
                                            is_valid,
                                            allocator_,
                                            ignore_error && query_range_ctx_->ignore_calc_failure_,
                                            query_range_ctx_->expr_constraints_))) {
    LOG_WARN("failed to calc const or calculable expr", K(ret));
  }
  return ret;
}

int ObQueryRange::add_precise_constraint(const ObRawExpr *expr, bool is_precise)
{
  int ret = OB_SUCCESS;
  PreCalcExprExpectResult expect_result = is_precise ? PreCalcExprExpectResult::PRE_CALC_PRECISE :
                                              PreCalcExprExpectResult::PRE_CALC_NOT_PRECISE;
  ObExprConstraint cons(const_cast<ObRawExpr*>(expr), expect_result);
  if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret));
  } else if (NULL == query_range_ctx_->expr_constraints_) {
    // do nothing
  } else if (OB_FAIL(add_var_to_array_no_dup(*query_range_ctx_->expr_constraints_, cons))) {
O
obdev 已提交
8741
    LOG_WARN("failed to add precise constraint", K(ret));
W
wangzelin.wzl 已提交
8742 8743 8744 8745
  }
  return ret;
}

O
obdev 已提交
8746 8747 8748 8749 8750 8751
int ObQueryRange::add_prefix_pattern_constraint(const ObRawExpr *expr)
{
  int ret = OB_SUCCESS;
  if (OB_FAIL(ObRawExprUtils::get_real_expr_without_cast(expr, expr))) {
    LOG_WARN("fail to get real expr", K(ret));
  } else if (OB_ISNULL(expr)) {
8752
    ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767
    LOG_WARN("unexpected null", K(ret));
  } else if (T_FUN_SYS_PREFIX_PATTERN == expr->get_expr_type()) {
    ObExprConstraint cons(const_cast<ObRawExpr*>(expr), PreCalcExprExpectResult::PRE_CALC_RESULT_NOT_NULL);
    if (OB_ISNULL(query_range_ctx_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected null", K(ret));
    } else if (NULL == query_range_ctx_->expr_constraints_) {
      // do nothing
    } else if (OB_FAIL(add_var_to_array_no_dup(*query_range_ctx_->expr_constraints_, cons))) {
      LOG_WARN("failed to add precise constraint", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
8768 8769 8770 8771 8772
int ObQueryRange::get_final_expr_val(const ObRawExpr *expr, ObObj &val)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(query_range_ctx_)) {
    ret = OB_NOT_INIT;
O
obdev 已提交
8773 8774 8775
    LOG_WARN("query range context is null", K(ret));
  } else {
    int64_t idx = query_range_ctx_->final_exprs_.count();
W
wangzelin.wzl 已提交
8776
    val.set_unknown(idx);
O
obdev 已提交
8777 8778 8779
    if (OB_FAIL(query_range_ctx_->final_exprs_.push_back(expr))) {
      LOG_WARN("failed to push back final expr pairs", K(ret));
    }
W
wangzelin.wzl 已提交
8780 8781 8782 8783 8784 8785 8786 8787 8788 8789
  }
  return ret;
}

int ObQueryRange::generate_expr_final_info()
{
  int ret = OB_SUCCESS;
  // todo sean.yyj: only cg the remaining final expr in table graph
  RowDesc row_desc;
  expr_final_infos_.reset();
O
obdev 已提交
8790 8791
  if (OB_ISNULL(query_range_ctx_) || OB_ISNULL(query_range_ctx_->exec_ctx_) ||
      OB_ISNULL(query_range_ctx_->exec_ctx_->get_sql_ctx())) {
W
wangzelin.wzl 已提交
8792
    ret = OB_NOT_INIT;
O
obdev 已提交
8793
    LOG_WARN("query range context is null", K(ret), K(query_range_ctx_));
8794 8795
  } else if (OB_UNLIKELY(query_range_ctx_->final_exprs_.empty())) {
    // do nothing
O
obdev 已提交
8796
  } else if (OB_FAIL(expr_final_infos_.prepare_allocate(query_range_ctx_->final_exprs_.count()))) {
W
wangzelin.wzl 已提交
8797 8798
    LOG_WARN("init expr final info failed", K(ret));
  }
O
obdev 已提交
8799 8800
  for (int64_t i = 0; OB_SUCC(ret) && i < query_range_ctx_->final_exprs_.count(); ++i) {
    const ObRawExpr *expr = query_range_ctx_->final_exprs_.at(i);
W
wangzelin.wzl 已提交
8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812
    ObTempExpr *temp_expr = NULL;
    if (OB_ISNULL(expr)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("expr is null", K(ret));
    } else if (T_QUESTIONMARK == expr->get_expr_type()) {
      const ObConstRawExpr *const_expr = static_cast<const ObConstRawExpr *>(expr);
      int64_t param_idx = OB_INVALID_ID;
      ObObj val = const_expr->get_value();
      if (OB_UNLIKELY(!val.is_unknown())) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("unexpected value type", K(val), K(ret));
      } else {
O
obdev 已提交
8813 8814 8815
        val.get_unknown(expr_final_infos_.at(i).param_idx_);
        expr_final_infos_.at(i).is_param_ = true;
        expr_final_infos_.at(i).cnt_exec_param_ = expr->has_flag(CNT_DYNAMIC_PARAM);
W
wangzelin.wzl 已提交
8816 8817
      }
    } else if (OB_FAIL(ObStaticEngineExprCG::gen_expr_with_row_desc(expr,
O
obdev 已提交
8818 8819 8820 8821 8822
                                      row_desc,
                                      query_range_ctx_->exec_ctx_->get_allocator(),
                                      query_range_ctx_->exec_ctx_->get_my_session(),
                                      query_range_ctx_->exec_ctx_->get_sql_ctx()->schema_guard_,
                                      temp_expr))) {
W
wangzelin.wzl 已提交
8823 8824
      LOG_WARN("failed to generate expr with row desc", K(ret));
    } else {
O
obdev 已提交
8825 8826 8827
      expr_final_infos_.at(i).temp_expr_ = temp_expr;
      expr_final_infos_.at(i).expr_exists_ = true;
      expr_final_infos_.at(i).cnt_exec_param_ = expr->has_flag(CNT_DYNAMIC_PARAM);
W
wangzelin.wzl 已提交
8828 8829 8830 8831 8832
    }
  }
  return ret;
}

O
oceanbase-admin 已提交
8833 8834 8835 8836 8837 8838 8839 8840 8841
DEF_TO_STRING(ObQueryRange::ObRangeExprItem)
{
  int64_t pos = 0;
  J_OBJ_START();
  J_KV(K_(cur_expr), K_(cur_pos));
  J_OBJ_END();
  return pos;
}

O
obdev 已提交
8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874
common::ObGeoRelationType ObQueryRange::get_geo_relation(ObItemType type) const
{
  common::ObGeoRelationType rel_type = common::ObGeoRelationType::T_INVALID;
  switch (type) {
    case T_FUN_SYS_ST_INTERSECTS : {
      rel_type = common::ObGeoRelationType::T_INTERSECTS;
      break;
    }
    case T_FUN_SYS_ST_CONTAINS :
    case T_FUN_SYS_ST_COVERS : {
      rel_type = common::ObGeoRelationType::T_COVERS;
      break;
    }
    case T_FUN_SYS_ST_DWITHIN : {
      rel_type = common::ObGeoRelationType::T_DWITHIN;
      break;
    }
    case T_FUN_SYS_ST_WITHIN : {
      rel_type = common::ObGeoRelationType::T_COVEREDBY;
      break;
    }
    default:
      break;
  }
  return rel_type;
}

int ObQueryRange::get_geo_intersects_keypart(uint32_t input_srid,
                                             const common::ObString &wkb_str,
                                             const common::ObGeoRelationType op_type,
                                             ObKeyPart *out_key_part)
{
  INIT_SUCC(ret);
O
obdev 已提交
8875
  common::ObArenaAllocator tmp_alloc(lib::ObLabel("GisIndex"));
O
obdev 已提交
8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887
  ObS2Cellids cells;
  ObS2Cellids cells_with_ancestors;
  ObSpatialMBR mbr_filter(op_type);
  ObGeoType geo_type = ObGeoType::GEOMETRY;
  const ObSrsItem *srs_item = NULL;
  omt::ObSrsCacheGuard srs_guard;
  const ObSrsBoundsItem *srs_bound = NULL;
  ObS2Adapter *s2object = NULL;
  ObString buffer_geo;
  double distance = NAN;

  // todo : fix me, get effective tenant_id
8888 8889
  if ((input_srid != 0) && OB_FAIL(OTSRS_MGR->get_tenant_srs_guard(srs_guard))) {
    LOG_WARN("get tenant srs guard failed", K(input_srid), K(ret));
O
obdev 已提交
8890 8891 8892
  } else if ((input_srid != 0) && OB_FAIL(srs_guard.get_srs_item(input_srid, srs_item))) {
    LOG_WARN("get tenant srs failed", K(input_srid), K(ret));
  } else if (((input_srid == 0) || !(srs_item->is_geographical_srs())) &&
8893
             OB_FAIL(OTSRS_MGR->get_srs_bounds(input_srid, srs_item, srs_bound))) {
O
obdev 已提交
8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928
    LOG_WARN("failed to get srs item", K(ret));
  } else if (op_type == ObGeoRelationType::T_DWITHIN) {
    distance = out_key_part->geo_keypart_->distance_.get_double();
    if (out_key_part->geo_keypart_->distance_.is_unknown() || std::isnan(distance)) {
      ret = OB_INVALID_ARGUMENT;
      LOG_WARN("invalid distance para", K(ret));
    } else if (input_srid != 0 && srs_item->is_geographical_srs()) {
      double sphere_radius = (srs_item->semi_major_axis() * 2 + srs_item->semi_minor_axis()) /  3;
      const double SPHERIOD_ERR_FRACTION = 0.005;
      double radius = ((1.0 + SPHERIOD_ERR_FRACTION) * distance) / sphere_radius;
      s2object = OB_NEWx(ObS2Adapter, (&tmp_alloc), (&tmp_alloc), true, radius);
      if (OB_ISNULL(s2object)) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_WARN("failed to alloc s2 object", K(ret));
      }
    } else {
      if (OB_FAIL(ObGeoTypeUtil::get_buffered_geo(&tmp_alloc, wkb_str, distance, srs_item, buffer_geo))) {
        LOG_WARN("failed to get buffer geo", K(ret));
        if (ret == OB_INVALID_ARGUMENT) {
          LOG_USER_ERROR(OB_INVALID_ARGUMENT, N_ST_BUFFER);
        } else if (ret == OB_ERR_GIS_INVALID_DATA) {
          LOG_USER_ERROR(OB_ERR_GIS_INVALID_DATA, N_ST_BUFFER);
        }
      }
    }
  }
  if (s2object == NULL && OB_SUCC(ret)) {
    s2object = OB_NEWx(ObS2Adapter, (&tmp_alloc), (&tmp_alloc), (input_srid != 0 ? srs_item->is_geographical_srs() : false));
    if (OB_ISNULL(s2object)) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_WARN("failed to alloc s2 object", K(ret));
    }
  }

  if (OB_SUCC(ret)) {
O
obdev 已提交
8929
    lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(MTL_ID(), "S2Adapter"));
O
obdev 已提交
8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011
    // build s2 object from wkb
    if (OB_FAIL(ObGeoTypeUtil::get_type_from_wkb((buffer_geo.empty() ? wkb_str : buffer_geo), geo_type))) {
      LOG_WARN("fail to get geo type by wkb", K(ret));
    } else if (OB_FAIL(s2object->init((buffer_geo.empty() ? wkb_str : buffer_geo), srs_bound))) {
      LOG_WARN("Init s2object failed", K(ret));
    } else if (OB_FAIL(s2object->get_cellids(cells, false))) {
      LOG_WARN("Get cellids from s2object failed", K(ret));
    } else if (OB_FAIL(s2object->get_cellids(cells_with_ancestors, true))) {
      LOG_WARN("Get cellids with ancestors from s2object failed", K(ret));
    } else if (OB_FAIL(s2object->get_mbr(mbr_filter))) {
      LOG_WARN("Get mbr from s2object failed", K(ret));
    } else if (OB_FAIL(mbr_filters_.push_back(mbr_filter))) {
      LOG_WARN("Push back to mbr_filters array failed", K(ret));
    } else if (mbr_filter.is_empty()) {
      if (cells.size() == 0) {
        LOG_INFO("it's might be empty geometry collection", K(wkb_str));
        if (OB_FAIL(set_geo_keypart_whole_range(*out_key_part))) {
          LOG_WARN("set keypart whole range failed", K(ret));
        }
      } else {
        ret = OB_ERR_GIS_INVALID_DATA;
        LOG_WARN("invalid geometry", K(ret), K(wkb_str));
      }
    } else {
      if (NULL != query_range_ctx_) {
        query_range_ctx_->cur_expr_is_precise_ = false;
      }
      ObKeyPart *last = out_key_part;
      // build keypart from cells_with_ancestors
      for (uint64_t i = 0; OB_SUCC(ret) && i < cells_with_ancestors.size(); i++) {
        ObObj val;
        val.set_uint64(cells_with_ancestors[i]);
        if (i == 0) {
          if (OB_FAIL(get_geo_single_keypart(val, val, *out_key_part))) {
            LOG_WARN("get normal cmp keypart failed", K(ret));
          }
        } else {
          ObKeyPart *tmp = NULL;
          if (OB_ISNULL((tmp = create_new_key_part()))) {
            ret = OB_ALLOCATE_MEMORY_FAILED;
            LOG_ERROR("alloc memory failed", K(ret));
          } else {
            tmp->id_ = out_key_part->id_;
            tmp->pos_ = out_key_part->pos_;
            if (OB_FAIL(get_geo_single_keypart(val, val, *tmp))) {
              LOG_WARN("get normal cmp keypart failed", K(ret));
            } else {
              last->or_next_ = tmp;
              last = tmp;
            }
          }
        }
      }

      if (OB_SUCC(ret) && (geo_type != ObGeoType::POINT || !std::isnan(distance))) {
        // build keypart to index child_of_cellid
        for (uint64_t i = 0; OB_SUCC(ret) && i < cells.size(); i++) {
          uint64_t cellid = cells.at(i);
          uint64_t start_id = 0;
          uint64_t end_id = 0;
          ObS2Adapter::get_child_of_cellid(cellid, start_id, end_id);
          ObKeyPart *tmp = NULL;
          if (OB_ISNULL((tmp = create_new_key_part()))) {
            ret = OB_ALLOCATE_MEMORY_FAILED;
            LOG_ERROR("alloc memory failed", K(ret));
          } else {
            tmp->id_ = out_key_part->id_;
            tmp->pos_ = out_key_part->pos_;
            ObObj val_start, val_end;
            val_start.set_uint64(start_id);
            val_end.set_uint64(end_id);
            if (OB_FAIL(get_geo_single_keypart(val_start, val_end, *tmp))) {
              LOG_WARN("get normal cmp keypart failed", K(ret));
            } else {
              last->or_next_ = tmp;
              last = tmp;
            }
          }
        }
      }
    }
  }
O
obdev 已提交
9012 9013 9014
  if (OB_NOT_NULL(s2object)) {
    s2object->~ObS2Adapter();
  }
O
obdev 已提交
9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034

  return ret;
}

int ObQueryRange::get_geo_coveredby_keypart(uint32_t input_srid,
                                            const common::ObString &wkb_str,
                                            const common::ObGeoRelationType op_type,
                                            ObKeyPart *out_key_part)
{
  INIT_SUCC(ret);
  common::ObArenaAllocator tmp_alloc;
  ObS2Cellids cells;
  ObSpatialMBR mbr_filter(op_type);
  const ObSrsItem *srs_item = NULL;
  omt::ObSrsCacheGuard srs_guard;
  const ObSrsBoundsItem *srs_bound = NULL;
  ObS2Adapter *s2object = NULL;
  ObExecContext *exec_ctx = NULL;
  ObString buffer_geo;

9035 9036
  if ((input_srid != 0) && OB_FAIL(OTSRS_MGR->get_tenant_srs_guard(srs_guard))) {
    LOG_WARN("get tenant srs guard failed", K(input_srid), K(ret));
O
obdev 已提交
9037 9038 9039
  } else if ((input_srid != 0) && OB_FAIL(srs_guard.get_srs_item(input_srid, srs_item))) {
    LOG_WARN("get tenant srs failed", K(input_srid), K(ret));
  } else if (((input_srid == 0) || !(srs_item->is_geographical_srs())) &&
9040
             OB_FAIL(OTSRS_MGR->get_srs_bounds(input_srid, srs_item, srs_bound))) {
O
obdev 已提交
9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051
    LOG_WARN("failed to get srs item", K(ret));
  }
  if (s2object == NULL && OB_SUCC(ret)) {
    s2object = OB_NEWx(ObS2Adapter, (&tmp_alloc), (&tmp_alloc), (input_srid != 0 ? srs_item->is_geographical_srs() : false));
    if (OB_ISNULL(s2object)) {
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_WARN("failed to alloc s2 object", K(ret));
    }
  }

  if (OB_SUCC(ret)) {
O
obdev 已提交
9052
    lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(MTL_ID(), "S2Adapter"));
O
obdev 已提交
9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076
    // build s2 object from wkb
    if (OB_FAIL(s2object->init((buffer_geo.empty() ? wkb_str : buffer_geo), srs_bound))) {
      LOG_WARN("Init s2object failed", K(ret));
    } else if (OB_FAIL(s2object->get_inner_cover_cellids(cells))) {
      LOG_WARN("Get cellids from s2object failed", K(ret));
    } else if (OB_FAIL(s2object->get_mbr(mbr_filter))) {
      LOG_WARN("Get mbr from s2object failed", K(ret));
    } else if (OB_FAIL(mbr_filters_.push_back(mbr_filter))) {
      LOG_WARN("Push back to mbr_filters array failed", K(ret));
    } else if (mbr_filter.is_empty()) {
      if (cells.size() == 0) {
        LOG_INFO("it's might be empty geometry collection", K(wkb_str));
        if (OB_FAIL(set_geo_keypart_whole_range(*out_key_part))) {
          LOG_WARN("set keypart whole range failed", K(ret));
        }
      } else {
        ret = OB_ERR_GIS_INVALID_DATA;
        LOG_WARN("invalid geometry", K(ret), K(wkb_str));
      }
    } else {
      if (NULL != query_range_ctx_) {
        query_range_ctx_->cur_expr_is_precise_ = false;
        exec_ctx = query_range_ctx_->exec_ctx_;
      }
9077 9078 9079 9080 9081 9082 9083 9084 9085
      ObKeyPart *head = nullptr;
      ObKeyPart *last = nullptr;
      hash::ObHashSet<uint64_t> cellid_set;
      if (OB_FAIL(cellid_set.create(128, "CoveredByKeyPart", "HashNode"))) {
        LOG_WARN("failed to create cellid set", K(ret));
      } else if (!cellid_set.created()) {
        ret = OB_NOT_INIT;
        LOG_WARN("fail to init cellid set", K(ret));
      }
O
obdev 已提交
9086
      for (uint64_t i = 0; OB_SUCC(ret) && i < cells.size(); i++) {
9087 9088 9089 9090 9091 9092 9093
        int hash_ret = cellid_set.exist_refactored(cells[i]);
        if (OB_HASH_NOT_EXIST == hash_ret) {
          ObKeyPart *cell_head = nullptr;
          ObKeyPart *cell_last = nullptr;
          if (OB_FAIL(cellid_set.set_refactored(cells[i]))) {
            LOG_WARN("failed to add cellid into set", K(ret));
          } else if (OB_ISNULL((cell_head = create_new_key_part()))) {
O
obdev 已提交
9094 9095 9096 9097
            ret = OB_ALLOCATE_MEMORY_FAILED;
            LOG_ERROR("alloc memory failed", K(ret));
          } else {
            ObObj val;
9098 9099 9100 9101
            val.set_uint64(cells[i]);
            cell_head->id_ = out_key_part->id_;
            cell_head->pos_ = out_key_part->pos_;
            if (OB_FAIL(get_geo_single_keypart(val, val, *cell_head))) {
O
obdev 已提交
9102 9103
              LOG_WARN("get normal cmp keypart failed", K(ret));
            } else {
9104
              cell_last = cell_head;
9105 9106
            }
          }
9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151
          ObS2Cellids ancestors;
          if (OB_FAIL(ret)) {
          } else if (OB_FAIL(s2object->get_ancestors(cells[i], ancestors))) {
            LOG_WARN("Get ancestors of cell failed", K(ret));
          }
          // if cur cellid is exists in set, then it's ancestors also exist in set
          int hash_ret = OB_HASH_NOT_EXIST;
          for (uint64_t i = 0; OB_SUCC(ret) && i < ancestors.size(); i++) {
            hash_ret = cellid_set.exist_refactored(ancestors[i]);
            if (hash_ret == OB_HASH_NOT_EXIST) {
              ObKeyPart *tmp = NULL;
              if (OB_FAIL(cellid_set.set_refactored(ancestors[i]))) {
                LOG_WARN("failed to add cellid into set", K(ret));
              } else if (OB_ISNULL((tmp = create_new_key_part()))) {
                ret = OB_ALLOCATE_MEMORY_FAILED;
                LOG_ERROR("alloc memory failed", K(ret));
              } else {
                ObObj val;
                val.set_uint64(ancestors[i]);
                tmp->id_ = out_key_part->id_;
                tmp->pos_ = out_key_part->pos_;
                if (OB_FAIL(get_geo_single_keypart(val, val, *tmp))) {
                  LOG_WARN("get normal cmp keypart failed", K(ret));
                } else {
                  cell_last->or_next_ = tmp;
                  cell_last = tmp;
                }
              }
            } else if (OB_HASH_EXIST != hash_ret) {
              ret = hash_ret;
              LOG_WARN("fail to check if key exist", K(ret), K(ancestors[i]), K(i));
            }
          }

          if (OB_SUCC(ret)) {
            if (OB_ISNULL(head)) {
              head = cell_head;
            } else {
              last->or_next_ = cell_head;
            }
            last = cell_last;
          }
        } else if (OB_HASH_EXIST != hash_ret) {
          ret = hash_ret;
          LOG_WARN("fail to check if key exist", K(ret), K(cells[i]), K(i));
O
obdev 已提交
9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162
        }
      }

      void *ptr = NULL;
      if (OB_FAIL(ret)) {
      } else if (OB_ISNULL(ptr = allocator_.alloc(sizeof(ObQueryRangeCtx)))) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LOG_ERROR("alloc query range context failed");
      } else {
        query_range_ctx_ = new(ptr) ObQueryRangeCtx(exec_ctx, NULL, NULL);
      }
9163

O
obdev 已提交
9164
      ObS2Cellids cells_cover_geo;
9165 9166 9167
      for (uint64_t i = 0; OB_SUCC(ret) && i < cells_cover_geo.size(); i++) {
        int hash_ret = cellid_set.exist_refactored(cells_cover_geo[i]);
        if (OB_HASH_NOT_EXIST == hash_ret) {
O
obdev 已提交
9168
          ObKeyPart *tmp = NULL;
9169 9170 9171
          if (OB_FAIL(cellid_set.set_refactored(cells_cover_geo[i]))) {
            LOG_WARN("failed to add cellid into set", K(ret));
          } else if (OB_ISNULL((tmp = create_new_key_part()))) {
O
obdev 已提交
9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185
            ret = OB_ALLOCATE_MEMORY_FAILED;
            LOG_ERROR("alloc memory failed", K(ret));
          } else {
            ObObj val;
            val.set_uint64(cells_cover_geo[i]);
            tmp->id_ = out_key_part->id_;
            tmp->pos_ = out_key_part->pos_;
            if (OB_FAIL(get_geo_single_keypart(val, val, *tmp))) {
              LOG_WARN("get normal cmp keypart failed", K(ret));
            } else {
              last->or_next_ = tmp;
              last = tmp;
            }
          }
9186 9187 9188
        } else if (OB_HASH_EXIST != hash_ret) {
          ret = hash_ret;
          LOG_WARN("fail to check if key exist", K(ret), K(cells_cover_geo[i]), K(i));
O
obdev 已提交
9189
        }
9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214
      }
      // copy temp_result to out_key_part
      if (OB_FAIL(ret)) {
      } else if (OB_FAIL(out_key_part->create_normal_key())) {
        LOG_WARN("create normal key failed", K(ret));
      } else if (OB_ISNULL(out_key_part->normal_keypart_)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("normal keypart is null");
      } else {
        out_key_part->null_safe_ = head->null_safe_;
        out_key_part->normal_keypart_->include_start_ = true;
        out_key_part->normal_keypart_->include_end_ = true;
        out_key_part->normal_keypart_->start_ = head->normal_keypart_->start_;
        out_key_part->normal_keypart_->end_ = head->normal_keypart_->end_;
        out_key_part->normal_keypart_->always_false_ = false;
        out_key_part->normal_keypart_->always_true_ = false;
        out_key_part->item_next_ = head->item_next_;
        out_key_part->or_next_ = head->or_next_;
        out_key_part->and_next_ = head->and_next_;
      }
      // clear hashset
      if (cellid_set.created()) {
        int tmp_ret = cellid_set.destroy();
        if (OB_SUCC(ret) && OB_FAIL(tmp_ret)) {
          LOG_WARN("failed to destory param set", K(ret));
O
obdev 已提交
9215 9216 9217 9218
        }
      }
    }
  }
O
obdev 已提交
9219 9220 9221
  if (OB_NOT_NULL(s2object)) {
    s2object->~ObS2Adapter();
  }
O
obdev 已提交
9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241

  return ret;
}

int ObQueryRange::get_geo_range(const common::ObObj &wkb, const common::ObGeoRelationType op_type,
                                ObKeyPart *out_key_part)
{
  INIT_SUCC(ret);
  ObString wkb_str(wkb.get_string());
  if (OB_ISNULL(wkb_str.ptr()) || wkb.is_unknown()) {
    // if this spatial relation function is pushdown filter of nl, wkb_str ptr is not null.
    // set whole range when can not get wkb
    if (OB_FAIL(set_geo_keypart_whole_range(*out_key_part))) {
      LOG_WARN("set keypart whole range failed", K(ret));
    }
  } else {
    // check srid
    uint64_t columnid = out_key_part->id_.column_id_;
    ObGeoColumnInfo column_info;
    uint32_t input_srid;
9242 9243 9244 9245
    ObArenaAllocator tmp_allocator(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
    if (OB_FAIL(ObTextStringHelper::read_real_string_data(&tmp_allocator, wkb, wkb_str))) {
      LOG_WARN("fail to get real string data", K(ret), K(wkb));
    } else if (OB_FAIL(ObGeoTypeUtil::get_srid_from_wkb(wkb_str, input_srid))) {
O
obdev 已提交
9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296
      LOG_WARN("failed to get srid", K(ret), K(wkb_str));
    } else if (OB_FAIL(columnId_map_.get_refactored(columnid, column_info))) {
      LOG_WARN("failed to get from columnId_map_", K(ret));
    } else if (OB_FAIL(ObSqlGeoUtils::check_srid(column_info.srid_, input_srid))) {
      ret = OB_ERR_WRONG_SRID_FOR_COLUMN;
      LOG_USER_ERROR(OB_ERR_WRONG_SRID_FOR_COLUMN, static_cast<uint64_t>(input_srid),
        static_cast<uint64_t>(column_info.srid_));
    } else {
      switch (op_type) {
        case ObGeoRelationType::T_INTERSECTS:
        case ObGeoRelationType::T_COVERS:
        case ObGeoRelationType::T_DWITHIN:
          if (OB_FAIL(get_geo_intersects_keypart(input_srid, wkb_str, op_type, out_key_part))) {
            LOG_WARN("failed to get keypart from intersects_keypart", K(ret), K(op_type));
          }
          break;
        case ObGeoRelationType::T_COVEREDBY:
          if (OB_FAIL(get_geo_coveredby_keypart(input_srid, wkb_str, op_type, out_key_part))) {
            LOG_WARN("failed to get keypart from intersects_keypart", K(ret), K(op_type));
          }
          break;
        default:
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("Not support op_type", K(ret), K(op_type));
          break;
      }
    }
  }

  return ret;
}

int ObQueryRange::init_columnId_map()
{
  INIT_SUCC(ret);
  if (!columnId_map_.created()
      && OB_FAIL(columnId_map_.create(OB_DEFAULT_SRID_BUKER, &map_alloc_, &bucket_allocator_wrapper_))) {
    LOG_WARN("Init column_info_map failed", K(ret));
  }
  return ret;
}

int ObQueryRange::set_columnId_map(uint64_t columnId, const ObGeoColumnInfo &column_info)
{
  INIT_SUCC(ret);
  if (OB_FAIL(columnId_map_.set_refactored(columnId, column_info))) {
    LOG_WARN("set columnId map failed", K(ret), K(columnId));
  }
  return ret;
}

O
oceanbase-admin 已提交
9297 9298
}  // namespace sql
}  // namespace oceanbase