ob_expr.h 40.6 KB
Newer Older
O
oceanbase-admin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/**
 * 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.
 */

#ifndef OCEANBASE_EXPR_OB_EXPR_H_
#define OCEANBASE_EXPR_OB_EXPR_H_

#include "lib/container/ob_2d_array.h"
#include "lib/allocator/ob_allocator.h"
W
wangzelin.wzl 已提交
18
#include "lib/oblog/ob_log.h"
O
oceanbase-admin 已提交
19 20
#include "share/datum/ob_datum.h"
#include "sql/engine/ob_serializable_function.h"
W
wangzelin.wzl 已提交
21 22
#include "objit/common/ob_item_type.h"
#include "sql/engine/ob_bit_vector.h"
O
oceanbase-admin 已提交
23

W
wangzelin.wzl 已提交
24 25 26 27 28
namespace oceanbase
{
namespace common
{
 class ObObjParam;
O
oceanbase-admin 已提交
29 30
}

W
wangzelin.wzl 已提交
31 32 33 34 35 36 37 38
namespace storage
{
  // forward declaration for friends
  class ObVectorStore;
}
namespace sql
{

O
oceanbase-admin 已提交
39
using lib::is_oracle_mode;
W
wangzelin.wzl 已提交
40
using lib::is_mysql_mode;
O
oceanbase-admin 已提交
41 42

class ObExecContext;
W
wangzelin.wzl 已提交
43 44 45
struct ObIExprExtraInfo;
struct ObSqlDatumArray;
class ObDatumCaster;
O
oceanbase-admin 已提交
46
using common::ObDatum;
W
wangzelin.wzl 已提交
47
using common::ObDatumVector;
O
oceanbase-admin 已提交
48 49 50

typedef ObItemType ObExprOperatorType;

W
wangzelin.wzl 已提交
51 52
struct ObDatumMeta
{
O
oceanbase-admin 已提交
53
  OB_UNIS_VERSION(1);
G
gm 已提交
54
public:
W
wangzelin.wzl 已提交
55 56 57 58 59 60 61 62
  ObDatumMeta() : type_(common::ObNullType), cs_type_(common::CS_TYPE_INVALID)
                  , scale_(-1), precision_(-1)
  {
  }
  ObDatumMeta(const common::ObObjType type,
              const common::ObCollationType cs_type,
              const int8_t scale)
    : type_(type), cs_type_(cs_type), scale_(scale), precision_(-1)
O
oceanbase-admin 已提交
63 64
  {
  }
W
wangzelin.wzl 已提交
65 66 67 68 69 70 71 72 73
  ObDatumMeta(const common::ObObjType type,
              const common::ObCollationType cs_type,
              const int8_t scale,
              const common::ObPrecision prec)
    : type_(type), cs_type_(cs_type), scale_(scale), precision_(prec)
  {
  }

  void reset() { new (this) ObDatumMeta(); }
O
oceanbase-admin 已提交
74 75 76 77 78 79 80 81 82 83 84
  TO_STRING_KV(K_(type), K_(cs_type), K_(scale), K_(precision));

  common::ObObjType type_;
  common::ObCollationType cs_type_;
  int8_t scale_;
  union {
    common::ObPrecision precision_;
    common::ObLengthSemantics length_semantics_;
  };
  OB_INLINE bool is_clob() const
  {
W
wangzelin.wzl 已提交
85 86 87
    return (is_oracle_mode()
            && (static_cast<uint8_t>(common::ObLongTextType) == type_)
            && (common::CS_TYPE_BINARY != cs_type_));
O
oceanbase-admin 已提交
88 89 90
  }
  OB_INLINE bool is_varchar() const
  {
W
wangzelin.wzl 已提交
91 92
    return ((static_cast<uint8_t>(common::ObVarcharType) == type_)
            && (common::CS_TYPE_BINARY != cs_type_));
O
oceanbase-admin 已提交
93 94 95
  }
  OB_INLINE bool is_char() const
  {
W
wangzelin.wzl 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109
    return ((static_cast<uint8_t>(common::ObCharType) == type_)
            && (common::CS_TYPE_BINARY != cs_type_));
  }
  OB_INLINE bool is_binary() const
  {
    return ((static_cast<uint8_t>(common::ObCharType) == type_)
        && (common::CS_TYPE_BINARY == cs_type_));
  }
  OB_INLINE bool is_ext_sql_array() const
  {
    //in ObObj, scale_ and meta extend flag union in the same structure,
    //for extend type meta, scale_ means extend flag
    return ((static_cast<uint8_t>(common::ObExtendType) == type_)
            && (common::T_EXT_SQL_ARRAY == static_cast<uint8_t>(scale_)));
O
oceanbase-admin 已提交
110
  }
W
wangzelin.wzl 已提交
111
  OB_INLINE common::ObObjType get_type() const { return type_; }
O
oceanbase-admin 已提交
112 113 114
};

// Expression evaluate result info
W
wangzelin.wzl 已提交
115 116
struct ObEvalInfo
{
O
oceanbase-admin 已提交
117 118
  void clear_evaluated_flag()
  {
W
wangzelin.wzl 已提交
119 120 121
    if (evaluated_ || projected_) {
      evaluated_ = 0;
      projected_ = 0;
O
oceanbase-admin 已提交
122 123 124 125
    }
  }
  DECLARE_TO_STRING;

W
wangzelin.wzl 已提交
126 127 128 129 130 131 132 133 134 135
  inline bool in_frame_notnull() const { return notnull_ && point_to_frame_; }

	union {
		struct {
			// is already evaluated
			uint16_t evaluated_:1;
			// is projected
			uint16_t projected_:1;
			// all datums are not null.
			// may not set even all datums are not null,
O
oceanbase-admin 已提交
136
      // e.g.: the null values are filtered by skip bitmap.
W
wangzelin.wzl 已提交
137 138 139 140 141 142 143 144
			uint16_t notnull_:1;
			// pointer is point to reserved buffer in frame.
			uint16_t point_to_frame_:1;
		};
		uint16_t flag_;
	};
	// result count (set to batch_size in batch_eval)
	uint16_t cnt_;
O
oceanbase-admin 已提交
145 146 147
};

// expression evaluate context
W
wangzelin.wzl 已提交
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
struct ObEvalCtx
{
  friend struct ObExpr;
  friend class ObOperator;
  friend class ObSubPlanFilterOp; // FIXME qubin.qb: remove this line from friend
  friend class oceanbase::storage::ObVectorStore;
  friend class ObDatumCaster;
  class TempAllocGuard
  {
  public:
    TempAllocGuard(ObEvalCtx &eval_ctx) : ctx_(eval_ctx), used_flag_(eval_ctx.tmp_alloc_used_)
    {
      alloc_ = &ctx_.get_reset_tmp_alloc();
      ctx_.tmp_alloc_used_ = true;
    }
    ~TempAllocGuard() { ctx_.tmp_alloc_used_ = used_flag_; }
    common::ObArenaAllocator &get_allocator() { return *alloc_; }
  private:
    ObEvalCtx &ctx_;
    common::ObArenaAllocator *alloc_;
    bool used_flag_;
  };
  class BatchInfoScopeGuard
  {
  public:
    explicit BatchInfoScopeGuard(ObEvalCtx &eval_ctx)
    {
      batch_idx_ptr_ = &eval_ctx.batch_idx_;
      batch_size_ptr_ = &eval_ctx.batch_size_;
      batch_idx_default_val_ = eval_ctx.batch_idx_;
      batch_size_default_val_ = eval_ctx.batch_size_;
    }
    ~BatchInfoScopeGuard()
    {
       *batch_idx_ptr_ = batch_idx_default_val_;
       *batch_size_ptr_ = batch_size_default_val_;
    }
    inline void set_batch_idx(int64_t v) { *batch_idx_ptr_ = v; }
    inline void set_batch_size(int64_t v) { *batch_size_ptr_ = v; }

  private:
    int64_t *batch_idx_ptr_ = nullptr;
    int64_t *batch_size_ptr_ = nullptr;
    int64_t batch_idx_default_val_ = 0;
    int64_t batch_size_default_val_ = 0;
  };
  explicit ObEvalCtx(ObExecContext &exec_ctx);
  explicit ObEvalCtx(ObEvalCtx &eval_ctx);
  virtual ~ObEvalCtx();

  OB_INLINE int64_t get_batch_idx() { return batch_idx_; }
  OB_INLINE int64_t get_batch_size() { return batch_size_; }
  OB_INLINE bool is_vectorized() const { return 0 != max_batch_size_; }
  OB_INLINE ObArenaAllocator &get_expr_res_alloc() { return expr_res_alloc_; }
  OB_INLINE void reuse(const int64_t batch_size)
  {
    batch_idx_ = 0;
    batch_size_ = batch_size;
  }
O
oceanbase-admin 已提交
207

W
wangzelin.wzl 已提交
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
  OB_INLINE void set_max_batch_size(const int64_t max_batch_size)
  {
    max_batch_size_ = max_batch_size;
  }
  int init_datum_caster();

  TO_STRING_KV(K_(batch_idx), K_(batch_size), K_(max_batch_size), KP(frames_));
private:
  // Allocate expression result memory.
  void *alloc_expr_res(const int64_t size) { return expr_res_alloc_.alloc(size); }

  // set current row evaluating in the batch
  OB_INLINE void set_batch_idx(const int64_t batch_idx)
  {
    // NOTICE: NEVER USE this routine. Use ObEvalCtx::BatchInfoScopeGuard to
    // protect and update batch_idx_. The reason this API is still here is
    // storage layer WON'T use ObEvalCtx::BatchInfoScopeGuard
    batch_idx_ = batch_idx;
  }
  // Note: use set_batch_size() for performance reason.
  // For other path, use ObEvalCtx::BatchInfoScopeGuard instead to protect and
  // update batch_size_.
  OB_INLINE void set_batch_size(const int64_t batch_size)
  {
    batch_size_ = batch_size;
  }
  //change to private interface, please use TempAllocGuard::get_allocator() instead
  common::ObArenaAllocator &get_reset_tmp_alloc()
O
oceanbase-admin 已提交
236 237
  {
#ifndef NDEBUG
W
wangzelin.wzl 已提交
238 239 240
    if (!tmp_alloc_used_) {
      tmp_alloc_.reset();
    }
O
oceanbase-admin 已提交
241
#else
W
wangzelin.wzl 已提交
242
    if (!tmp_alloc_used_ && tmp_alloc_.used() > common::OB_MALLOC_MIDDLE_BLOCK_SIZE) {
O
oceanbase-admin 已提交
243 244 245 246 247 248
      tmp_alloc_.reset_remain_one_page();
    }
#endif
    return tmp_alloc_;
  }

G
gm 已提交
249
public:
W
wangzelin.wzl 已提交
250 251 252 253
  char **frames_;
  // Used for das, the semantics is the same as max_batch_size_ in spec
  int64_t max_batch_size_;
  ObExecContext &exec_ctx_;
O
oceanbase-admin 已提交
254 255
  // Temporary allocator for expression evaluating, may be reset immediately after ObExpr::eval().
  // Can not use allocator for expression result. (ObExpr::get_str_res_mem() is used for result).
W
wangzelin.wzl 已提交
256 257
  common::ObArenaAllocator &tmp_alloc_;
  ObDatumCaster *datum_caster_;
258
  bool &tmp_alloc_used_;
W
wangzelin.wzl 已提交
259 260 261 262 263
private:
  int64_t batch_idx_;
  int64_t batch_size_;
  // Expression result allocator, never reset.
  common::ObArenaAllocator &expr_res_alloc_;
O
oceanbase-admin 已提交
264 265
};

W
wangzelin.wzl 已提交
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280

typedef uint64_t (*ObExprHashFuncType)(const common::ObDatum &datum, const uint64_t seed);

// batch datum hash functions, %seeds, %hash_values may be the same.
typedef void (*ObBatchDatumHashFunc)(uint64_t *hash_values,
                                     common::ObDatum *datums,
                                     const bool is_batch_datum,
                                     const ObBitVector &skip,
                                     int64_t size,
                                     const uint64_t *seeds,
                                     const bool is_batch_seed);

typedef int (*ObExprCmpFuncType)(const common::ObDatum &datum1, const common::ObDatum &datum2);
struct ObExprBasicFuncs
{
O
oceanbase-admin 已提交
281 282 283 284 285 286
  // Default hash method:
  //    murmur for non string tyeps
  //    mysql string hash for string types
  // Try not to use it unless you need to be compatible with ObObj::hash()/ObObj::varchar_hash(),
  // use murmur_hash_ instead.
  ObExprHashFuncType default_hash_;
W
wangzelin.wzl 已提交
287
  ObBatchDatumHashFunc default_hash_batch_;
O
oceanbase-admin 已提交
288 289
  // For murmur/xx/wy functions, the specified hash method is used for all tyeps.
  ObExprHashFuncType murmur_hash_;
W
wangzelin.wzl 已提交
290
  ObBatchDatumHashFunc murmur_hash_batch_;
O
oceanbase-admin 已提交
291
  ObExprHashFuncType xx_hash_;
W
wangzelin.wzl 已提交
292
  ObBatchDatumHashFunc xx_hash_batch_;
O
oceanbase-admin 已提交
293
  ObExprHashFuncType wy_hash_;
W
wangzelin.wzl 已提交
294 295
  ObBatchDatumHashFunc wy_hash_batch_;

O
oceanbase-admin 已提交
296 297 298 299
  ObExprCmpFuncType null_first_cmp_;
  ObExprCmpFuncType null_last_cmp_;
};

W
wangzelin.wzl 已提交
300 301 302

struct ObDynReserveBuf
{
O
oceanbase-admin 已提交
303
  static const uint32_t MAGIC_NUM = 0xD928e5bf;
W
wangzelin.wzl 已提交
304
  static bool supported(const common::ObObjType &type)
O
oceanbase-admin 已提交
305 306
  {
    const common::ObObjTypeClass tc = common::ob_obj_type_class(type);
W
wangzelin.wzl 已提交
307 308 309 310 311
    return common::ObStringTC == tc || common::ObTextTC == tc
           || common::ObRawTC == tc
           || common::ObRowIDTC == tc
           || common::ObLobTC == tc
           || common::ObJsonTC == tc;
O
oceanbase-admin 已提交
312 313 314 315 316 317
  }

  ObDynReserveBuf() = default;

  uint32_t magic_;
  uint32_t len_;
W
wangzelin.wzl 已提交
318
  char *mem_;
O
oceanbase-admin 已提交
319 320 321
};
static_assert(16 == sizeof(ObDynReserveBuf), "ObDynReserveBuf size can not be changed");

W
wangzelin.wzl 已提交
322

O
oceanbase-admin 已提交
323 324
typedef common::ObFixedArray<common::ObString, common::ObIAllocator> ObStrValues;

W
wangzelin.wzl 已提交
325 326 327 328 329 330
#define BATCH_EVAL_FUNC_ARG_DECL const ObExpr &expr, ObEvalCtx &ctx, \
  const ObBitVector &skip, const int64_t size
#define BATCH_EVAL_FUNC_ARG_LIST expr, ctx, skip, size

#define EVAL_FUNC_ARG_DECL const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum
#define EVAL_FUNC_ARG_LIST expr, ctx, expr_datum
O
oceanbase-admin 已提交
331

W
wangzelin.wzl 已提交
332 333 334 335 336 337
// default evaluate batch function which call eval() for every datum of batch.
extern int expr_default_eval_batch_func(BATCH_EVAL_FUNC_ARG_DECL);

struct ObExpr
{
  OB_UNIS_VERSION(1);
G
gm 已提交
338
public:
W
wangzelin.wzl 已提交
339

O
oceanbase-admin 已提交
340 341 342
  const static uint32_t INVALID_EXP_CTX_ID = UINT32_MAX;

  ObExpr();
W
wangzelin.wzl 已提交
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
  OB_INLINE int eval(ObEvalCtx &ctx, common::ObDatum *&datum) const;
  int eval_enumset(ObEvalCtx &ctx,
                   const common::ObIArray<common::ObString> &str_values,
                   const uint64_t cast_mode,
                   common::ObDatum *&datum) const;

  OB_INLINE int eval_batch(ObEvalCtx &ctx,
                           const ObBitVector &skip,
                           const int64_t size) const;

  void reset() { new (this) ObExpr(); }
  ObDatum &locate_expr_datum(ObEvalCtx &ctx) const
  {
    // performance critical, do not check pointer validity.
    return reinterpret_cast<ObDatum *>(ctx.frames_[frame_idx_] + datum_off_)[get_datum_idx(ctx)];
  }
O
oceanbase-admin 已提交
359

W
wangzelin.wzl 已提交
360
  ObDatum &locate_expr_datum(ObEvalCtx &ctx, const int64_t batch_idx) const
O
oceanbase-admin 已提交
361
  {
W
wangzelin.wzl 已提交
362 363
    int64_t idx = batch_idx_mask_ & batch_idx;
    return reinterpret_cast<ObDatum *>(ctx.frames_[frame_idx_] + datum_off_)[idx];
O
oceanbase-admin 已提交
364
  }
W
wangzelin.wzl 已提交
365 366

  ObDatumVector locate_expr_datumvector(ObEvalCtx &ctx) const
O
oceanbase-admin 已提交
367
  {
W
wangzelin.wzl 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
    ObDatumVector datumsvector;
    datumsvector.set_batch(is_batch_result());
    datumsvector.datums_ = reinterpret_cast<ObDatum *>(ctx.frames_[frame_idx_] + datum_off_);
    return datumsvector;
  }

  ObDatum *locate_batch_datums(ObEvalCtx &ctx) const
  {
    return reinterpret_cast<ObDatum *>(ctx.frames_[frame_idx_] + datum_off_);
  }

  // batch version of locate_param_datum.  Array size is batch_size_ in ObEvalCtx
  OB_INLINE ObDatumVector locate_param_datumvector(ObEvalCtx &ctx, int param_index) const
  {
      return args_[param_index]->locate_expr_datumvector(ctx);
  }

  ObBitVector &get_evaluated_flags(ObEvalCtx &ctx) const
  {
    return *to_bit_vector(ctx.frames_[frame_idx_] + eval_flags_off_);
O
oceanbase-admin 已提交
388 389
  }

W
wangzelin.wzl 已提交
390
  ObBitVector &get_pvt_skip(ObEvalCtx &ctx) const
O
oceanbase-admin 已提交
391
  {
W
wangzelin.wzl 已提交
392
    return *to_bit_vector(ctx.frames_[frame_idx_] + pvt_skip_off_);
O
oceanbase-admin 已提交
393 394
  }

W
wangzelin.wzl 已提交
395 396 397 398 399 400 401 402 403 404 405
  ObEvalInfo &get_eval_info(ObEvalCtx &ctx) const
  {
    return *reinterpret_cast<ObEvalInfo *>(ctx.frames_[frame_idx_] + eval_info_off_);
  }

  OB_INLINE char *get_rev_buf(ObEvalCtx &ctx) const
  {
    return ctx.frames_[frame_idx_] + res_buf_off_;
  }


O
oceanbase-admin 已提交
406
  // locate expr datum && reset ptr_ to reserved buf
W
wangzelin.wzl 已提交
407 408 409 410 411 412
  OB_INLINE ObDatum &locate_datum_for_write(ObEvalCtx &ctx) const;

  // locate batch datums and reset datum ptr_ to reserved buf
  inline ObDatum *locate_datums_for_update(ObEvalCtx &ctx, const int64_t size) const;

  OB_INLINE ObDatum &locate_param_datum(ObEvalCtx &ctx, int param_index) const
O
oceanbase-admin 已提交
413
  {
W
wangzelin.wzl 已提交
414
      return args_[param_index]->locate_expr_datum(ctx);
O
oceanbase-admin 已提交
415 416 417 418
  }

  // Get result memory for string type.
  // Dynamic allocated memory is allocated if reserved buffer if not enough.
W
wangzelin.wzl 已提交
419 420 421 422 423 424
  char *get_str_res_mem(ObEvalCtx &ctx, const int64_t size) const
  {
    return get_str_res_mem(ctx, size, get_datum_idx(ctx));
  }

  char *get_str_res_mem(ObEvalCtx &ctx, const int64_t size, const int64_t datum_idx) const
O
oceanbase-admin 已提交
425
  {
W
wangzelin.wzl 已提交
426 427 428
    return OB_LIKELY(size <= res_buf_len_)
        ? ctx.frames_[frame_idx_] + res_buf_off_ + res_buf_len_ * (batch_idx_mask_ & datum_idx)
        : alloc_str_res_mem(ctx, size, datum_idx);
O
oceanbase-admin 已提交
429 430
  }

W
wangzelin.wzl 已提交
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
  void cur_str_resvered_buf(ObEvalCtx &ctx, const int64_t datum_idx, char *&buffer, int64_t &len) const
  {
    buffer = nullptr;
    len = 0;
    int64_t idx = batch_idx_mask_ & datum_idx;
    if (OB_UNLIKELY(!ObDynReserveBuf::supported(datum_meta_.type_))) {
      SQL_ENG_LOG(ERROR, "unexpected alloc string result memory called", K(*this));
    } else {
      ObDynReserveBuf *drb = reinterpret_cast<ObDynReserveBuf *>(
        ctx.frames_[frame_idx_] + dyn_buf_header_offset_ + sizeof(ObDynReserveBuf) * idx);
      if (OB_LIKELY(drb->len_ >= res_buf_len_)) {
        buffer = drb->mem_;
        len = drb->len_;
      } else {
        len = res_buf_len_;
        buffer = ctx.frames_[frame_idx_] + res_buf_off_ + res_buf_len_ * idx;
      }
    }
  }

  // Get pre allocate result memory buffer, only used for string result
  void cur_str_resvered_buf(ObEvalCtx &ctx, char *&buffer, int64_t &len) const
  {
    cur_str_resvered_buf(ctx, get_datum_idx(ctx), buffer, len);
  }

  bool is_variable_res_buf()
  {
    return OBJ_DATUM_STRING == obj_datum_map_;
  };

O
oceanbase-admin 已提交
462 463 464 465 466 467 468 469 470 471 472 473 474 475
  // Evaluate all parameters, assign the first sizeof...(args) parameters to %args.
  //
  // e.g.:
  //  arg_cnt_ = 2;
  //
  //  eval_param_values(ctx):
  //    call: args_[0]->eval(), args_[1]->eval()
  //
  //  eval_param_values(ctx, param0);
  //    call:args_[0]->eval(param0), args_[1]->eval();
  //
  //  eval_param_values(ctx, param0, param1, param2
  //    call: args[0]->eval(param0), args[1]->eval(param1)
  //    keep param2 unchanged.
W
wangzelin.wzl 已提交
476 477 478 479 480 481 482
  template <typename ...TS>
  OB_INLINE int eval_param_value(ObEvalCtx &ctx, TS &...args) const;

  // batch version for eval_param_value
  template <typename ...TS>
  OB_INLINE int eval_batch_param_value(ObEvalCtx &ctx, const ObBitVector &skip,
                                       const int64_t size, TS &...args) const;
O
oceanbase-admin 已提交
483 484

  // deep copy %datum to reserve buffer or new allocated buffer if reserved buffer is not enough.
W
wangzelin.wzl 已提交
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 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
  OB_INLINE int deep_copy_datum(ObEvalCtx &ctx, const common::ObDatum &datum) const;

  bool is_batch_result() const { return batch_result_; }
  int64_t get_datum_idx(ObEvalCtx &ctx) const
  {
    return batch_idx_mask_ & ctx.get_batch_idx();
  }

  // mark contian = TRUE if it meets the following rules:
  //   - expr itself equal to input expr
  //   - expr's children equals to input expr
  // Note: NO stack-overflow check as it is done when resolve raw expr
  int contain_expr (const ObExpr * expr, bool & is_contain)
  {
    int ret = OB_SUCCESS;
    if (this == expr) {
      is_contain = true;
    } else {
      if (arg_cnt_ > 0) {
        for (auto i = 0; !is_contain && i < arg_cnt_; i++) {
          if (args_[i] != nullptr) {
            ret = args_[i]->contain_expr(expr, is_contain);
          }
        }
      } else {
        // do nothing
      }
    }
    return ret;
  }
  OB_INLINE void clear_evaluated_flag(ObEvalCtx &ctx)
  {
    if (is_batch_result()) {
      get_evaluated_flags(ctx).unset(ctx.get_batch_idx());
    } else {
      get_eval_info(ctx).clear_evaluated_flag();
    }
  }

  OB_INLINE void set_evaluated_flag(ObEvalCtx &ctx) const
  {
    get_eval_info(ctx).evaluated_ = true;
    if (batch_result_) {
      get_evaluated_flags(ctx).set(ctx.get_batch_idx());
    }
  }

  OB_INLINE void set_evaluated_projected(ObEvalCtx &ctx) const
  {
    get_eval_info(ctx).evaluated_ = true;
    get_eval_info(ctx).projected_ = true;
  }
O
oceanbase-admin 已提交
537 538

  typedef common::ObIArray<ObExpr> ObExprIArray;
W
wangzelin.wzl 已提交
539
  OB_INLINE static ObExprIArray *&get_serialize_array()
O
oceanbase-admin 已提交
540
  {
W
wangzelin.wzl 已提交
541
    RLOCAL_INLINE(ObExprIArray *, g_expr_ser_array);
O
oceanbase-admin 已提交
542 543 544
    return g_expr_ser_array;
  }

W
wangzelin.wzl 已提交
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
  TO_STRING_KV("type", get_type_name(type_),
              K_(datum_meta),
              K_(obj_meta),
              K_(obj_datum_map),
              K_(flag),
              KP_(eval_func),
              KP_(eval_batch_func),
              KP_(inner_functions),
              K_(inner_func_cnt),
              K_(arg_cnt),
              K_(parent_cnt),
              K_(frame_idx),
              K_(datum_off),
              K_(res_buf_off),
              K_(dyn_buf_header_offset),
              K_(res_buf_len),
              K_(eval_flags_off),
              K_(pvt_skip_off),
              K_(expr_ctx_id),
              K_(extra),
              K_(batch_idx_mask),
              KP(this));
O
oceanbase-admin 已提交
567

G
gm 已提交
568
private:
W
wangzelin.wzl 已提交
569 570 571 572 573
  char *alloc_str_res_mem(ObEvalCtx &ctx, const int64_t size, const int64_t idx) const;
  // reset datums pointer to reserved buffer.
  void reset_datums_ptr(char *frame, const int64_t size) const;
  int eval_one_datum_of_batch(ObEvalCtx &ctx, common::ObDatum *&datum) const;
  int do_eval_batch(ObEvalCtx &ctx, const ObBitVector &skip, const int64_t size) const;
O
oceanbase-admin 已提交
574 575


W
wangzelin.wzl 已提交
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
public:
  typedef int (*EvalFunc) (const ObExpr &expr,
                           ObEvalCtx &ctx,
                           ObDatum &expr_datum);
  typedef int (*EvalBatchFunc) (const ObExpr &expr,
                                ObEvalCtx &ctx,
                                const ObBitVector &skip,
                                const int64_t size);
  typedef int (*EvalEnumSetFunc) (const ObExpr &expr,
                                  const common::ObIArray<common::ObString> &str_values,
                                  const uint64_t cast_mode,
                                  ObEvalCtx &ctx,
                                  ObDatum &expr_datum);

  const static uint64_t MAGIC_NUM = 0x6367614D72707845L; // string of "ExprMagc"
O
oceanbase-admin 已提交
591 592 593 594 595 596 597 598 599 600 601
  uint64_t magic_;
  ObExprOperatorType type_;
  // meta data of datum
  ObDatumMeta datum_meta_;
  // meta data of ObObj, used for ObObj converting.
  common::ObObjMeta obj_meta_;
  // max length of datum value. can be less than 0
  int32_t max_length_;
  // type of ObObj memory layout to ObDatum memory layout mapping,
  // used to convert ObDatum to ObObj and vice versa.
  common::ObObjDatumMapType obj_datum_map_;
W
wangzelin.wzl 已提交
602 603 604 605 606 607 608 609 610 611 612

  union {
    struct {
      uint64_t batch_result_:1;
      uint64_t is_called_in_sql_:1;
      uint64_t is_static_const_:1; // is const during the whole execution
      uint64_t is_boolean_:1; // to distinguish result of this expr between and int tc
      uint64_t is_dynamic_const_:1; // is const during the subplan execution, including exec param
    };
    uint64_t flag_;
  };
O
oceanbase-admin 已提交
613 614 615 616 617 618
  // expr evaluate function
  union {
    EvalFunc eval_func_;
    // helper union member for eval_func_ serialize && deserialize
    sql::serializable_function ser_eval_func_;
  };
W
wangzelin.wzl 已提交
619 620 621 622
  union {
    EvalBatchFunc eval_batch_func_;
    sql::ser_eval_batch_function ser_eval_batch_func_;
  };
O
oceanbase-admin 已提交
623 624 625 626 627 628 629 630
  // aux evaluate functions for eval_func_, array of any function pointers, which interpreted
  // by eval_func_.
  // mysql row operand use the inner function array
  // to compare condition pairs. e.g.:
  //     (a, b, c) = (1, 2, 3)
  //     arg_cnt_ is 6
  //     inner_func_cnt_ is 3
  union {
W
wangzelin.wzl 已提交
631
    void **inner_functions_;
O
oceanbase-admin 已提交
632
    // helper member for inner_functions_ serialize && deserialize
W
wangzelin.wzl 已提交
633
    sql::serializable_function *ser_inner_functions_;
O
oceanbase-admin 已提交
634 635
  };
  uint32_t inner_func_cnt_;
W
wangzelin.wzl 已提交
636
  ObExpr **args_;
O
oceanbase-admin 已提交
637
  uint32_t arg_cnt_;
W
wangzelin.wzl 已提交
638
  ObExpr **parents_;
O
oceanbase-admin 已提交
639 640 641 642 643 644 645
  uint32_t parent_cnt_;
  // frame index
  uint32_t frame_idx_;
  // offset of ObDatum in frame
  uint32_t datum_off_;
  // offset of ObEvalInfo
  uint32_t eval_info_off_;
W
wangzelin.wzl 已提交
646 647
  // Dynamic buf header offset
  uint32_t dyn_buf_header_offset_;
O
oceanbase-admin 已提交
648 649
  // reserve buffer offset in frame
  uint32_t res_buf_off_;
W
wangzelin.wzl 已提交
650
  // reserve buffer length for each datum
O
oceanbase-admin 已提交
651
  uint32_t res_buf_len_;
W
wangzelin.wzl 已提交
652 653 654 655
  // evaluated flags for batch
  uint32_t eval_flags_off_;
  // private skip bit vector
  uint32_t pvt_skip_off_;
O
oceanbase-admin 已提交
656 657 658 659 660
  // expr context id
  uint32_t expr_ctx_id_;
  // extra info, reinterpreted by each expr
  union {
    uint64_t extra_;
W
wangzelin.wzl 已提交
661 662 663 664 665
    struct {
      int64_t div_calc_scale_          :   16;
      int64_t is_error_div_by_zero_    :    1;
      int64_t reserved_                :   47;
    };
O
oceanbase-admin 已提交
666
  };
W
wangzelin.wzl 已提交
667 668 669
  ObExprBasicFuncs *basic_funcs_;
  uint64_t batch_idx_mask_;
  ObIExprExtraInfo *extra_info_;
O
oceanbase-admin 已提交
670 671 672 673
};

// helper template to access ObExpr::extra_
template <typename T>
W
wangzelin.wzl 已提交
674 675 676 677 678 679 680
struct ObExprExtraInfoAccess
{
  static T &get_info(int64_t &v) { return *reinterpret_cast<T *>(&v); }
  static const T &get_info(const int64_t &v) { return *reinterpret_cast<const T*>(&v); }
  static T &get_info(ObExpr &e) { return get_info(*reinterpret_cast<int64_t *>(&e.extra_)); }
  static const T &get_info(const ObExpr &e)
  { return get_info(*reinterpret_cast<const int64_t *>(&e.extra_)); }
O
oceanbase-admin 已提交
681 682 683 684 685
};

// Wrap expression string result buffer allocation to allocator interface.
// Please try not to use this, if you mast use it, make sure it only allocate one time and is
// for expression result.
W
wangzelin.wzl 已提交
686 687
class ObExprStrResAlloc : public common::ObIAllocator
{
G
gm 已提交
688
public:
W
wangzelin.wzl 已提交
689 690 691
  ObExprStrResAlloc(const ObExpr &expr, ObEvalCtx &ctx) : off_(0), expr_(expr), ctx_(ctx)
  {
  }
O
oceanbase-admin 已提交
692

W
wangzelin.wzl 已提交
693 694
  void *alloc(const int64_t size) override;
  void* alloc(const int64_t size, const ObMemAttr &attr) override
N
nroskill 已提交
695 696 697 698
  {
    UNUSED(attr);
    return alloc(size);
  }
W
wangzelin.wzl 已提交
699
  void free(void *ptr) override { UNUSED(ptr); }
G
gm 已提交
700
private:
O
oceanbase-admin 已提交
701
  int64_t off_;
W
wangzelin.wzl 已提交
702 703
  const ObExpr &expr_;
  ObEvalCtx &ctx_;
O
oceanbase-admin 已提交
704 705
};

W
wangzelin.wzl 已提交
706 707
struct ObDatumObj
{
G
gm 已提交
708
public:
W
wangzelin.wzl 已提交
709
  void set_scale(common::ObScale scale) {
O
oceanbase-admin 已提交
710 711 712 713
    meta_.scale_ = scale;
  }
  TO_STRING_KV(K_(meta));

G
gm 已提交
714
public:
O
oceanbase-admin 已提交
715 716 717 718
  ObDatumMeta meta_;
  common::ObDatum datum_;
};

W
wangzelin.wzl 已提交
719 720
typedef common::ObIArray<ObExpr *> ObExprPtrIArray;
typedef common::ObFixedArray<ObExpr *, common::ObIAllocator> ExprFixedArray;
O
oceanbase-admin 已提交
721 722

// copy from ObObjParam
W
wangzelin.wzl 已提交
723 724
struct ObDatumObjParam : public ObDatumObj
{
O
oceanbase-admin 已提交
725
  ObDatumObjParam() : ObDatumObj(), accuracy_(), res_flags_(0), flag_()
W
wangzelin.wzl 已提交
726 727 728 729 730 731
  {
  }
  ObDatumObjParam(const ObDatumObj &other)
    : ObDatumObj(other), accuracy_(), res_flags_(0), flag_()
  {
  }
O
oceanbase-admin 已提交
732 733

  TO_STRING_KV(K_(accuracy), K_(res_flags), K_(datum), K_(meta));
G
gm 已提交
734
public:
W
wangzelin.wzl 已提交
735
  int from_objparam(const common::ObObjParam &objparam, common::ObIAllocator *allocator = nullptr);
O
oceanbase-admin 已提交
736

W
wangzelin.wzl 已提交
737 738 739 740 741
  int to_objparam(common::ObObjParam &obj_param, common::ObIAllocator *allocator = nullptr);
  int construct_array_param_datum(const common::ObObjParam &obj_param, common::ObIAllocator &alloc);
  int construct_sql_array_obj(common::ObObjParam &obj_param, common::ObIAllocator &allocator);
  template<typename T>
  int alloc_datum_reserved_buff(const T &obj_meta, common::ObIAllocator &allocator)
O
oceanbase-admin 已提交
742
  {
W
wangzelin.wzl 已提交
743 744 745 746 747 748 749 750 751 752 753
    int ret = OB_SUCCESS;
    common::ObObjType real_type = obj_meta.is_ext_sql_array() ? common::ObIntType : obj_meta.get_type();
    common::ObObjDatumMapType obj_datum_map = common::ObDatum::get_obj_datum_map_type(real_type);
    if (OB_LIKELY(common::OBJ_DATUM_NULL != obj_datum_map)) {
      uint32_t def_res_len = common::ObDatum::get_reserved_size(obj_datum_map);
      if (OB_ISNULL(datum_.ptr_ = static_cast<char *>(allocator.alloc(def_res_len)))) {
        ret = common::OB_ALLOCATE_MEMORY_FAILED;
        SQL_ENG_LOG(WARN, "fail to alloc memory", K(def_res_len), K(ret));
      }
    }
    return ret;
O
oceanbase-admin 已提交
754
  }
W
wangzelin.wzl 已提交
755
  void set_sql_array_datum(const ObSqlDatumArray *datum_array)
O
oceanbase-admin 已提交
756
  {
W
wangzelin.wzl 已提交
757 758 759 760
    //you can't use datum_.extend_obj_ here,
    //datum_.extend_obj_m is just to asign an ObObj pointer
    //here you need to set the address of the constructed datum array
    datum_.set_int(reinterpret_cast<int64_t>(datum_array));
O
oceanbase-admin 已提交
761
  }
W
wangzelin.wzl 已提交
762
  const ObSqlDatumArray *get_sql_datum_array() const
O
oceanbase-admin 已提交
763
  {
W
wangzelin.wzl 已提交
764 765 766 767 768 769 770 771
    ObSqlDatumArray *datum_array = nullptr;
    if (meta_.is_ext_sql_array()) {
      //you can't call get_ext() here, get_ext() in Datum is to get an ObObj pointer
      //here you need to get the address of the constructed datum array
      int64_t array_addr = datum_.get_int();
      datum_array = reinterpret_cast<ObSqlDatumArray*>(array_addr);
    }
    return datum_array;
O
oceanbase-admin 已提交
772
  }
W
wangzelin.wzl 已提交
773
  ObSqlDatumArray *get_sql_datum_array()
O
oceanbase-admin 已提交
774
  {
W
wangzelin.wzl 已提交
775 776 777 778 779 780 781 782
    ObSqlDatumArray *datum_array = nullptr;
    if (meta_.is_ext_sql_array()) {
      //you can't call get_ext() here, get_ext() in Datum is to get an ObObj pointer
      //here you need to get the address of the constructed datum array
      int64_t array_addr = datum_.get_int();
      datum_array = reinterpret_cast<ObSqlDatumArray*>(array_addr);
    }
    return datum_array;
O
oceanbase-admin 已提交
783
  }
W
wangzelin.wzl 已提交
784 785

  OB_INLINE void set_datum(const common::ObDatum &datum)
O
oceanbase-admin 已提交
786
  {
W
wangzelin.wzl 已提交
787
    datum_ = datum;
O
oceanbase-admin 已提交
788
  }
W
wangzelin.wzl 已提交
789 790

  OB_INLINE void set_meta(const ObDatumMeta &meta)
O
oceanbase-admin 已提交
791
  {
W
wangzelin.wzl 已提交
792
    meta_ = meta;
O
oceanbase-admin 已提交
793
  }
W
wangzelin.wzl 已提交
794 795 796 797 798 799
  // accuracy.
  OB_INLINE void set_accuracy(const common::ObAccuracy &accuracy) { accuracy_.set_accuracy(accuracy); }
  OB_INLINE void set_length(common::ObLength length) { accuracy_.set_length(length); }
  OB_INLINE void set_precision(common::ObPrecision precision) { accuracy_.set_precision(precision); }
  OB_INLINE void set_length_semantics(common::ObLengthSemantics length_semantics) { accuracy_.set_length_semantics(length_semantics); }
  OB_INLINE void set_scale(common::ObScale scale) {
O
oceanbase-admin 已提交
800 801 802
    ObDatumObj::set_scale(scale);
    accuracy_.set_scale(scale);
  }
W
wangzelin.wzl 已提交
803
  OB_INLINE void set_udt_id(uint64_t id) {
O
oceanbase-admin 已提交
804 805
    accuracy_.set_accuracy(id);
  }
W
wangzelin.wzl 已提交
806 807 808 809 810 811 812 813
  OB_INLINE const common::ObAccuracy &get_accuracy() const { return accuracy_; }
  OB_INLINE common::ObLength get_length() const { return accuracy_.get_length(); }
  OB_INLINE common::ObPrecision get_precision() const { return accuracy_.get_precision(); }
  OB_INLINE common::ObScale get_scale() const { return accuracy_.get_scale(); }
  OB_INLINE uint64_t get_udt_id() const {
    return meta_.type_ == static_cast<uint8_t>(common::ObExtendType)
           ? accuracy_.get_accuracy()
           : common::OB_INVALID_INDEX;
O
oceanbase-admin 已提交
814
  }
W
wangzelin.wzl 已提交
815 816 817 818
  OB_INLINE void set_result_flag(uint32_t flag) { res_flags_ |= flag; }
  OB_INLINE void unset_result_flag(uint32_t flag) { res_flags_ &= (~flag); }
  OB_INLINE bool has_result_flag(uint32_t flag) const { return res_flags_ & flag; }
  OB_INLINE uint32_t get_result_flag() const { return res_flags_; }
O
oceanbase-admin 已提交
819

W
wangzelin.wzl 已提交
820 821 822
  OB_INLINE const common::ParamFlag &get_param_flag() const { return flag_; }
  OB_INLINE void set_need_to_check_type(bool flag) { flag_.need_to_check_type_ = flag; }
  OB_INLINE bool need_to_check_type() const { return flag_.need_to_check_type_; }
O
oceanbase-admin 已提交
823

W
wangzelin.wzl 已提交
824 825
  OB_INLINE void set_need_to_check_bool_value(bool flag) { flag_.need_to_check_bool_value_ = flag; }
  OB_INLINE bool need_to_check_bool_value() const { return flag_.need_to_check_bool_value_; }
O
oceanbase-admin 已提交
826

W
wangzelin.wzl 已提交
827 828 829 830
  OB_INLINE void set_expected_bool_value(bool b_value) { flag_.expected_bool_value_ = b_value; }
  OB_INLINE bool expected_bool_value() const { return flag_.expected_bool_value_; }

  OB_INLINE bool is_nop_value() const { return false; }
O
oceanbase-admin 已提交
831 832 833

  NEED_SERIALIZE_AND_DESERIALIZE;

W
wangzelin.wzl 已提交
834 835 836
  static uint32_t accuracy_offset_bits() { return offsetof(ObDatumObjParam, accuracy_) * 8; }
  static uint32_t res_flags_offset_bits() { return offsetof(ObDatumObjParam, res_flags_) * 8; }
  static uint32_t flag_offset_bits() { return offsetof(ObDatumObjParam, flag_) * 8; }
O
oceanbase-admin 已提交
837

G
gm 已提交
838
private:
O
oceanbase-admin 已提交
839 840 841 842 843 844
  common::ObAccuracy accuracy_;
  uint32_t res_flags_;  // BINARY, NUM, NOT_NULL, TIMESTAMP, etc
                        // reference: src/lib/regex/include/mysql_com.h
  common::ParamFlag flag_;
};

W
wangzelin.wzl 已提交
845 846 847 848 849 850
typedef common::Ob2DArray<ObDatumObjParam,
                          common::OB_MALLOC_BIG_BLOCK_SIZE,
                          common::ObWrapperAllocator,
                          false,
                          common::ObSEArray<ObDatumObjParam *, 1, common::ObWrapperAllocator, false>
                          > DatumParamStore;
O
oceanbase-admin 已提交
851 852 853 854

// Helper function for print datum which interpreted by expression
// Can only be used in log message like this:
//    LOG_WARN(....., "datum", DATUM2STR(*expr, *datum))
W
wangzelin.wzl 已提交
855 856 857
struct ObToStringDatum
{
  ObToStringDatum(const ObExpr &e, const common::ObDatum &d) : e_(e), d_(d) {}
O
oceanbase-admin 已提交
858 859 860

  DECLARE_TO_STRING;

W
wangzelin.wzl 已提交
861 862
  const ObExpr &e_;
  const common::ObDatum  &d_;
O
oceanbase-admin 已提交
863 864 865 866 867 868 869
};
typedef ObToStringDatum DATUM2STR;

// Helper function for expression evaluate && print result
// Can only be used in log message like this:
//    LOG_WARN(....., "datum", EXPR2STR(eval_ctx_, *expr))
//
W
wangzelin.wzl 已提交
870 871 872 873 874 875 876 877
// 注意: 在ObExpr的eval_func_定义中不要使用该封装打印表达式值,
// 因为实现的eval_func中, 打印日志时, 如果调用ObToStringExpr(ctx, expr),
// 该函数又会调用eval_func计算, 不断循环调用, 且一直没走到设置evaluated_
// 标记为true的逻辑, 最终会导致爆栈;
// bug:https://work.aone.alibaba-inc.com/issue/29459333
struct ObToStringExpr
{
  ObToStringExpr(ObEvalCtx &ctx, const ObExpr &e) : c_(ctx), e_(e) {}
O
oceanbase-admin 已提交
878 879 880

  DECLARE_TO_STRING;

W
wangzelin.wzl 已提交
881 882
  ObEvalCtx &c_;
  const ObExpr &e_;
O
oceanbase-admin 已提交
883 884 885 886 887 888
};
typedef ObToStringExpr EXPR2STR;

// Helper function for expression array evaluate && print result
// Can only be used in log message like this:
//    LOG_WARN(......, "row", ROWEXPR2STR(eval_ctx_, output_)
W
wangzelin.wzl 已提交
889 890 891 892
struct ObToStringExprRow
{
  ObToStringExprRow(ObEvalCtx &ctx, const common::ObIArray<ObExpr *> &exprs)
      : c_(ctx), exprs_(exprs) { }
O
oceanbase-admin 已提交
893 894 895

  DECLARE_TO_STRING;

W
wangzelin.wzl 已提交
896 897
  ObEvalCtx &c_;
  const common::ObIArray<ObExpr *> &exprs_;
O
oceanbase-admin 已提交
898 899 900
};
typedef ObToStringExprRow ROWEXPR2STR;

W
wangzelin.wzl 已提交
901
OB_INLINE ObDatum &ObExpr::locate_datum_for_write(ObEvalCtx &ctx) const
O
oceanbase-admin 已提交
902 903
{
  // performance critical, do not check pointer validity.
W
wangzelin.wzl 已提交
904
	char *frame = ctx.frames_[frame_idx_];
O
oceanbase-admin 已提交
905
  OB_ASSERT(NULL != frame);
W
wangzelin.wzl 已提交
906 907 908 909 910
  const int64_t idx = get_datum_idx(ctx);
  ObDatum *expr_datum = reinterpret_cast<ObDatum *>(frame + datum_off_) + idx;
  char *data_pos = frame + res_buf_off_ + res_buf_len_ * idx;
  if (expr_datum->ptr_ != data_pos) {
    expr_datum->ptr_ = data_pos;
O
oceanbase-admin 已提交
911 912 913 914
  }
  return *expr_datum;
}

W
wangzelin.wzl 已提交
915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934
inline ObDatum *ObExpr::locate_datums_for_update(ObEvalCtx &ctx,
                                                 const int64_t size) const
{
  char *frame = ctx.frames_[frame_idx_];
  OB_ASSERT(NULL != frame);
  ObDatum *datums = reinterpret_cast<ObDatum *>(frame + datum_off_);
  char *ptr = frame + res_buf_off_;
  ObDatum *d = datums;
  for (int64_t i = 0; i < size; i++) {
    if (d->ptr_ != ptr) {
      d->ptr_ = ptr;
    }
    ptr += res_buf_len_;
    d++;
  }
  return datums;
}

template <typename ...TS>
OB_INLINE int ObExpr::eval_param_value(ObEvalCtx &ctx, TS &...args) const
O
oceanbase-admin 已提交
935 936
{
  int ret = common::OB_SUCCESS;
W
wangzelin.wzl 已提交
937 938
  common::ObDatum **params[] = { &args... };
  common::ObDatum *tmp = NULL;
O
oceanbase-admin 已提交
939
  for (int param_index = 0; OB_SUCC(ret) && param_index < arg_cnt_; param_index++) {
W
wangzelin.wzl 已提交
940 941 942 943
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Warray-bounds\"")
    if (OB_FAIL(args_[param_index]->eval(
                ctx, param_index < ARRAYSIZEOF(params) ? *params[param_index] : tmp))) {
O
oceanbase-admin 已提交
944 945
      SQL_LOG(WARN, "evaluate parameter failed", K(ret), K(param_index));
    }
W
wangzelin.wzl 已提交
946
_Pragma("GCC diagnostic pop")
O
oceanbase-admin 已提交
947 948 949 950
  }
  return ret;
}

W
wangzelin.wzl 已提交
951 952 953
template <typename ...TS>
OB_INLINE int ObExpr::eval_batch_param_value(ObEvalCtx &ctx, const ObBitVector &skip,
                                       const int64_t size, TS &...args) const
O
oceanbase-admin 已提交
954 955
{
  int ret = common::OB_SUCCESS;
W
wangzelin.wzl 已提交
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
  ObDatumVector *params[] = { &args...};
  for (int param_index = 0; OB_SUCC(ret) && param_index < arg_cnt_; param_index++) {
    if (OB_FAIL(args_[param_index]->eval_batch(ctx, skip, size))) {
      SQL_LOG(WARN, "evaluate parameter failed", K(ret), K(param_index));
    } else if (param_index < ARRAYSIZEOF(params)) {
      *params[param_index] = locate_param_datumvector(ctx, param_index);
    }
  }
  return ret;
}


OB_INLINE int ObExpr::eval(ObEvalCtx &ctx, common::ObDatum *&datum) const
{
  // performance critical, do not check %frame_idx_ and %frame again. (checked in CG)
	int ret = common::OB_SUCCESS;
	char *frame = ctx.frames_[frame_idx_];
O
oceanbase-admin 已提交
973
  OB_ASSERT(NULL != frame);
W
wangzelin.wzl 已提交
974 975
	datum = (ObDatum *)(frame + datum_off_);
  ObEvalInfo *eval_info = (ObEvalInfo *)(frame + eval_info_off_);
O
oceanbase-admin 已提交
976

W
wangzelin.wzl 已提交
977 978 979 980 981
  if (is_batch_result()) {
    if (NULL == eval_func_ || eval_info->projected_) {
      datum = datum + ctx.get_batch_idx();
    } else {
      ret = eval_one_datum_of_batch(ctx, datum);
O
oceanbase-admin 已提交
982
    }
W
wangzelin.wzl 已提交
983 984 985 986 987 988
  } else if (NULL != eval_func_ && !eval_info->evaluated_) {
	// do nothing for const/column reference expr or already evaluated expr
		if (datum->ptr_ != frame + res_buf_off_) {
			datum->ptr_ = frame + res_buf_off_;
		}
		ret = eval_func_(*this, ctx, *datum);
O
oceanbase-admin 已提交
989 990 991 992 993
    if (OB_LIKELY(common::OB_SUCCESS == ret)) {
      eval_info->evaluated_ = true;
    } else {
      datum->set_null();
    }
W
wangzelin.wzl 已提交
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
	}
	return ret;
}

OB_INLINE int ObExpr::eval_batch(ObEvalCtx &ctx,
                                 const ObBitVector &skip,
                                 const int64_t size) const
{
  int ret = common::OB_SUCCESS;
  const ObEvalInfo &info = get_eval_info(ctx);
  if (!is_batch_result()) {
    if (skip.accumulate_bit_cnt(size) < size) {
      common::ObDatum *datum = NULL;
      ret = eval(ctx, datum);
    } else {
      // all skiped
    }
  } else if (info.projected_ || NULL == eval_batch_func_) {
    // expr values is projected by child or has no evaluate func, do nothing.
  } else if (size > 0) {
    ret = do_eval_batch(ctx, skip, size);
O
oceanbase-admin 已提交
1015 1016 1017 1018
  }
  return ret;
}

W
wangzelin.wzl 已提交
1019
OB_INLINE int ObExpr::deep_copy_datum(ObEvalCtx &ctx, const common::ObDatum &datum) const
O
oceanbase-admin 已提交
1020 1021 1022 1023
{
  int ret = common::OB_SUCCESS;
  // shadow copy datum first, because %datum may overlay with %dst
  common::ObDatum src = datum;
W
wangzelin.wzl 已提交
1024
  ObDatum &dst = this->locate_datum_for_write(ctx);
O
oceanbase-admin 已提交
1025 1026 1027 1028 1029 1030 1031 1032
  dst.pack_ = src.pack_;
  if (!src.null_) {
    if (OB_UNLIKELY(src.len_ > res_buf_len_)) {
      // only string datum may exceed %res_buf_len_;
      if (OB_ISNULL(dst.ptr_ = get_str_res_mem(ctx, src.len_))) {
        ret = common::OB_ALLOCATE_MEMORY_FAILED;
        SQL_LOG(WARN, "allocate memory failed", K(ret));
      } else {
W
wangzelin.wzl 已提交
1033
        MEMMOVE(const_cast<char *>(dst.ptr_), src.ptr_, src.len_);
O
oceanbase-admin 已提交
1034 1035
      }
    } else {
W
wangzelin.wzl 已提交
1036
      MEMMOVE(const_cast<char *>(dst.ptr_), src.ptr_, src.len_);
O
oceanbase-admin 已提交
1037 1038 1039 1040 1041
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
inline const char *get_vectorized_row_str(ObEvalCtx &eval_ctx,
                                          const ObExprPtrIArray &exprs,
                                          int64_t index)
{
  char *buffer = NULL;
  int64_t pos = 0;
  CStringBufMgr *mgr = GET_TSI(CStringBufMgr);
  mgr->inc_level();
  CStringBufMgr::BufNode *node = mgr->acquire();
  if (OB_ISNULL(node)) {
    LIB_LOG(ERROR, "buffer is NULL");
  } else {
    buffer = node->buf_;
    databuff_printf(buffer, CStringBufMgr::BUF_SIZE, pos, "vectorized_rows(%ld)=", index);
    pos += to_string(ROWEXPR2STR(eval_ctx, exprs), buffer + pos, CStringBufMgr::BUF_SIZE -1);
    if (pos >= 0 && pos < CStringBufMgr::BUF_SIZE) {
      buffer[pos] = '\0';
    } else {
      buffer[0] = '\0';
    }
  }
  mgr->try_clear_list();
  mgr->dec_level();
  return buffer;
}

#define PRINT_VECTORIZED_ROWS(parMod, level, eval_ctx, exprs, batch_size, args...)       \
    do { if (IS_LOG_ENABLED(level)) {                                                            \
    [&](const char *_fun_name_) __attribute__((GET_LOG_FUNC_ATTR(level))) {                      \
    if (OB_UNLIKELY(OB_LOGGER.need_to_print(::oceanbase::common::OB_LOG_ROOT::M_##parMod,        \
                                            OB_LOG_LEVEL_##level)))                              \
    {                                                                                            \
      int64_t _batch_size = common::min(batch_size, (eval_ctx).get_batch_size());                \
      ObEvalCtx::BatchInfoScopeGuard _batch_info_guard(eval_ctx);                                \
      _batch_info_guard.set_batch_size(_batch_size);                                             \
      for (int64_t i = 0; i < _batch_size; ++i) {                                                \
        _batch_info_guard.set_batch_idx(i);                                                      \
        ::oceanbase::common::OB_PRINT("["#parMod"] ", OB_LOG_LEVEL(level),                       \
                                      get_vectorized_row_str(eval_ctx, exprs, i),                \
                                      LOG_KVS(args)); }                                          \
      }                                                                                          \
    }(__FUNCTION__); } } while (false)
} // end namespace sql
namespace common
{
namespace serialization
{
O
oceanbase-admin 已提交
1089 1090 1091 1092

// ObExpr pointer serialize && deserialize.
// Convert pointer to index of expr array, serialize && deserialize the index.
// The serialized index is the real index + 1, to make room for NULL.
W
wangzelin.wzl 已提交
1093
inline int64_t encoded_length(sql::ObExpr *)
O
oceanbase-admin 已提交
1094 1095 1096 1097
{
  return sizeof(uint32_t);
}

W
wangzelin.wzl 已提交
1098
inline int encode(char *buf, const int64_t buf_len, int64_t &pos, sql::ObExpr *expr)
O
oceanbase-admin 已提交
1099 1100 1101 1102
{
  int ret = common::OB_SUCCESS;
  uint32_t idx = 0;
  if (NULL != expr) {
W
wangzelin.wzl 已提交
1103 1104 1105
    sql::ObExpr::ObExprIArray *array = sql::ObExpr::get_serialize_array();
    if (OB_UNLIKELY(NULL == array || array->empty() || expr < &array->at(0)
                    || (idx = expr - &array->at(0) + 1) > array->count())) {
O
oceanbase-admin 已提交
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
      ret = OB_ERR_UNEXPECTED;
      SQL_LOG(WARN, "expr not in array", K(ret), KP(array), KP(idx), KP(expr));
    }
  }
  if (OB_SUCC(ret)) {
    ret = encode_i32(buf, buf_len, pos, idx);
  }
  return ret;
}

W
wangzelin.wzl 已提交
1116
inline int decode(const char *buf, const int64_t data_len, int64_t &pos, sql::ObExpr *&expr)
O
oceanbase-admin 已提交
1117 1118 1119
{
  int ret = common::OB_SUCCESS;
  uint32_t idx = 0;
W
wangzelin.wzl 已提交
1120
  ret = decode_i32(buf, data_len, pos, reinterpret_cast<int32_t *>(&idx));
O
oceanbase-admin 已提交
1121 1122 1123 1124
  if (OB_SUCC(ret)) {
    if (0 == idx) {
      expr = NULL;
    } else {
W
wangzelin.wzl 已提交
1125
      sql::ObExpr::ObExprIArray *array = sql::ObExpr::get_serialize_array();
O
oceanbase-admin 已提交
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
      if (OB_UNLIKELY(NULL == array) || OB_UNLIKELY(idx > array->count())) {
        ret = OB_ERR_UNEXPECTED;
        SQL_LOG(WARN, "expr index out of expr array range", K(ret), KP(array), K(idx));
      } else {
        expr = &array->at(idx - 1);
      }
    }
  }
  return ret;
}

template <>
W
wangzelin.wzl 已提交
1138 1139 1140
struct EnumEncoder<false, sql::ObExpr *>
{
  static int encode(char *buf, const int64_t buf_len, int64_t &pos, sql::ObExpr *expr)
O
oceanbase-admin 已提交
1141 1142 1143 1144
  {
    return serialization::encode(buf, buf_len, pos, expr);
  }

W
wangzelin.wzl 已提交
1145
  static int decode(const char *buf, const int64_t data_len, int64_t &pos, sql::ObExpr *&expr)
O
oceanbase-admin 已提交
1146 1147 1148 1149
  {
    return serialization::decode(buf, data_len, pos, expr);
  }

W
wangzelin.wzl 已提交
1150
  static int64_t encoded_length(sql::ObExpr *expr)
O
oceanbase-admin 已提交
1151 1152 1153 1154 1155
  {
    return serialization::encoded_length(expr);
  }
};

W
wangzelin.wzl 已提交
1156

O
oceanbase-admin 已提交
1157 1158 1159 1160 1161
//
// Simple c array wrapper for serialize && deserialize. e.g.:
//  OB_SERIALIZE_MEMBER(Foo, make_ser_carray(items_, item_cnt_))
//
template <typename T, typename U>
W
wangzelin.wzl 已提交
1162 1163 1164 1165 1166
struct ObSerCArray
{
  ObSerCArray(T &data, U &cnt) : data_(data), cnt_(cnt) {}
  T &data_;
  U &cnt_;
O
oceanbase-admin 已提交
1167 1168 1169
};

template <typename T, typename U>
W
wangzelin.wzl 已提交
1170 1171
ObSerCArray<T, U> make_ser_carray(T &data, U &cnt) { return ObSerCArray<T, U>(data, cnt); }

O
oceanbase-admin 已提交
1172 1173

template <typename T, typename U>
W
wangzelin.wzl 已提交
1174
inline int64_t encoded_length(const ObSerCArray<T *const, U> &array)
O
oceanbase-admin 已提交
1175 1176 1177 1178 1179 1180 1181
{
  int64_t len = 0;
  OB_UNIS_ADD_LEN_ARRAY(array.data_, array.cnt_);
  return len;
}

template <typename T, typename U>
W
wangzelin.wzl 已提交
1182 1183
inline int encode(char *buf, const int64_t buf_len, int64_t &pos,
                  const ObSerCArray<T *const, U> &array)
O
oceanbase-admin 已提交
1184 1185 1186 1187
{
  int ret = OB_SUCCESS;
  if (OB_UNLIKELY(array.cnt_ > 0 && NULL == array.data_)) {
    ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
1188 1189
    SQL_LOG(WARN, "array not empty but data is NULL",
            K(ret), KP(array.data_), K(array.cnt_));
O
oceanbase-admin 已提交
1190 1191 1192 1193 1194 1195 1196
  } else {
    OB_UNIS_ENCODE_ARRAY(array.data_, array.cnt_);
  }
  return ret;
}

template <typename T, typename U>
W
wangzelin.wzl 已提交
1197 1198
inline int decode(const char *buf, const int64_t data_len, int64_t &pos,
                  const ObSerCArray<T *, U> &array)
O
oceanbase-admin 已提交
1199 1200 1201 1202 1203 1204 1205 1206
{
  int ret = OB_SUCCESS;
  OB_UNIS_DECODE(array.cnt_);
  if (OB_SUCC(ret)) {
    if (0 == array.cnt_) {
      array.data_ = NULL;
    } else {
      const int64_t alloc_size = sizeof(*array.data_) * array.cnt_;
W
wangzelin.wzl 已提交
1207 1208
      array.data_ = static_cast<T *>(
          CURRENT_CONTEXT->get_arena_allocator().alloc(alloc_size));
O
oceanbase-admin 已提交
1209 1210 1211 1212 1213
      if (OB_ISNULL(array.data_)) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        SQL_LOG(WARN, "alloc memory failed", K(ret), K(alloc_size));
      } else {
        int64_t idx = 0;
W
wangzelin.wzl 已提交
1214
        for ( ; OB_SUCC(ret) && idx < array.cnt_; idx++) {
O
oceanbase-admin 已提交
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
          new (&array.data_[idx]) T();
          OB_UNIS_DECODE(array.data_[idx]);
        }
        // deconstruct the constructed objects.
        if (OB_SUCCESS != ret) {
          for (int64_t i = idx; i >= 0; i--) {
            array.data_[i].~T();
          }
        }
      }
    }
  }
  return ret;
}
W
wangzelin.wzl 已提交
1229 1230 1231
} // end namespace serialization
} // end namespace common
} // end namespace oceanbase
O
oceanbase-admin 已提交
1232

W
wangzelin.wzl 已提交
1233
#endif // OCEANBASE_EXPR_OB_EXPR_H_