Files
oceanbase/src/sql/resolver/expr/ob_raw_expr.h

4844 lines
171 KiB
C++

/**
* 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_SQL_RESOLVER_EXPR_RAW_EXPR_
#define OCEANBASE_SQL_RESOLVER_EXPR_RAW_EXPR_
#include "share/ob_define.h"
#include "lib/container/ob_bit_set.h"
#include "lib/string/ob_string.h"
#include "lib/container/ob_se_array.h"
#include "lib/hash_func/ob_hash_func.h"
#include "lib/list/ob_obj_store.h"
#include "lib/rc/context.h"
#include "common/ob_range.h"
#include "common/ob_accuracy.h"
#include "objit/expr/ob_iraw_expr.h"
#include "objit/expr/ob_const_expr.h"
#include "objit/expr/ob_var_expr.h"
#include "objit/expr/ob_op_expr.h"
#include "objit/expr/ob_column_ref_expr.h"
#include "objit/expr/ob_case_op_expr.h"
#include "sql/engine/expr/ob_expr_res_type.h"
#include "share/schema/ob_schema_utils.h"
#include "sql/ob_sql_define.h"
#include "sql/resolver/expr/ob_expr_info_flag.h"
#include "share/system_variable/ob_system_variable.h"
#include "share/schema/ob_udf.h"
#include "lib/worker.h"
#include "sql/parser/parse_node.h"
#include "sql/resolver/ob_resolver_define.h"
#include "sql/engine/expr/ob_expr_operator.h"
#include "sql/engine/expr/ob_expr_operator_factory.h"
#include "sql/code_generator/ob_static_engine_expr_cg.h"
#include "pl/ob_pl_type.h"
#include "share/schema/ob_trigger_info.h"
#include "sql/engine/expr/ob_expr_join_filter.h"
#include "sql/engine/expr/ob_expr_calc_partition_id.h"
#include "sql/resolver/dml/ob_raw_expr_sets.h"
namespace oceanbase
{
namespace share
{
namespace schema
{
class ObSchemaGetterGuard;
}
}
namespace pl
{
class ObPLCodeGenerator;
}
namespace sql
{
class ObStmt;
class ObCallProcedureInfo;
class ObSQLSessionInfo;
class ObExprOperator;
class ObRawExprFactory;
class ObIRawExprCopier;
class ObSelectStmt;
class ObRTDatumArith;
class ObLogicalOperator;
extern ObRawExpr *USELESS_POINTER;
// If is_stack_overflow is true, the printing will not continue
#ifndef DEFINE_VIRTUAL_TO_STRING_CHECK_STACK_OVERFLOW
#define DEFINE_VIRTUAL_TO_STRING_CHECK_STACK_OVERFLOW(body) DECLARE_VIRTUAL_TO_STRING \
{ \
int ret = common::OB_SUCCESS; \
int64_t pos = 0; \
bool is_stack_overflow = false; \
if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { \
SQL_RESV_LOG(WARN, "failed to check stack overflow", K(ret), K(is_stack_overflow)); \
} else if (is_stack_overflow) { \
SQL_RESV_LOG(DEBUG, "too deep recursive", K(ret), K(is_stack_overflow)); \
} else { \
J_OBJ_START(); \
body; \
J_OBJ_END(); \
} \
return pos; \
}
#define VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(args...) DEFINE_VIRTUAL_TO_STRING_CHECK_STACK_OVERFLOW(J_KV(args))
#endif
#define IS_SPATIAL_OP(op) \
(((op) == T_FUN_SYS_ST_INTERSECTS) \
|| ((op) == T_FUN_SYS_ST_COVERS) \
|| ((op) == T_FUN_SYS_ST_DWITHIN) \
|| ((op) == T_FUN_SYS_ST_WITHIN) \
|| ((op) == T_FUN_SYS_ST_CONTAINS)) \
#define IS_MYSQL_GEO_OP(op) \
(((op) == T_FUN_SYS_ST_GEOMFROMTEXT) \
|| ((op) == T_FUN_SYS_ST_INTERSECTION) \
|| ((op) == T_FUN_SYS_ST_AREA) \
|| ((op) == T_FUN_SYS_ST_INTERSECTS) \
|| ((op) == T_FUN_SYS_ST_X) \
|| ((op) == T_FUN_SYS_ST_Y) \
|| ((op) == T_FUN_SYS_ST_LATITUDE) \
|| ((op) == T_FUN_SYS_ST_LONGITUDE) \
|| ((op) == T_FUN_SYS_ST_TRANSFORM) \
|| ((op) == T_FUN_SYS_POINT) \
|| ((op) == T_FUN_SYS_LINESTRING) \
|| ((op) == T_FUN_SYS_MULTIPOINT) \
|| ((op) == T_FUN_SYS_MULTILINESTRING) \
|| ((op) == T_FUN_SYS_POLYGON) \
|| ((op) == T_FUN_SYS_MULTIPOLYGON) \
|| ((op) == T_FUN_SYS_GEOMCOLLECTION) \
|| ((op) == T_FUN_SYS_ST_COVERS) \
|| ((op) == T_FUN_SYS_ST_ASTEXT) \
|| ((op) == T_FUN_SYS_ST_BUFFER_STRATEGY) \
|| ((op) == T_FUN_SYS_ST_BUFFER) \
|| ((op) == T_FUN_SYS_SPATIAL_CELLID) \
|| ((op) == T_FUN_SYS_SPATIAL_MBR) \
|| ((op) == T_FUN_SYS_ST_GEOMFROMEWKB) \
|| ((op) == T_FUN_SYS_ST_GEOMFROMWKB) \
|| ((op) == T_FUN_SYS_ST_GEOMETRYFROMWKB) \
|| ((op) == T_FUN_SYS_ST_GEOMFROMEWKT) \
|| ((op) == T_FUN_SYS_ST_SRID) \
|| ((op) == T_FUN_SYS_ST_ASWKT) \
|| ((op) == T_FUN_SYS_ST_DISTANCE) \
|| ((op) == T_FUN_SYS_ST_GEOMETRYFROMTEXT) \
|| ((op) == T_FUN_SYS_ST_ISVALID) \
|| ((op) == T_FUN_SYS_ST_ASWKB) \
|| ((op) == T_FUN_SYS_ST_ASBINARY) \
|| ((op) == T_FUN_SYS_ST_DISTANCE_SPHERE) \
|| ((op) == T_FUN_SYS_ST_DWITHIN) \
|| ((op) == T_FUN_SYS_ST_WITHIN) \
|| ((op) == T_FUN_SYS_ST_CONTAINS)) \
#define IS_PRIV_GEO_OP(op) \
(((op) == T_FUN_SYS_PRIV_ST_BUFFER) \
|| ((op) == T_FUN_SYS_PRIV_ST_ASEWKB) \
|| ((op) == T_FUN_SYS_PRIV_ST_TRANSFORM) \
|| ((op) == T_FUN_SYS_PRIV_ST_SETSRID) \
|| ((op) == T_FUN_SYS_PRIV_ST_BESTSRID) \
|| ((op) == T_FUN_SYS_PRIV_ST_POINT) \
|| ((op) == T_FUN_SYS_PRIV_ST_GEOGFROMTEXT) \
|| ((op) == T_FUN_SYS_PRIV_ST_GEOGRAPHYFROMTEXT) \
|| ((op) == T_FUN_SYS_PRIV_ST_ASEWKT)) \
#define IS_GEO_OP(op) ((IS_MYSQL_GEO_OP(op)) || IS_PRIV_GEO_OP(op))
#define IS_XML_OP(op) \
(((op) == T_FUN_SYS_XML_ELEMENT) \
|| ((op) == T_FUN_SYS_XMLPARSE)) \
#define IS_SPATIAL_EXPR(op) \
((op) >= T_FUN_SYS_ST_LONGITUDE && (op) <= T_FUN_SYS_ST_LATITUDE)
// ObSqlBitSet is a simple bitset, in order to avoid memory explosure
// ObBitSet is too large just for a simple bitset
const static int64_t DEFAULT_SQL_BITSET_SIZE = 32;
template<int64_t N = DEFAULT_SQL_BITSET_SIZE,
typename FlagType = int64_t,
bool auto_free = false>
class ObSqlBitSet
{
public:
typedef uint32_t BitSetWord;
ObSqlBitSet()
:block_allocator_(NULL), bit_set_word_array_(NULL), desc_()
{
int ret = OB_SUCCESS;
if (OB_FAIL(init_block_allocator())) {
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "failed to init block allocator", K(ret));
} else if (OB_ISNULL(block_allocator_)) {
ret = OB_INVALID_ARGUMENT;
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "invalid argument", K(ret));
} else {
int64_t words_size = sizeof(BitSetWord) * MAX_BITSETWORD;
if (OB_ISNULL(bit_set_word_array_ = (BitSetWord *)block_allocator_->alloc(words_size))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "failed to alloc memory", K(ret));
} else {
MEMSET(bit_set_word_array_, 0, words_size);
desc_.cap_ = static_cast<int16_t>(MAX_BITSETWORD);
desc_.len_ = 0;
desc_.inited_ = true;
}
}
}
ObSqlBitSet(const ObSqlBitSet<N, FlagType, auto_free> &other)
: block_allocator_(NULL), bit_set_word_array_(NULL), desc_()
{
int ret = OB_SUCCESS;
if (!other.is_valid()) {
desc_.init_errcode_ = other.desc_.init_errcode_;
SQL_RESV_LOG(WARN, "other not intied", K(other.desc_.init_errcode_));
} else if (OB_FAIL(init_block_allocator())) {
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "failed to init block allocator", K(ret));
} else if (OB_ISNULL(block_allocator_)) {
ret = OB_INVALID_ARGUMENT;
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "block_allocator_ is null", K(ret));
} else {
int64_t cap = other.bitset_word_count() * 2;
if (cap <= 0) {
cap = MAX_BITSETWORD;
}
int64_t words_size = sizeof(BitSetWord) * cap;
if (OB_ISNULL(bit_set_word_array_ = (BitSetWord *)block_allocator_->alloc(words_size))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "failed to alloc memory", K(ret));
} else {
MEMSET(bit_set_word_array_, 0, words_size);
for (int64_t i = 0; i < other.bitset_word_count(); i++) {
bit_set_word_array_[i] = other.get_bitset_word(i);
}
desc_.len_ = static_cast<int16_t>(other.bitset_word_count());
desc_.cap_ = static_cast<int16_t>(cap);
desc_.inited_ = true;
}
}
}
explicit ObSqlBitSet(const int64_t bit_size)
:block_allocator_(NULL), bit_set_word_array_(NULL), desc_()
{
int ret = OB_SUCCESS;
if (bit_size < 0) {
ret = OB_INVALID_ARGUMENT;
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "invalid argument", K(ret));
} else if (OB_FAIL(init_block_allocator())) {
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "failed to init block allocator", K(ret));
} else {
int64_t bitset_word_cnt = (bit_size <= N ? MAX_BITSETWORD
: ((bit_size - 1) / PER_BITSETWORD_BITS + 1));
int64_t words_size = sizeof(BitSetWord) * bitset_word_cnt;
if (OB_ISNULL(bit_set_word_array_ = (BitSetWord *)block_allocator_->alloc(words_size))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
desc_.init_errcode_ = ret;
SQL_RESV_LOG(WARN, "failed to alloc memory", K(ret));
} else {
MEMSET(bit_set_word_array_, 0, words_size);
desc_.len_ = 0;
desc_.cap_ = static_cast<int16_t>(bitset_word_cnt);
desc_.inited_ = true;
}
}
}
~ObSqlBitSet()
{
destroy();
}
void reset()
{
reuse();
}
uint64_t hash() const
{
uint64_t hash_val = 0;
for (int64_t i = 0; i < desc_.len_; i++) {
hash_val = murmurhash(&bit_set_word_array_[i],
sizeof(bit_set_word_array_[i]),
hash_val);
}
return hash_val;
}
int hash(uint64_t &hash_val) const { hash_val = hash(); return OB_SUCCESS; }
void reuse()
{
if (is_valid()) {
if (NULL != bit_set_word_array_ && desc_.len_ > 0) {
MEMSET(bit_set_word_array_, 0, desc_.len_ * sizeof(BitSetWord));
}
desc_.len_ = 0;
}
}
void destroy()
{
if (is_valid()) {
if (auto_free) {
// auto_free = true, context allocator is used,
// free memory is just useless
// do nothing
} else {
// free memory
if (NULL != block_allocator_ && NULL != bit_set_word_array_) {
block_allocator_->free(bit_set_word_array_);
}
if (NULL != block_allocator_) {
block_allocator_->reset();
ob_free(block_allocator_);
}
block_allocator_ = NULL;
bit_set_word_array_ = NULL;
}
desc_.len_ = 0;
desc_.cap_ = 0;
desc_.inited_ = false;
}
}
int64_t bitset_word_count() const { return static_cast<int64_t>(desc_.len_); }
int64_t bit_count() const { return static_cast<int64_t>(desc_.len_) * PER_BITSETWORD_BITS; }
bool is_empty() const { return 0 == num_members(); }
bool is_valid() const { return desc_.inited_; }
void clear_all()
{
if (!is_valid()) {
// do nothing
} else {
MEMSET(bit_set_word_array_, 0, desc_.len_ * sizeof(BitSetWord));
}
}
BitSetWord get_bitset_word(int64_t index) const
{
BitSetWord word = 0;
if (!is_valid()) {
SQL_RESV_LOG_RET(WARN, OB_NOT_INIT, "not inited", K(desc_.init_errcode_));
} else if (index < 0 || index >= desc_.len_) {
SQL_RESV_LOG_RET(WARN, OB_ERR_UNEXPECTED, "bitmap word index exceeds scope", K(index), K(desc_.len_));
} else {
word = bit_set_word_array_[index];
}
return word;
}
int64_t num_members() const
{
int64_t num = 0;
BitSetWord word = 0;
if (!is_valid()) {
// do nothing
} else {
for (int64_t i = 0; i < desc_.len_; i++) {
word = bit_set_word_array_[i];
if (0 == word) {
// do nothing
} else {
word = (word & UINT32_C(0x55555555)) + ((word >> 1) & UINT32_C(0x55555555));
word = (word & UINT32_C(0x33333333)) + ((word >> 2) & UINT32_C(0x33333333));
word = (word & UINT32_C(0x0f0f0f0f)) + ((word >> 4) & UINT32_C(0x0f0f0f0f));
word = (word & UINT32_C(0x00ff00ff)) + ((word >> 8) & UINT32_C(0x00ff00ff));
word = (word & UINT32_C(0x0000ffff)) + ((word >> 16) & UINT32_C(0x0000ffff));
num += (int64_t)word;
}
}
}
return num;
}
bool has_member(int64_t index) const
{
bool bool_ret = false;
if (!is_valid()) {
// do nothing
} else if (OB_UNLIKELY(index < 0)) {
SQL_RESV_LOG_RET(WARN, OB_INVALID_ARGUMENT, "negative bitmap member not allowed");
} else {
int64_t pos = index >> PER_BITSETWORD_MOD_BITS;
if (pos >= desc_.len_) {
// dp nothing
} else {
bool_ret = (bit_set_word_array_[pos]
& ((BitSetWord) 1 << (index & PER_BITSETWORD_MASK))) != 0;
}
}
return bool_ret;
}
int add_member(int64_t index)
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "got init error", K(desc_.init_errcode_));
} else if (OB_UNLIKELY (index < 0)) {
ret = OB_INVALID_ARGUMENT;
SQL_RESV_LOG(WARN, "negative bitmap member not allowed", K(ret), K(index));
} else {
int64_t pos = index >> PER_BITSETWORD_MOD_BITS;
if (OB_UNLIKELY(pos >= desc_.cap_)) {
int64_t new_word_cnt = pos * 2;
if (OB_FAIL(alloc_new_buf(new_word_cnt))) {
SQL_RESV_LOG(WARN, "failed to alloc new buf", K(ret));
}
}
if (OB_SUCC(ret)) {
if (pos >= desc_.len_) {
desc_.len_ = static_cast<int16_t>(pos) + 1;
}
bit_set_word_array_[pos] |= ((BitSetWord) 1 << (index & PER_BITSETWORD_MASK));
}
}
return ret;
}
int del_member(int64_t index)
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "got init error", K(desc_.init_errcode_));
} else if (OB_UNLIKELY(index < 0)) {
ret = common::OB_INVALID_ARGUMENT;
SQL_RESV_LOG(WARN, "negative bitmap member not allowed", K(ret), K(index));
} else {
int64_t pos = index >> PER_BITSETWORD_MOD_BITS;
if (OB_UNLIKELY(pos >= desc_.len_)) {
// do nothing
} else {
bit_set_word_array_[pos] &= ~((BitSetWord) 1 << (index & PER_BITSETWORD_MASK));
}
}
return ret;
}
int do_mask(int64_t begin_index, int64_t end_index)
{
int ret = OB_SUCCESS;
int64_t max_bit_count = static_cast<int64_t>(desc_.len_) * PER_BITSETWORD_BITS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "got init error", K(desc_.init_errcode_));
} else if (begin_index < 0 || begin_index >= max_bit_count
|| end_index < 0 || end_index >= max_bit_count) {
ret = OB_INVALID_ARGUMENT;
SQL_RESV_LOG(WARN, "invalid argument", K(ret), K(begin_index), K(end_index), K(max_bit_count));
} else {
int64_t begin_word = begin_index / PER_BITSETWORD_BITS;
int64_t end_word = end_index / PER_BITSETWORD_BITS;
int64_t begin_pos = begin_index % PER_BITSETWORD_BITS;
int64_t end_pos = end_index % PER_BITSETWORD_BITS;
for (int64_t i = 0; i < begin_word; i++) {
bit_set_word_array_[i] = 0;
}
for (int64_t i = desc_.len_ - 1; i > end_word; i--) {
bit_set_word_array_[i] = 0;
}
for (int64_t i = 0; i < begin_pos; i++) {
bit_set_word_array_[begin_word] &= ~((BitSetWord) 1 << i);
}
for (int64_t i = 1 + end_pos; i < PER_BITSETWORD_BITS; i++) {
bit_set_word_array_[end_word] &= ~((BitSetWord) 1 << i);
}
}
return ret;
}
template<int64_t M, typename FlagType2, bool auto_free2>
int add_members(const ObSqlBitSet<M, FlagType2, auto_free2> &other)
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "got init error", K(desc_.init_errcode_));
} else if (OB_ISNULL(bit_set_word_array_)) {
ret = common::OB_INVALID_ARGUMENT;
SQL_RESV_LOG(WARN, "invalid argument", K(ret), K(bit_set_word_array_));
} else {
int64_t this_count = desc_.len_;
int64_t that_count = other.bitset_word_count();
if (this_count < that_count) {
if (desc_.cap_ >= that_count) {
// do nothing
} else {
int64_t new_word_cnt = that_count * 2;
if (OB_FAIL(alloc_new_buf(new_word_cnt))) {
SQL_RESV_LOG(WARN, "failed to alloc new buffer", K(ret));
}
}
}
if (OB_SUCC(ret) && that_count >= desc_.len_) {
desc_.len_ = static_cast<int16_t>(that_count);
}
if (OB_FAIL(ret)) {
// do nothing
} else {
for (int64_t i = 0; i < that_count; i++) {
bit_set_word_array_[i] |= other.get_bitset_word(i);
}
}
}
return ret;
}
template<int64_t M, typename FlagType2, bool auto_free2>
int add_members2(const ObSqlBitSet<M, FlagType2, auto_free2> &other)
{
return add_members(other);
}
template<int64_t M, typename FlagType2, bool auto_free2>
int del_members(const ObSqlBitSet<M, FlagType2, auto_free2> &other)
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "got init error", K(desc_.init_errcode_));
} else {
for (int64_t i = 0; i < desc_.len_; i++) {
bit_set_word_array_[i] &= ~(other.get_bitset_word(i));
}
}
return ret;
}
template<int64_t M, typename FlagType2, bool auto_free2>
int del_members2(const ObSqlBitSet<M, FlagType2, auto_free2> &other)
{
return del_members(other);
}
template<int64_t M, typename FlagType2, bool auto_free2>
int intersect_members(const ObSqlBitSet<M, FlagType2, auto_free2> &other)
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = common::OB_NOT_INIT;
SQL_RESV_LOG(WARN, "not inited", K(ret));
} else {
for (int64_t i = 0; i < desc_.len_; i++) {
bit_set_word_array_[i] &= (other.get_bitset_word(i));
}
}
return ret;
}
int reserve_first() {
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = OB_NOT_INIT;
SQL_RESV_LOG(WARN, "not inited", K(ret));
} else {
bool find = false;
int64_t num = 0;
for (int64_t i = 0; i < desc_.len_; i++) {
BitSetWord& word = bit_set_word_array_[i];
if (word == 0) {
// do nothing
} else if (find) {
word &= 0;
} else {
for (int64_t j = 0; !find && j < PER_BITSETWORD_BITS; j ++) {
if (word & ((BitSetWord) 1 << j)) {
word &= ((BitSetWord) 1 << j);
find = true;
}
}
}
}
}
return ret;
}
template <int64_t M, typename FlagType2, bool auto_free2>
bool is_subset(const ObSqlBitSet<M, FlagType2, auto_free2> &other) const
{
bool bool_ret = true;
if (!is_valid()) {
// do nothing
} else if (is_empty()) {
bool_ret = true;
} else if (other.is_empty()) {
bool_ret = false;
} else if (desc_.len_ > other.bitset_word_count()) {
bool_ret = false;
} else {
for (int64_t i = 0; bool_ret && i < desc_.len_; i++) {
if ((bit_set_word_array_[i] & (~(other.get_bitset_word(i)))) != 0) {
bool_ret = false;
}
}
}
return bool_ret;
}
template <int64_t M, typename FlagType2, bool auto_free2>
bool is_subset2(const ObSqlBitSet<M, FlagType2, auto_free2> &other) const
{
return is_subset(other);
}
template <int64_t M, typename FlagType2, bool auto_free2>
bool is_superset(const ObSqlBitSet<M, FlagType2, auto_free2> &other) const
{
bool bool_ret = false;
if (!is_valid()) {
// do nothing
} else if (is_empty()) {
bool_ret = false;
} else if (other.is_empty()) {
bool_ret = true;
} else if (desc_.len_ < other.bitset_word_count()) {
bool_ret = false;
} else {
bool_ret = true;
for (int64_t i = 0; bool_ret && i < other.bitset_word_count(); i++) {
if (((~bit_set_word_array_[i]) & other.get_bitset_word(i)) != 0) {
bool_ret = false;
}
}
}
return bool_ret;
}
template <int64_t M, typename FlagType2, bool auto_free2>
bool is_superset2(const ObSqlBitSet<M, FlagType2, auto_free2> &other) const
{
return is_superset(other);
}
template<int64_t M, typename FlagType2, bool auto_free2>
bool overlap(const ObSqlBitSet<M, FlagType2, auto_free2> &other) const
{
bool bool_ret = false;
if (!is_valid()) {
// do nothing
} else {
int64_t min_bitset_word_count = std::min(static_cast<int64_t>(desc_.len_), other.bitset_word_count());
for (int64_t i = 0; !bool_ret && i < min_bitset_word_count; i++) {
if ((bit_set_word_array_[i] & (other.get_bitset_word(i))) != 0) {
bool_ret = true;
}
}
}
return bool_ret;
}
template<int64_t M, typename FlagType2, bool auto_free2>
bool overlap2(const ObSqlBitSet<M, FlagType2, auto_free2> &other) const
{
return overlap(other);
}
int to_array(ObIArray<int64_t> &arr) const
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "got init error", K(desc_.init_errcode_));
} else {
arr.reuse();
int64_t num = num_members();
int64_t count = 0;
int64_t max_bit_count = desc_.len_ * PER_BITSETWORD_BITS;
for (int64_t i = 0; OB_SUCC(ret) && count < num && i < max_bit_count; i++) {
if (has_member(i)) {
if (OB_FAIL(arr.push_back(i))) {
SQL_RESV_LOG(WARN, "failed to push back element", K(ret));
} else {
count++;
}
}
} // for end
}
return ret;
}
template<int64_t M, typename FlagType2, bool auto_free2>
bool equal(const ObSqlBitSet<M, FlagType2, auto_free2> &other) const
{
bool bool_ret = true;
if (!is_valid() || !other.is_valid()) {
bool_ret = false;
} else if (bitset_word_count() != other.bitset_word_count()) {
bool_ret = false;
} else {
for (int64_t i = 0; bool_ret && i < bitset_word_count(); i++) {
if (get_bitset_word(i) != other.get_bitset_word(i)) {
bool_ret = false;
}
}
}
return bool_ret;
}
bool operator==(const ObSqlBitSet<N, FlagType, auto_free> &other) const
{
return this->equal(other);
}
bool operator!=(const ObSqlBitSet<N, FlagType, auto_free> &other) const
{
return !(*this == other);
}
template<int64_t M, typename FlagType2, bool auto_free2,
int64_t L, typename FlagType3, bool auto_free3 >
int intersect(const ObSqlBitSet<M, FlagType2, auto_free2> &left,
const ObSqlBitSet<L, FlagType3, auto_free3> &right)
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "init error", K(desc_.init_errcode_));
} else if (!left.is_valid()) {
ret = left.desc_.init_errcode_;
SQL_RESV_LOG(WARN, "left init error", K(left.desc_.init_errcode_));
} else if (!right.is_valid()) {
ret = right.desc_.init_errcode_;
SQL_RESV_LOG(WARN, "right init error", K(right.desc_.init_errcode_));
} else if (OB_ISNULL(bit_set_word_array_)) {
ret = common::OB_INVALID_ARGUMENT;
SQL_RESV_LOG(WARN, "invalid argument", K(ret), K(bit_set_word_array_));
} else {
reset();
int64_t that_count = left.bitset_word_count() < right.bitset_word_count() ?
left.bitset_word_count() : right.bitset_word_count() ;
if (desc_.cap_ < that_count) {
int64_t new_word_cnt = that_count * 2;
if (OB_FAIL(alloc_new_buf(new_word_cnt))) {
SQL_RESV_LOG(WARN, "failed to alloc new buffer", K(ret));
}
}
if (OB_FAIL(ret)) {
// do nothing
} else {
for (int64_t i = 0; i < that_count; i++) {
bit_set_word_array_[i] = left.get_bitset_word(i) & right.get_bitset_word(i);
}
desc_.len_ = static_cast<int16_t>(that_count);
}
}
return ret;
}
template<int64_t M, typename FlagType2, bool auto_free2,
int64_t L, typename FlagType3, bool auto_free3 >
int except(const ObSqlBitSet<M, FlagType2, auto_free2> &left,
const ObSqlBitSet<L, FlagType3, auto_free3> &right)
{
int ret = common::OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "init error", K(desc_.init_errcode_));
} else if (!left.is_valid()) {
ret = left.desc_.init_errcode_;
SQL_RESV_LOG(WARN, "left init error", K(left.desc_.init_errcode_));
} else if (!right.is_valid()) {
ret = right.desc_.init_errcode_;
SQL_RESV_LOG(WARN, "right init error", K(right.desc_.init_errcode_));
} else if (OB_ISNULL(bit_set_word_array_)) {
ret = common::OB_INVALID_ARGUMENT;
SQL_RESV_LOG(WARN, "invalid argument", K(ret), K(bit_set_word_array_));
} else {
reset();
int64_t that_count = left.bitset_word_count();
if (desc_.cap_ < that_count) {
int64_t new_word_cnt = that_count * 2;
if (OB_FAIL(alloc_new_buf(new_word_cnt))) {
SQL_RESV_LOG(WARN, "failed to alloc new buffer", K(ret));
}
}
if (OB_FAIL(ret)) {
// do nothing
} else {
int64_t i = 0;
for (; i < left.bitset_word_count() && i < right.bitset_word_count(); i++) {
bit_set_word_array_[i] = left.get_bitset_word(i) ^ (left.get_bitset_word(i) & right.get_bitset_word(i));
}
for (; i < left.bitset_word_count(); i++) {
bit_set_word_array_[i] = left.get_bitset_word(i);
}
desc_.len_ = static_cast<int16_t>(that_count);
}
}
return ret;
}
static int databuff_print_obj(char *buf, const int64_t buf_len, int64_t &pos, const int64_t &obj)
{
return common::databuff_print_obj(buf, buf_len, pos, obj);
}
static int databuff_print_obj(char *buf, const int64_t buf_len, int64_t &pos, const ObExprInfoFlag &flag)
{
return common::databuff_printf(buf, buf_len, pos, "\"%s\"", get_expr_info_flag_str(flag));
}
int64_t to_string(char *buf, const int64_t buf_len) const
{
int ret = common::OB_SUCCESS;
int64_t pos = 0;
J_ARRAY_START();
int64_t num = num_members();
int64_t count = 0;
for (int64_t i = 0; i < bit_count(); i++) {
if (has_member(i)) {
if (count != 0 && count < num) {
J_COMMA();
}
FlagType flag = static_cast<FlagType>(i);
if (OB_FAIL(databuff_print_obj(buf, buf_len, pos, flag))) {
SQL_RESV_LOG(WARN, "databuff print obj failed", K(ret));
}
++count;
}
}
J_ARRAY_END();
return pos;
}
ObSqlBitSet<N, FlagType, auto_free>& operator=(const ObSqlBitSet<N, FlagType, auto_free> &other)
{
int ret = OB_SUCCESS;
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "init error", K(desc_.init_errcode_));
} else if (!other.is_valid()) {
ret = other.desc_.init_errcode_;
SQL_RESV_LOG(WARN, "init error", K(other.desc_.init_errcode_));
} else if (&other == this) {
// do nothing
} else {
if (other.bitset_word_count() > desc_.cap_) {
int64_t new_word_cnt = other.bitset_word_count() * 2;
if (OB_FAIL(alloc_new_buf(new_word_cnt))) {
SQL_RESV_LOG(WARN, "failed to alloc new buf", K(ret));
}
}
for (int64_t i = 0; OB_SUCC(ret) && i < other.bitset_word_count(); i++) {
bit_set_word_array_[i] = other.get_bitset_word(i);
}
desc_.len_ = static_cast<int16_t>(other.bitset_word_count());
}
if (OB_FAIL(ret)) {
// error happened, set inited flag to be false
desc_.init_errcode_ = ret;
desc_.inited_ = false;
}
return *this;
}
private:
int alloc_new_buf(int64_t word_cnt)
{
int ret = OB_SUCCESS;
int64_t words_size = sizeof(BitSetWord) * word_cnt;
BitSetWord *new_buf = NULL;
ObIAllocator *allocator = get_block_allocator();
if (!is_valid()) {
ret = desc_.init_errcode_;
SQL_RESV_LOG(WARN, "not inited", K(ret));
} else if (OB_ISNULL(allocator)) {
ret = OB_ERR_UNEXPECTED;
SQL_RESV_LOG(WARN, "invalid allocator", K(ret));
} else if (OB_ISNULL(new_buf = (BitSetWord *)allocator->alloc(words_size))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
SQL_RESV_LOG(WARN, "failed to alloc memory", K(ret));
} else {
MEMSET(new_buf, 0, words_size);
MEMCPY(new_buf, bit_set_word_array_, desc_.len_ * sizeof(BitSetWord));
// set word array to new buffer
allocator->free(bit_set_word_array_);
bit_set_word_array_ = new_buf;
desc_.cap_ = static_cast<int16_t>(word_cnt);
}
return ret;
}
ObIAllocator *get_block_allocator()
{
ObIAllocator *ret_alloc = NULL;
if (!is_valid()) {
// do nothing
} else {
ret_alloc = block_allocator_;
}
return ret_alloc;
}
int init_block_allocator()
{
int ret = OB_SUCCESS;
if (is_valid()) {
ret = OB_INIT_TWICE;
SQL_RESV_LOG(WARN, "init twice", K(ret));
} else if (auto_free) {
block_allocator_ = &CURRENT_CONTEXT->get_arena_allocator();
} else {
void *alloc_buf = NULL;
if (OB_ISNULL(alloc_buf = ob_malloc(sizeof(ObArenaAllocator), ObModIds::OB_BIT_SET))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
SQL_RESV_LOG(WARN, "failed to allocate memory", K(ret));
} else {
block_allocator_ = new(alloc_buf)ObArenaAllocator(ObModIds::OB_BIT_SET);
}
}
return ret;
}
private:
template<int64_t N2, typename FlagType2, bool auto_free2>
friend struct ObSqlBitSet;
static const int64_t PER_BITSETWORD_BITS = 32;
static const int64_t PER_BITSETWORD_MOD_BITS = 5;
static const int64_t PER_BITSETWORD_MASK = PER_BITSETWORD_BITS - 1;
static const int64_t MAX_BITSETWORD = ((N <= 0 ? DEFAULT_SQL_BITSET_SIZE : N) - 1)
/ PER_BITSETWORD_BITS + 1;
struct SqlBitSetDesc
{
union
{
int32_t init_errcode_;
struct
{
int16_t len_;
int16_t cap_;
};
};
bool inited_;
SqlBitSetDesc() : len_(0), cap_(0), inited_(false)
{}
};
private:
ObIAllocator *block_allocator_;
BitSetWord *bit_set_word_array_;
SqlBitSetDesc desc_;
};
typedef ObSqlBitSet<96, ObExprInfoFlag, true> ObExprInfo;
class ObUDFRawExpr;
struct ObUDFInfo
{
ObUDFInfo() :
udf_name_(),
udf_package_(),
udf_database_(),
param_names_(),
param_exprs_(),
udf_param_num_(0),
ref_expr_(NULL),
is_udt_udf_(false),
is_contain_self_param_(false),
is_udt_udf_inside_pkg_(false),
is_new_keyword_used_(false),
flag_(0) {}
void set_is_udf_udt_static() {
flag_ |= UDF_UDT_STATIC;
}
bool is_udf_udt_member() const {
return is_udt_udf_ && !(flag_ & UDF_UDT_STATIC);
}
void set_is_udf_udt_cons() {
is_udt_udf_ = true;
flag_ |= UDF_UDT_CONS;
}
bool is_udf_udt_cons() const {
return is_udt_udf_ && !!(flag_ & UDF_UDT_CONS);
}
void clear_is_udf_udt_cons() {
flag_ &= ~UDF_UDT_CONS;
}
void set_is_udt_overload_default_cons() {
flag_ |= UDF_UDT_CONS_OVERLOAD_DEFAULT;
}
bool is_udt_overload_default_cons() {
return is_udf_udt_cons() && !!(flag_ & UDF_UDT_CONS_OVERLOAD_DEFAULT);
}
void clear_udt_overload_default_cons() {
flag_ &= ~UDF_UDT_CONS_OVERLOAD_DEFAULT;
}
static constexpr uint64_t UDF_UDT_STATIC = 1;
static constexpr uint64_t UDF_UDT_CONS = 2;
static constexpr uint64_t UDF_UDT_CONS_OVERLOAD_DEFAULT = 4;
TO_STRING_KV(K_(udf_name),
K_(udf_package),
K_(udf_database),
K_(param_names),
K_(param_exprs),
K_(udf_param_num),
K_(is_udt_udf),
K_(is_contain_self_param),
K_(is_udt_udf_inside_pkg),
K_(is_new_keyword_used),
K_(flag));
common::ObString udf_name_;
common::ObString udf_package_;
common::ObString udf_database_;
common::ObArray<common::ObString> param_names_;
common::ObArray<ObRawExpr*> param_exprs_;
int64_t udf_param_num_;
ObUDFRawExpr *ref_expr_;
bool is_udt_udf_; // if this udf is udt object routine
bool is_contain_self_param_; // self param is mocked.
bool is_udt_udf_inside_pkg_;
bool is_new_keyword_used_; // if in NEW obj(...) form
uint64_t flag_;
};
enum AccessNameType
{
UNKNOWN = -1,
SYS_FUNC,
DLL_UDF,
PL_UDF,
PL_VAR,
DB_NS,
PKG_NS,
REC_ELEM,
TYPE_METHOD,
CURSOR_ATTR,
UDT_NS,
LOCAL_TYPE,
PKG_TYPE,
};
class ObRawExpr;
class ObSysFunRawExpr;
class ObObjAccessIdent
{
public:
ObObjAccessIdent()
: type_(UNKNOWN),
access_name_(),
access_index_(common::OB_INVALID_INDEX),
udf_info_(),
sys_func_expr_(NULL),
params_(),
has_brackets_(false) {}
ObObjAccessIdent(const common::ObString &name, int64_t index = common::OB_INVALID_INDEX)
: type_(UNKNOWN),
access_name_(name),
access_index_(index),
udf_info_(),
sys_func_expr_(NULL),
params_(),
has_brackets_(false) {}
virtual ~ObObjAccessIdent() {}
int assign(const ObObjAccessIdent &other)
{
type_ = other.type_;
access_name_ = other.access_name_;
access_index_ = other.access_index_;
udf_info_ = other.udf_info_;
sys_func_expr_ = other.sys_func_expr_;
has_brackets_ = other.has_brackets_;
return params_.assign(other.params_);
}
ObObjAccessIdent &operator =(const ObObjAccessIdent &other)
{
assign(other);
return *this;
}
public:
inline void set_type(AccessNameType type) { type_ = type; }
inline AccessNameType get_type() { return type_; }
inline void set_sys_func() { type_ = SYS_FUNC; }
inline void set_dll_udf() { type_ = DLL_UDF; }
inline void set_pl_udf() { type_ = PL_UDF; }
inline void set_pl_var() { type_ = PL_VAR; }
inline void set_db_ns() { type_ = DB_NS; }
inline void set_pkg_ns() { type_ = PKG_NS; }
inline void set_rec_elem() { type_ = REC_ELEM; }
inline void set_type_method() { type_ = TYPE_METHOD; }
inline void set_cursor_attr() { type_ = CURSOR_ATTR; }
inline void set_udt_ns() { type_ = UDT_NS; }
inline bool is_unknown() const { return UNKNOWN == type_; }
inline bool is_sys_func() const { return SYS_FUNC == type_; }
inline bool is_dll_udf() const { return DLL_UDF == type_; }
inline bool is_pl_udf() const { return PL_UDF == type_; }
inline bool is_pl_var() const { return PL_VAR == type_; }
inline bool is_db_ns() const { return DB_NS == type_; }
inline bool is_pkg_ns() const { return PKG_NS == type_; }
inline bool is_rec_elem() const { return REC_ELEM == type_; }
inline bool is_type_method() const { return TYPE_METHOD == type_; }
inline bool is_cursor_attr() const { return CURSOR_ATTR == type_; }
inline bool is_udt_ns() const { return UDT_NS == type_; }
inline bool is_local_type() const { return LOCAL_TYPE == type_; }
inline bool is_pkg_type() const { return PKG_TYPE == type_; }
inline bool is_udt_type() const { return UDT_NS == type_; }
inline bool is_type() const { return is_local_type() || is_pkg_type() || is_udt_type(); }
int extract_params(int64_t level, common::ObIArray<ObRawExpr*> &params) const;
int replace_params(ObRawExpr *from, ObRawExpr *to);
TO_STRING_KV(K_(access_name), K_(access_index), K_(type), K_(params));
AccessNameType type_;
common::ObString access_name_;
int64_t access_index_;
ObUDFInfo udf_info_;
ObSysFunRawExpr *sys_func_expr_;
//a.f(x,y)(m,n)里的x、y、m、n都是f的参数,但是x、y的param_level_是0,m、n是1
common::ObSEArray<std::pair<ObRawExpr*, int64_t>, 4, common::ModulePageAllocator, true> params_;
bool has_brackets_; // may has empty (), record it.
};
class ObColumnRefRawExpr;
struct ObQualifiedName
{
public:
ObQualifiedName()
: database_name_(),
tbl_name_(),
col_name_(),
is_star_(false),
ref_expr_(NULL),
parents_expr_info_(),
parent_aggr_level_(-1),
access_idents_(),
current_resolve_level_(-1),
is_access_root_(true)
{
}
virtual ~ObQualifiedName() {}
int assign(const ObQualifiedName &other)
{
database_name_ = other.database_name_;
tbl_name_ = other.tbl_name_;
col_name_ = other.col_name_;
is_star_ = other.is_star_;
ref_expr_ = other.ref_expr_;
parents_expr_info_ = other.parents_expr_info_;
parent_aggr_level_ = other.parent_aggr_level_;
current_resolve_level_ = other.current_resolve_level_;
is_access_root_ = other.is_access_root_;
return access_idents_.assign(other.access_idents_);
}
ObQualifiedName &operator =(const ObQualifiedName &other)
{
assign(other);
return *this;
}
void format_qualified_name(common::ObNameCaseMode mode);
inline bool is_unknown() const
{
bool bret = true;
for (int64_t i = 0; bret && i < access_idents_.count(); ++i) {
if (!access_idents_.at(i).is_unknown()) {
bret = false;
break;
}
}
return bret;
}
inline bool is_sys_func() const
{
return 1 == access_idents_.count() && access_idents_.at(0).is_sys_func();
}
inline bool is_pl_udf() const
{
bool bret = !access_idents_.empty()
&& access_idents_.at(access_idents_.count() - 1).is_pl_udf();
//如果最后的UDF有多层参数,那么说明不是UDF
for (int64_t i = 0;
bret && i < access_idents_.at(access_idents_.count() - 1).params_.count();
++i) {
bret = 0 == access_idents_.at(access_idents_.count() - 1).params_.at(i).second;
}
return bret;
}
inline bool is_udf_return_access() const
{
bool bret = !access_idents_.empty()
&& access_idents_.at(access_idents_.count() - 1).is_pl_udf();
//如果最后的UDF有多层参数,那么说明是对UDF返回值的访问
bool multi_level = false;
for (int64_t i = 0;
bret && !multi_level && i < access_idents_.at(access_idents_.count() - 1).params_.count();
++i) {
multi_level = 0 != access_idents_.at(access_idents_.count() - 1).params_.at(i).second;
}
return bret && multi_level;
}
inline bool is_dll_udf() const { return false; }
inline bool is_pl_var() const
{
bool is_true = false;
if (!is_sys_func() && !is_pl_udf() && !is_dll_udf()) {
for (int64_t i = 0; !is_true && i < access_idents_.count(); ++i) {
if (access_idents_.at(i).is_pl_var()) {
is_true = true;
}
}
is_true = is_true || access_idents_.count() > 3;
}
return is_true;
}
inline bool is_type_method() const
{
return access_idents_.at(access_idents_.count() - 1).is_type_method();
}
inline bool is_access_root() const { return is_access_root_; }
int replace_access_ident_params(ObRawExpr *from, ObRawExpr *to);
TO_STRING_KV(N_DATABASE_NAME, database_name_,
N_TABLE_NAME, tbl_name_,
N_COLUMN, col_name_,
K_(is_star),
K_(ref_expr),
K_(parents_expr_info),
K_(parent_aggr_level),
K_(access_idents),
K_(current_resolve_level),
K_(is_access_root));
public:
common::ObString database_name_;
common::ObString tbl_name_; //当用于UDF的时候,表示package name
common::ObString col_name_; //当用于UDF的时候,表示function name
bool is_star_;
ObColumnRefRawExpr *ref_expr_;
ObExprInfo parents_expr_info_;
int64_t parent_aggr_level_;
//通过'.'的方式访问的序列都存在这里,如a.f(x,y).c里的a、f、c
common::ObSEArray<ObObjAccessIdent, 4, common::ModulePageAllocator, true> access_idents_;
// the depth of resolve level
int64_t current_resolve_level_;
bool is_access_root_; //a(b(c))会被递归解析出c、b(c)、a(b(c))三个ObQualifiedName,只有a(b(c))是root
};
// bug 6349933: for most of the cases, 8 tables should be more than enough
typedef ObSqlBitSet<8, int64_t, true> ObRelIds;
typedef ObSqlBitSet<common::OB_MAX_SUBQUERY_LAYER_NUM, int64_t, true> ObExprLevels;
/**
* @brief The ExprCopyPolicy enum
* Share 表达式:column, query, aggregation, window function, 伪列以及被打上 IS_SHARED_REF 的表达式
* COPY_REF_DEFAULT: 共享表达式采用浅拷贝,其他表达式采用深拷贝
* COPY_REF_SHARE: 共享表达式也采用深拷贝。
* e.g. min(c1),
* default mode: 直接返回指针
* share mode: 深拷 min,浅拷贝 c1,返回深拷贝的指针。
* 每个 share 表达式只能深拷贝自己。不能触发其他 share 表达式的深拷
*/
enum ExprCopyPolicy {
COPY_REF_DEFAULT = 0,
COPY_REF_SHARED = 1 << 0,
};
struct OrderItem
{
OrderItem()
{
reset();
}
explicit OrderItem(ObRawExpr *expr)
: expr_(expr), order_type_(default_asc_direction()) {}
OrderItem(ObRawExpr *expr, ObOrderDirection order_type)
: expr_(expr), order_type_(order_type) {}
public:
virtual ~OrderItem() {}
void reset()
{
expr_ = NULL;
order_type_ = default_asc_direction();
}
inline bool operator ==(const OrderItem &other) const
{
return (expr_ == other.expr_
&& order_type_ == other.order_type_);
}
inline bool operator !=(const OrderItem &other) const
{
return !(*this == other);
}
uint64_t hash(uint64_t seed) const
{
if (NULL != expr_) {
seed = common::do_hash(*expr_, seed);
}
seed = common::do_hash(order_type_, seed);
return seed;
}
int hash(uint64_t &hash_val, uint64_t seed) const
{
hash_val = hash(seed);
return OB_SUCCESS;
}
bool is_null_first() const {
return NULLS_FIRST_ASC == order_type_ || NULLS_FIRST_DESC == order_type_;
}
bool is_ascending() const {
return NULLS_FIRST_ASC == order_type_ || NULLS_LAST_ASC == order_type_;
}
bool is_descending() const {
return NULLS_FIRST_DESC == order_type_ || NULLS_LAST_DESC == order_type_;
}
int deep_copy(ObIRawExprCopier &copier, const OrderItem &other);
static const char* order_type2name(const ObOrderDirection direction)
{
const char* name = NULL;
switch (direction) {
case NULLS_FIRST_ASC:
name = N_NULLS_FIRST_ASC;
break;
case NULLS_LAST_ASC:
name = N_NULLS_LAST_ASC;
break;
case NULLS_FIRST_DESC:
name = N_NULLS_FIRST_DESC;
break;
case NULLS_LAST_DESC:
name = N_NULLS_LAST_DESC;
break;
default:
break;
}
return name;
}
TO_STRING_KV(N_EXPR, expr_,
N_ASCENDING, order_type2name(order_type_));
ObRawExpr* expr_;
ObOrderDirection order_type_;
};
class ObQueryRefRawExpr;
class ObPlQueryRefRawExpr;
class ObSetOpRawExpr;
struct ObExprEqualCheckContext
{
ObExprEqualCheckContext()
: override_const_compare_(false),
override_column_compare_(false),
override_query_compare_(false),
ignore_implicit_cast_(false),
recursion_level_(0),
override_set_op_compare_(false),
err_code_(common::OB_SUCCESS),
param_expr_(),
need_check_deterministic_(false),
ignore_param_(false)
{ }
ObExprEqualCheckContext(bool need_check_deterministic)
: override_const_compare_(false),
override_column_compare_(false),
override_query_compare_(false),
ignore_implicit_cast_(false),
recursion_level_(0),
override_set_op_compare_(false),
err_code_(common::OB_SUCCESS),
param_expr_(),
need_check_deterministic_(need_check_deterministic),
ignore_param_(false)
{ }
virtual ~ObExprEqualCheckContext() {}
struct ParamExprPair
{
ParamExprPair(int64_t param_idx,
const ObRawExpr *expr)
: param_idx_(param_idx), expr_(expr)
{ }
ParamExprPair() : param_idx_(-1), expr_(NULL)
{ }
TO_STRING_KV(K_(param_idx), K_(expr));
int64_t param_idx_;
const ObRawExpr *expr_;
};
inline int add_param_pair(int64_t param_idx, const ObRawExpr *expr)
{
return param_expr_.push_back(ParamExprPair(param_idx, expr));
}
// only compare the result type of two columns
virtual bool compare_column(const ObColumnRefRawExpr &left,
const ObColumnRefRawExpr &right);
virtual bool compare_const(const ObConstRawExpr &left,
const ObConstRawExpr &right);
virtual bool compare_query(const ObQueryRefRawExpr &left,
const ObQueryRefRawExpr &right);
virtual bool compare_query(const ObPlQueryRefRawExpr &left,
const ObPlQueryRefRawExpr &right);
virtual bool compare_set_op_expr(const ObSetOpRawExpr& left,
const ObSetOpRawExpr& right);
void reset() {
override_const_compare_ = false;
override_column_compare_ = false;
override_query_compare_ = false;
ignore_implicit_cast_ = false;
recursion_level_ = 0;
override_set_op_compare_ = false;
err_code_ = OB_SUCCESS;
param_expr_.reset();
need_check_deterministic_ = false;
ignore_param_ = false;
}
bool override_const_compare_;
bool override_column_compare_;
bool override_query_compare_;
bool ignore_implicit_cast_;
int recursion_level_;
bool override_set_op_compare_;
int err_code_;
//when compare with T_QUESTIONMARK, as T_QUESTIONMARK is unkown, record this first.
common::ObSEArray<ParamExprPair, 3, common::ModulePageAllocator, true> param_expr_;
bool need_check_deterministic_;
bool ignore_param_; // only compare structure of expr
};
struct ObExprParamCheckContext : ObExprEqualCheckContext
{
ObExprParamCheckContext() :
ObExprEqualCheckContext(),
calculable_items_(NULL),
equal_param_constraints_(NULL)
{
override_column_compare_ = true;
override_const_compare_ = true;
override_query_compare_ = false;
}
virtual ~ObExprParamCheckContext() {}
void init(const ObIArray<ObHiddenColumnItem> *calculable_items,
const common::ObIArray<ObPCParamEqualInfo> *equal_param_constraints,
EqualSets *equal_sets = NULL);
virtual bool compare_column(const ObColumnRefRawExpr &left,
const ObColumnRefRawExpr &right)override;
/**
* 比较两个常量表达式:
* 如果两个表达式都没有参数化,比较实际值
* 如果两个表达式都参数化了,并且是预计算表达式,需要进一步
* 获取预计算表达式比较;
* 比较参数idx是否一致,如果一致,返回相等
* 否则在all_equal_param_constraints_中查找是否存在等值约束,
* 如果存在则返回相等,否则返回不相等
*/
bool compare_const(const ObConstRawExpr &left, const ObConstRawExpr &right) override;
int get_calc_expr(const int64_t param_idx, const ObRawExpr *&expr);
int is_pre_calc_item(const ObConstRawExpr &const_expr, bool &is_calc);
const ObIArray<ObHiddenColumnItem> *calculable_items_; // from query context
const common::ObIArray<ObPCParamEqualInfo> *equal_param_constraints_;
EqualSets *equal_sets_;
};
enum ObVarType
{
INVALID_VAR = -1,
SYS_VAR = 0,
USER_VAR = 1,
};
struct ObVarInfo final
{
OB_UNIS_VERSION(1);
public:
ObVarInfo() : type_(INVALID_VAR), name_() {}
int deep_copy(common::ObIAllocator &allocator, ObVarInfo &var_info) const;
bool operator==(const ObVarInfo &other) const
{
return (type_ == other.type_ && name_ == other.name_);
}
TO_STRING_KV(K_(type), K_(name));
ObVarType type_;
common::ObString name_;
};
class ObQueryRefRawExpr;
struct ObSubQueryInfo
{
ObSubQueryInfo()
{
sub_query_ = NULL;
ref_expr_ = NULL;
}
TO_STRING_KV(K_(ref_expr));
const ParseNode *sub_query_;
ObQueryRefRawExpr *ref_expr_;
ObExprInfo parents_expr_info_;
};
class ObAggFunRawExpr;
class ObPseudoColumnRawExpr;
class ObOpRawExpr;
class ObWinFunRawExpr;
class ObUserVarIdentRawExpr;
struct ObUDFInfo;
template <typename ExprFactoryT>
struct ObResolveContext
{
struct ObAggResolveLinkNode : public common::ObDLinkBase<ObAggResolveLinkNode>
{
ObAggResolveLinkNode()
: is_win_agg_(false) {}
bool is_win_agg_;
};
ObResolveContext(ExprFactoryT &expr_factory,
const common::ObTimeZoneInfo *tz_info,
const common::ObNameCaseMode mode)
: expr_factory_(expr_factory),
stmt_(NULL),
connection_charset_(common::CHARSET_INVALID),
dest_collation_(common::CS_TYPE_INVALID),
tz_info_(tz_info),
case_mode_(mode),
columns_(NULL),
sys_vars_(NULL),
sub_query_info_(NULL),
aggr_exprs_(NULL),
win_exprs_(NULL),
udf_info_(NULL),
op_exprs_(NULL),
user_var_exprs_(nullptr),
is_extract_param_type_(true),
param_list_(NULL),
prepare_param_count_(0),
external_param_info_(NULL),
current_scope_(T_NONE_SCOPE),
is_win_agg_(false),
schema_checker_(NULL),
session_info_(NULL),
secondary_namespace_(NULL),
query_ctx_(NULL),
is_for_pivot_(false),
is_for_dynamic_sql_(false),
is_for_dbms_sql_(false),
tg_timing_event_(TG_TIMING_EVENT_INVALID)
{
}
ExprFactoryT &expr_factory_;
ObStmt *stmt_;
common::ObCharsetType connection_charset_;
common::ObCollationType dest_collation_;
const common::ObTimeZoneInfo *tz_info_;
common::ObNameCaseMode case_mode_;
//标记该表达式的上层表达式的一些属性,
//比如count(c1), c1的上层是count(),所以c1的parents_expr_info 含有IS_AGG
ObExprInfo parents_expr_info_;
common::ObIArray<ObQualifiedName> *columns_;
common::ObIArray<ObVarInfo> *sys_vars_;
common::ObIArray<ObSubQueryInfo> *sub_query_info_;
common::ObIArray<ObAggFunRawExpr*> *aggr_exprs_;
common::ObIArray<ObWinFunRawExpr*> *win_exprs_;
common::ObIArray<ObUDFInfo> *udf_info_;
common::ObIArray<ObOpRawExpr*> *op_exprs_;
common::ObIArray<ObUserVarIdentRawExpr*> *user_var_exprs_;
//由于单测expr resolver中包含一些带?的表达式case,
//所以为expr resolver ctx增添一个配置变量isextract_param_type
//如果配置该参数为true,那么遇到?将为其填上真实的参数类型,
//如果没有对应的参数将报错,如果配置该参数为false的时候,
//参数列表指定了也将为其填上真实的参数类型,
//如果没有指定参数列表,那么expr resolver将忽略参数类型的填充
bool is_extract_param_type_;
const ParamStore *param_list_;
int64_t prepare_param_count_;
ExternalParams *external_param_info_;//for anonymous + ps
ObStmtScope current_scope_;
common::ObArenaAllocator local_allocator_;
typedef common::ObDList<ObAggResolveLinkNode> ObAggResolveLink;
ObAggResolveLink agg_resolve_link_;
bool is_win_agg_;
ObSchemaChecker *schema_checker_;// we use checker to get udf function name.
const ObSQLSessionInfo *session_info_;// we use to get tenant id
pl::ObPLBlockNS *secondary_namespace_;
ObQueryCtx *query_ctx_;
bool is_for_pivot_;
bool is_for_dynamic_sql_;
bool is_for_dbms_sql_;
TgTimingEvent tg_timing_event_; // for msyql trigger
};
typedef ObResolveContext<ObRawExprFactory> ObExprResolveContext;
class ObRawExprVisitor;
struct ObHiddenColumnItem;
enum ExplicitedRefType {
NONE_REF = 0,
REF_BY_NORMAL = 1 << 0,
REF_BY_PART_EXPR = 1 << 1,
REF_BY_VIRTUAL_GEN_COL = 1<< 2,
REF_BY_STORED_GEN_COL = 1 << 3
};
class ObRawExpr : virtual public jit::expr::ObIRawExpr
{
public:
friend sql::ObExpr *ObStaticEngineExprCG::get_rt_expr(const ObRawExpr &raw_expr);
friend sql::ObExpr *ObExprOperator::get_rt_expr(const ObRawExpr &raw_expr) const;
friend class pl::ObPLCodeGenerator;
friend class sql::ObCallProcedureInfo;
friend class sql::ObRTDatumArith;
explicit ObRawExpr(ObItemType expr_type = T_INVALID)
: ObIRawExpr(expr_type),
magic_num_(0x13572468),
info_(),
rel_ids_(),
inner_alloc_(NULL),
expr_factory_(NULL),
reference_type_(ExplicitedRefType::NONE_REF),
ref_count_(0),
is_for_generated_column_(false),
rt_expr_(NULL),
extra_(0),
is_called_in_sql_(true),
is_calculated_(false),
is_deterministic_(true),
partition_id_calc_type_(CALC_INVALID)
{
}
explicit ObRawExpr(common::ObIAllocator &alloc, ObItemType expr_type = T_INVALID)
: ObIRawExpr(alloc, expr_type),
magic_num_(0x13572468),
info_(),
rel_ids_(),
inner_alloc_(&alloc),
expr_factory_(NULL),
reference_type_(ExplicitedRefType::NONE_REF),
ref_count_(0),
is_for_generated_column_(false),
rt_expr_(NULL),
extra_(0),
is_called_in_sql_(true),
is_calculated_(false),
is_deterministic_(true),
partition_id_calc_type_(CALC_INVALID),
may_add_interval_part_(MayAddIntervalPart::NO),
runtime_filter_type_(NOT_INIT_RUNTIME_FILTER_TYPE)
{
}
virtual ~ObRawExpr();
int deep_copy(ObIRawExprCopier &copier, const ObRawExpr &other);
virtual int assign(const ObRawExpr &other);
virtual int inner_deep_copy(ObIRawExprCopier &copier);
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) = 0;
virtual void clear_child() = 0;
virtual void reset();
/// whether is the same expression.
/// Compare the two expression tree.
bool has_generalized_column() const;
bool has_enum_set_column() const;
bool has_specified_pseudocolumn() const;
bool same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const = 0;
inline bool is_generalized_column() const
{
return is_column_ref_expr() || is_query_ref_expr() || is_aggr_expr() || is_set_op_expr()
|| is_win_func_expr() || has_flag(IS_ROWNUM) || has_flag(IS_PSEUDO_COLUMN)
|| has_flag(IS_SEQ_EXPR) || has_flag(IS_SYS_CONNECT_BY_PATH)
|| has_flag(IS_CONNECT_BY_ROOT) || has_flag(IS_OP_PSEUDO_COLUMN);
}
// The expr result is vectorized, the batch result is the same if not vectorized result e.g:
// c1 + c1: is vectorized
// ? + ?: is not vectorized
bool is_vectorize_result() const;
void unset_result_flag(uint32_t result_flag);
//void set_op_factory(ObExprOperatorFactory &factory) { op_factory_ = &factory; }
void set_allocator(common::ObIAllocator &alloc);
void set_expr_factory(ObRawExprFactory &factory) { expr_factory_ = &factory; }
ObRawExprFactory *get_expr_factory() { return expr_factory_; }
void set_expr_info(const ObExprInfo &info);
int add_flag(int32_t flag);
int add_flags(const ObExprInfo &flags);
int add_child_flags(const ObExprInfo &flags);
bool has_flag(ObExprInfoFlag flag) const;
int clear_flag(int32_t flag);
/** +-is_static_scalar_const_expr
* (1、1+2、sysdate) | (1,not for[1,2,3])
* +-is_static_const_expr-+
* |
* is_const_or_calculable_expr-+
* (1、1+2、2+?、sysdate) |
* +-is_dynamic_const_expr
* (2 + ?)
*/
bool is_param_expr() const;
bool cnt_param_expr() const;
bool is_const_expr() const;
bool is_static_const_expr() const;
bool is_static_scalar_const_expr() const;
bool is_dynamic_const_expr() const;
bool has_hierarchical_query_flag() const;
const ObExprInfo &get_expr_info() const;
ObExprInfo &get_expr_info();
int add_relation_id(int64_t rel_idx);
int add_relation_ids(const ObRelIds &rel_ids);
ObRelIds &get_relation_ids();
const ObRelIds &get_relation_ids() const;
// implemented base on get_param_count() and get_param_expr() interface,
// children are visited in get_param_expr() return order.
int preorder_accept(ObRawExprVisitor &visitor);
int postorder_accept(ObRawExprVisitor &visitor);
virtual int do_visit(ObRawExprVisitor &visitor) = 0;
// skip visit child for expr visitor. (ObSetIterRawExpr)
virtual bool skip_visit_child() const { return false; }
virtual int64_t get_param_count() const = 0;
virtual const ObRawExpr *get_param_expr(int64_t index) const = 0;
virtual ObRawExpr *&get_param_expr(int64_t index) = 0;
virtual int64_t get_output_column() const {return -1;}
inline bool is_not_null_for_read() const { return get_result_type().has_result_flag(NOT_NULL_FLAG); }
inline bool is_not_null_for_write() const { return get_result_type().has_result_flag(NOT_NULL_WRITE_FLAG); }
inline bool is_auto_increment() const { return get_result_type().has_result_flag(AUTO_INCREMENT_FLAG); }
inline bool is_rand_func_expr() const { return has_flag(IS_RAND_FUNC); }
inline bool is_obj_access_expr() const { return T_OBJ_ACCESS_REF == get_expr_type(); }
inline bool is_assoc_index_expr() const { return T_FUN_PL_ASSOCIATIVE_INDEX == get_expr_type(); }
bool is_not_calculable_expr() const;
bool cnt_not_calculable_expr() const;
int is_const_inherit_expr(bool &is_const_inherit, const bool param_need_replace = false) const;
int is_non_pure_sys_func_expr(bool &is_non_pure) const;
bool is_specified_pseudocolumn_expr() const;
void set_alias_column_name(const common::ObString &alias_name) { alias_column_name_ = alias_name; }
const common::ObString &get_alias_column_name() const { return alias_column_name_; }
int set_expr_name(const common::ObString &expr_name);
const common::ObString &get_expr_name() const { return expr_name_; }
inline uint64_t hash(uint64_t seed) const
{
seed = common::do_hash(type_, seed);
seed = common::do_hash(expr_class_, seed);
seed = result_type_.hash(seed);
seed = hash_internal(seed);
return seed;
}
inline int hash(uint64_t &hash_val, uint64_t seed) const
{
hash_val = hash(seed);
return OB_SUCCESS;
}
inline bool is_type_to_str_expr() const
{
return (T_FUN_ENUM_TO_STR == type_ || T_FUN_SET_TO_STR == type_
|| T_FUN_ENUM_TO_INNER_TYPE == type_ || T_FUN_SET_TO_INNER_TYPE == type_);
}
virtual uint64_t hash_internal(uint64_t seed) const = 0;
int get_name(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type = EXPLAIN_UNINITIALIZED) const;
int get_type_and_length(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
virtual int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const = 0;
// post-processing for expressions
int formalize(const ObSQLSessionInfo *my_session);
int pull_relation_id();
int extract_info();
int deduce_type(const ObSQLSessionInfo *my_session = NULL);
inline ObExprInfo &get_flags() { return info_; }
int set_enum_set_values(const common::ObIArray<common::ObString> &values);
const common::ObIArray<common::ObString> &get_enum_set_values() const { return enum_set_values_; }
bool is_explicited_reference() const { return reference_type_ != ExplicitedRefType::NONE_REF; }
bool is_referred_by_normal() const { return (reference_type_ & ExplicitedRefType::REF_BY_NORMAL) != 0; }
bool is_only_referred_by_stored_gen_col() const { return reference_type_ == ExplicitedRefType::REF_BY_STORED_GEN_COL; }
int32_t get_explicited_reftype() const { return reference_type_; }
void set_explicited_reference()
{
ref_count_++;
reference_type_ |= ExplicitedRefType::REF_BY_NORMAL;
}
void set_part_key_reference() {
ref_count_++;
reference_type_ |= ExplicitedRefType::REF_BY_PART_EXPR;
}
void set_explicited_reference(ExplicitedRefType ref_type)
{
ref_count_++;
reference_type_ |= ref_type;
}
void clear_explicited_referece()
{
ref_count_ = 0;
reference_type_ = ExplicitedRefType::NONE_REF;
}
int64_t get_ref_count() const {
return ref_count_;
}
bool is_for_generated_column() const { return is_for_generated_column_; }
void set_for_generated_column()
{
is_for_generated_column_ = true;
}
void clear_for_generated_column()
{
is_for_generated_column_ = false;
}
void set_rt_expr(sql::ObExpr *expr) { rt_expr_ = expr; }
void reset_rt_expr() { rt_expr_ = NULL; }
void set_extra(uint64_t extra) { extra_ = extra; }
void set_is_called_in_sql(bool is_called_in_sql) { is_called_in_sql_ = is_called_in_sql; }
void set_is_calculated(bool is_calculated) { is_calculated_ = is_calculated; }
uint64_t get_extra() const { return extra_; }
bool is_called_in_sql() const { return is_called_in_sql_; }
bool is_calculated() const { return is_calculated_; }
bool is_deterministic() const { return is_deterministic_; }
bool is_bool_expr() const;
bool is_spatial_expr() const;
bool is_geo_expr() const;
bool is_mysql_geo_expr() const;
bool is_priv_geo_expr() const;
bool is_xml_expr() const;
ObGeoType get_geo_expr_result_type() const;
void set_is_deterministic(bool is_deterministic) { is_deterministic_ = is_deterministic; }
int get_geo_cast_result_type(ObGeoType& geo_type) const;
void set_partition_id_calc_type(PartitionIdCalcType calc_type) {
partition_id_calc_type_ = calc_type; }
bool is_json_expr() const;
bool is_multiset_expr() const;
PartitionIdCalcType get_partition_id_calc_type() const { return partition_id_calc_type_; }
void set_may_add_interval_part(MayAddIntervalPart flag) {
may_add_interval_part_ = flag;
}
MayAddIntervalPart get_may_add_interval_part() const
{ return may_add_interval_part_;}
RuntimeFilterType get_runtime_filter_type() const { return runtime_filter_type_; }
void set_runtime_filter_type(RuntimeFilterType type) { runtime_filter_type_ = type; }
VIRTUAL_TO_STRING_KV(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
K_(enum_set_values),
K_(reference_type),
K_(ref_count),
K_(is_for_generated_column),
K_(extra),
K_(is_called_in_sql),
K_(is_calculated),
K_(is_deterministic),
K_(partition_id_calc_type),
K_(may_add_interval_part));
private:
const ObRawExpr *get_same_identify(const ObRawExpr *e,
const ObExprEqualCheckContext *check_ctx) const;
public:
uint32_t magic_num_;
protected:
static const int64_t COMMON_MULTI_NUM = 16;
static const int64_t COMMON_ENUM_SET_VALUE_NUM = 4;
protected:
ObExprInfo info_; // flags
ObRelIds rel_ids_; // related table idx
common::ObIAllocator *inner_alloc_;
ObRawExprFactory *expr_factory_;
common::ObString alias_column_name_;
common::ObSEArray<common::ObString, 1, common::ModulePageAllocator, true> enum_set_values_;//string_map
//在mysql中表达式都有自己的自己名字,例如,cast('1' as unsigned),这个
//表达式解析出来这一整串会作为这个表达式的名字。
//在udf中,需要将udf_func(expr1, expr2)中expr1和expr2的名字作为参数传递
//给user defined function。
common::ObString expr_name_;
// for column expr, agg expr, window function expr and query ref exprs
int32_t reference_type_;
int64_t ref_count_;
bool is_for_generated_column_;
sql::ObExpr *rt_expr_;
// 每个raw expr有自己的解释
uint64_t extra_;
bool is_called_in_sql_; // 用于区分是被 pl 还是 sql 调用
bool is_calculated_; // 用于在新引擎 cg 中检查 raw expr 是否被重复计算
bool is_deterministic_; //expr is deterministic, given the same inputs, returns the same result
PartitionIdCalcType partition_id_calc_type_; //for calc_partition_id func to mark calc part type
MayAddIntervalPart may_add_interval_part_; // for calc_partition_id
RuntimeFilterType runtime_filter_type_; // for runtime filter
private:
DISALLOW_COPY_AND_ASSIGN(ObRawExpr);
};
inline void ObRawExpr::set_allocator(ObIAllocator &alloc)
{
inner_alloc_ = &alloc;
result_type_.set_allocator(&alloc);
}
inline void ObRawExpr::unset_result_flag(uint32_t result_flag)
{
result_type_.unset_result_flag(result_flag);
}
inline int ObRawExpr::add_relation_id(int64_t rel_idx)
{
int ret = common::OB_SUCCESS;
if (rel_idx < 0) {
ret = common::OB_INVALID_ARGUMENT;
} else {
ret = rel_ids_.add_member(rel_idx);
}
return ret;
}
inline int ObRawExpr::add_relation_ids(const ObRelIds &rel_ids)
{
return rel_ids_.add_members(rel_ids);
}
inline int ObRawExpr::add_flag(int32_t flag)
{
int ret = common::OB_SUCCESS;
if (OB_FAIL(info_.add_member(flag))) {
//add_member will print log,here no need
} else if (flag <= IS_INFO_MASK_END) {
if (OB_FAIL(info_.add_member(CNT_INFO_MASK_BEGIN + flag))) {
//add_member will print log,here no need
}
} else {}
return ret;
}
inline int ObRawExpr::clear_flag(int32_t flag)
{
return info_.del_member(flag);
}
inline bool ObRawExpr::is_param_expr() const
{
return has_flag(IS_STATIC_PARAM) || has_flag(IS_DYNAMIC_PARAM);
}
inline bool ObRawExpr::cnt_param_expr() const
{
return has_flag(CNT_STATIC_PARAM) || has_flag(CNT_DYNAMIC_PARAM);
}
inline bool ObRawExpr::is_const_expr() const
{
return has_flag(IS_CONST) || has_flag(IS_CONST_EXPR);
}
inline bool ObRawExpr::is_static_const_expr() const
{
return is_const_expr() &&
!has_flag(CNT_DYNAMIC_PARAM);
}
inline bool ObRawExpr::is_static_scalar_const_expr() const
{
return is_static_const_expr() && T_OP_ROW != get_expr_type();
}
inline bool ObRawExpr::is_dynamic_const_expr() const
{
return is_const_expr() && has_flag(CNT_DYNAMIC_PARAM);
}
inline bool ObRawExpr::has_hierarchical_query_flag() const
{
return has_flag(CNT_PRIOR) || has_flag(CNT_LEVEL)
|| has_flag(CNT_CONNECT_BY_ISLEAF)
|| has_flag(CNT_CONNECT_BY_ISCYCLE)
|| has_flag(CNT_CONNECT_BY_ROOT)
|| has_flag(CNT_SYS_CONNECT_BY_PATH);;
}
inline int ObRawExpr::add_flags(const ObExprInfo &flags)
{
return info_.add_members(flags);
}
inline bool ObRawExpr::has_flag(ObExprInfoFlag flag) const
{
return info_.has_member(flag);
}
inline bool ObRawExpr::inner_same_as(
const ObRawExpr &expr,
ObExprEqualCheckContext *check_context) const
{
UNUSED(check_context);
return (get_expr_type() == expr.get_expr_type() && get_result_type() == expr.get_result_type());
}
inline void ObRawExpr::set_expr_info(const ObExprInfo &info)
{
info_ = info;
}
inline ObExprInfo &ObRawExpr::get_expr_info()
{
return info_;
}
inline const ObExprInfo &ObRawExpr::get_expr_info() const
{
return info_;
}
inline ObRelIds &ObRawExpr::get_relation_ids()
{
return rel_ids_;
}
inline const ObRelIds &ObRawExpr::get_relation_ids() const
{
return rel_ids_;
}
////////////////////////////////////////////////////////////////
class ObTerminalRawExpr: public ObRawExpr
{
public:
explicit ObTerminalRawExpr(ObItemType expr_type = T_INVALID)
: ObRawExpr(expr_type)
{}
explicit ObTerminalRawExpr(common::ObIAllocator &alloc, ObItemType expr_type = T_INVALID)
: ObRawExpr(alloc, expr_type)
{}
virtual ~ObTerminalRawExpr() {}
virtual void clear_child() {}
virtual int64_t get_param_count() const { return 0; }
virtual const ObRawExpr *get_param_expr(int64_t index) const { UNUSED(index); return NULL; }
virtual ObRawExpr *&get_param_expr(int64_t index);
virtual uint64_t hash_internal(uint64_t seed) const { return seed; }
protected:
private:
DISALLOW_COPY_AND_ASSIGN(ObTerminalRawExpr);
};
////////////////////////////////////////////////////////////////
class ObConstRawExpr :
public ObTerminalRawExpr,
public jit::expr::ObConstExpr
{
public:
ObConstRawExpr()
:is_date_unit_(false),
is_literal_bool_(false),
is_batch_stmt_parameter_(false)/*: precalc_expr_(NULL)*/
{ ObRawExpr::set_expr_class(ObRawExpr::EXPR_CONST); }
ObConstRawExpr(common::ObIAllocator &alloc)
: ObIRawExpr(alloc),
ObTerminalRawExpr(alloc),
ObConstExpr(),
is_date_unit_(false),
is_literal_bool_(false),
is_batch_stmt_parameter_(false)
{ ObIRawExpr::set_expr_class(ObIRawExpr::EXPR_CONST); }
ObConstRawExpr(const oceanbase::common::ObObj &val, ObItemType expr_type = T_INVALID)
: ObIRawExpr(expr_type),
ObTerminalRawExpr(expr_type),
ObConstExpr(),
is_date_unit_(false),
is_literal_bool_(false),
is_batch_stmt_parameter_(false)
{
set_value(val);
set_expr_class(ObIRawExpr::EXPR_CONST);
}
virtual ~ObConstRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
void set_value(const oceanbase::common::ObObj &val);
void set_literal_prefix(const common::ObString &name);
void set_expr_obj_meta(const common::ObObjMeta &meta) { obj_meta_ = meta; }
const common::ObObjMeta &get_expr_obj_meta() const { return obj_meta_; }
const common::ObString &get_literal_prefix() const { return literal_prefix_; }
void set_is_date_unit();
void reset_is_date_unit();
bool is_date_unit() {return true == is_date_unit_; }
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
void set_is_literal_bool(const bool is_literal_bool) { is_literal_bool_ = is_literal_bool; }
bool is_literal_bool() const { return is_literal_bool_; }
void set_is_batch_stmt_parameter() { is_batch_stmt_parameter_ = true; }
bool is_batch_stmt_parameter() { return is_batch_stmt_parameter_; }
DECLARE_VIRTUAL_TO_STRING;
private:
common::ObString literal_prefix_; //仅在编译期使用, 执行期无关
common::ObObjMeta obj_meta_;
bool is_date_unit_;
// for mysql mode to distinguish tinyint and literal bool
bool is_literal_bool_;
// is_batch_stmt_parameter_ only used for array_binding batch_execution optimization
// Indicates that the current parameter is the batch parameter
bool is_batch_stmt_parameter_;
private:
DISALLOW_COPY_AND_ASSIGN(ObConstRawExpr);
};
////////////////////////////////////////////////////////////////
/// \brief The ObVarRawExpr class
/// designed for deducing calc type
/// only used by nullif, least, greatest, from_unixtime
class ObVarRawExpr :
public ObTerminalRawExpr,
public jit::expr::ObVarExpr
{
public:
ObVarRawExpr() { ObIRawExpr::set_expr_class(ObIRawExpr::EXPR_VAR); }
ObVarRawExpr(common::ObIAllocator &alloc)
: ObIRawExpr(alloc),
ObTerminalRawExpr(alloc),
ObVarExpr(),
result_type_assigned_(false)
{ ObIRawExpr::set_expr_class(ObIRawExpr::EXPR_VAR); }
ObVarRawExpr(ObItemType expr_type = T_INVALID)
: ObIRawExpr(expr_type),
ObTerminalRawExpr(expr_type),
ObVarExpr(),
result_type_assigned_(false)
{ set_expr_class(ObIRawExpr::EXPR_VAR); }
virtual ~ObVarRawExpr() {}
int assign(const ObRawExpr &other) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
void set_result_type_assigned(bool v) { result_type_assigned_ = v; }
bool get_result_type_assigned() { return result_type_assigned_; }
private:
bool result_type_assigned_;
DISALLOW_COPY_AND_ASSIGN(ObVarRawExpr);
};
////////////////////////////////////////////////////////////////
class ObUserVarIdentRawExpr : public ObConstRawExpr
{
public:
ObUserVarIdentRawExpr() : is_contain_assign_(false), query_has_udf_(false) {}
ObUserVarIdentRawExpr(common::ObIAllocator &alloc)
: ObConstRawExpr(alloc), is_contain_assign_(false), query_has_udf_(false) {}
ObUserVarIdentRawExpr(const oceanbase::common::ObObj &val, ObItemType expr_type = T_INVALID)
: ObConstRawExpr(val, expr_type), is_contain_assign_(false), query_has_udf_(false) {}
virtual ~ObUserVarIdentRawExpr() {}
int assign(const ObRawExpr &other) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
bool get_is_contain_assign() const { return is_contain_assign_; }
void set_is_contain_assign(bool is_contain_assign) { is_contain_assign_ = is_contain_assign; }
bool get_query_has_udf() const { return query_has_udf_; }
void set_query_has_udf(bool query_has_udf) { query_has_udf_ = query_has_udf; }
bool is_same_variable(const ObObj &obj) const;
DECLARE_VIRTUAL_TO_STRING;
private:
bool is_contain_assign_; // 用户变量在整个query中是否存在赋值操作
bool query_has_udf_; // 整个query中是否包含UDF
private:
DISALLOW_COPY_AND_ASSIGN(ObUserVarIdentRawExpr);
};
////////////////////////////////////////////////////////////////
class ObExecParamRawExpr : public ObConstRawExpr
{
public:
ObExecParamRawExpr() :
ObConstRawExpr(),
ref_same_dblink_(false)
{
set_expr_class(ObIRawExpr::EXPR_EXEC_PARAM);
}
ObExecParamRawExpr(common::ObIAllocator &alloc)
: ObConstRawExpr(alloc),
ref_same_dblink_(false)
{
set_expr_class(ObIRawExpr::EXPR_EXEC_PARAM);
}
virtual ~ObExecParamRawExpr() {}
void set_param_index(int64_t index);
int64_t get_param_index() const;
void set_ref_expr(ObRawExpr *expr, bool is_onetime = false)
{
outer_expr_ = expr;
is_onetime_ = is_onetime;
}
const ObRawExpr* get_ref_expr() const { return outer_expr_; }
ObRawExpr*& get_ref_expr() { return outer_expr_; }
bool is_onetime() const { return is_onetime_; }
bool is_ref_same_dblink() const { return ref_same_dblink_; }
void set_ref_same_dblink(bool ref_same_dblink) { ref_same_dblink_ = ref_same_dblink; }
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
virtual int get_name_internal(char *buf,
const int64_t buf_len,
int64_t &pos,
ExplainType type) const;
DECLARE_VIRTUAL_TO_STRING;
private:
// the refered expr in the outer stmt
ObRawExpr *outer_expr_;
bool is_onetime_;
bool ref_same_dblink_;
};
class ObQueryRefRawExpr : public ObRawExpr
{
public:
ObQueryRefRawExpr()
: ObRawExpr(),
ref_id_(common::OB_INVALID_ID),
output_column_(0),
is_set_(false),
is_cursor_(false),
has_nl_param_(false),
is_multiset_(false)
{
//匿名union对象的初始化只能放到函数体里面,不然会报多次初始化同一个对象的编译错误
ref_stmt_ = NULL;
set_expr_class(ObIRawExpr::EXPR_QUERY_REF);
}
ObQueryRefRawExpr(common::ObIAllocator &alloc)
: ObRawExpr(alloc),
ref_id_(common::OB_INVALID_ID),
output_column_(0),
is_set_(false),
is_cursor_(false),
has_nl_param_(false),
is_multiset_(false)
{
//匿名union对象的初始化只能放到函数体里面,不然会报多次初始化同一个对象的编译错误
ref_stmt_ = NULL;
set_expr_class(ObIRawExpr::EXPR_QUERY_REF);
}
ObQueryRefRawExpr(int64_t id, ObItemType expr_type = T_INVALID)
: ObRawExpr(expr_type),
ref_id_(id),
output_column_(0),
is_set_(false),
is_cursor_(false),
has_nl_param_(false),
is_multiset_(false)
{
//匿名union对象的初始化只能放到函数体里面,不然会报多次初始化同一个对象的编译错误
ref_stmt_ = NULL;
set_expr_class(ObIRawExpr::EXPR_QUERY_REF);
}
virtual ~ObQueryRefRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
virtual void clear_child() override;
int add_param_expr(ObRawExpr *expr);
int add_exec_param_expr(ObExecParamRawExpr *expr);
int add_exec_param_exprs(const ObIArray<ObExecParamRawExpr *> &exprs);
bool has_exec_param() const { return !exec_params_.empty(); }
virtual int64_t get_param_count() const override;
virtual const ObRawExpr *get_param_expr(int64_t index) const override;
virtual ObRawExpr *&get_param_expr(int64_t index) override;
ObExecParamRawExpr *get_exec_param(int64_t index);
const ObIArray<ObExecParamRawExpr *> &get_exec_params() const { return exec_params_; }
ObIArray<ObExecParamRawExpr *> &get_exec_params() { return exec_params_; }
int64_t get_ref_id() const;
void set_ref_id(int64_t id);
ObSelectStmt *get_ref_stmt() { return ref_stmt_; }
const ObSelectStmt *get_ref_stmt() const { return ref_stmt_; }
void set_ref_stmt(ObSelectStmt *ref_stmt)
{
ref_stmt_ = ref_stmt;
}
void set_output_column(int64_t output_column);
int64_t get_output_column() const;
int add_column_type(const ObExprResType &type) { return column_types_.push_back(type); }
const common::ObIArray<ObExprResType> &get_column_types() const { return column_types_; }
common::ObIArray<ObExprResType> &get_column_types() { return column_types_; }
void set_is_set(bool is_set) { is_set_ = is_set; }
bool is_set() const { return is_set_; }
void set_cursor(bool is_cursor) { is_cursor_ = is_cursor; }
bool is_cursor() const { return is_cursor_; }
void set_has_nl_param(bool has_nl_param) { has_nl_param_ = has_nl_param; }
bool has_nl_param() const { return has_nl_param_; }
void set_is_multiset(bool is_multiset) { is_multiset_ = is_multiset; }
bool is_multiset() const {return is_multiset_; }
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const { return common::do_hash(ref_id_, seed); }
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_ID, ref_id_,
K_(output_column),
K_(is_set),
K_(is_cursor),
K_(is_multiset),
K_(column_types),
K_(enum_set_values),
N_CHILDREN, exec_params_);
private:
DISALLOW_COPY_AND_ASSIGN(ObQueryRefRawExpr);
//ObUnaryRefExpr是表示对一个stmt或者logical plan的引用,
//引用都是指针,对显示不够友好,所以加一个ref_id,用来展示给人看
int64_t ref_id_;
ObSelectStmt *ref_stmt_;
int64_t output_column_;
bool is_set_;
bool is_cursor_;
// Given a query_ref_expr in a function table,
// an exec param in the subquery may not belong to the query_ref_expr
// it may be a nlparam of a nest loop join
bool has_nl_param_;
bool is_multiset_;
//子查询的输出列类型
common::ObSEArray<ObExprResType, 64, common::ModulePageAllocator, true> column_types_;
common::ObSEArray<ObExecParamRawExpr *, 4, common::ModulePageAllocator, true> exec_params_;
};
inline int64_t ObQueryRefRawExpr::get_ref_id() const
{
return ref_id_;
}
inline void ObQueryRefRawExpr::set_ref_id(int64_t id)
{
ref_id_ = id;
}
inline void ObQueryRefRawExpr::set_output_column(int64_t output_column)
{
output_column_ = output_column;
}
inline int64_t ObQueryRefRawExpr::get_output_column() const
{
return output_column_;
}
////////////////////////////////////////////////////////////////
class ObColumnRefRawExpr : public ObTerminalRawExpr, public jit::expr::ObColumnRefExpr
{
public:
ObColumnRefRawExpr()
: ObIRawExpr(),
ObTerminalRawExpr(),
jit::expr::ObColumnRefExpr(),
table_id_(common::OB_INVALID_ID),
column_id_(common::OB_INVALID_ID),
database_name_(),
table_name_(),
synonym_name_(),
synonym_db_name_(),
column_name_(),
column_flags_(0),
dependant_expr_(NULL),
is_lob_column_(false),
is_joined_dup_column_(false),
is_unpivot_mocked_column_(false),
is_hidden_(false),
from_alias_table_(false),
is_rowkey_column_(false),
is_unique_key_column_(false),
is_mul_key_column_(false),
is_strict_json_column_(0),
srs_id_(UINT64_MAX),
udt_set_id_(0)
{
set_expr_class(ObIRawExpr::EXPR_COLUMN_REF);
}
ObColumnRefRawExpr(common::ObIAllocator &alloc)
: ObIRawExpr(alloc),
ObTerminalRawExpr(alloc),
ObColumnRefExpr(alloc),
table_id_(common::OB_INVALID_ID),
column_id_(common::OB_INVALID_ID),
database_name_(),
table_name_(),
synonym_name_(),
synonym_db_name_(),
column_name_(),
column_flags_(0),
dependant_expr_(NULL),
is_lob_column_(false),
is_joined_dup_column_(false),
is_unpivot_mocked_column_(false),
is_hidden_(false),
from_alias_table_(false),
is_rowkey_column_(false),
is_unique_key_column_(false),
is_mul_key_column_(false),
is_strict_json_column_(0),
srs_id_(UINT64_MAX),
udt_set_id_(0)
{
set_expr_class(ObIRawExpr::EXPR_COLUMN_REF);
}
ObColumnRefRawExpr(uint64_t first_id, uint64_t second_id, ObItemType expr_type = T_INVALID)
: ObIRawExpr(expr_type),
ObTerminalRawExpr(expr_type),
ObColumnRefExpr(expr_type),
table_id_(first_id),
column_id_(second_id),
database_name_(),
table_name_(),
synonym_name_(),
synonym_db_name_(),
column_name_(),
column_flags_(0),
dependant_expr_(NULL),
is_lob_column_(false),
is_joined_dup_column_(false),
is_unpivot_mocked_column_(false),
is_hidden_(false),
from_alias_table_(false),
is_rowkey_column_(false),
is_unique_key_column_(false),
is_mul_key_column_(false),
is_strict_json_column_(0),
srs_id_(UINT64_MAX),
udt_set_id_(0)
{
set_expr_class(ObIRawExpr::EXPR_COLUMN_REF);
}
virtual ~ObColumnRefRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
uint64_t get_table_id() const;
uint64_t get_column_id() const;
uint64_t &get_table_id();
uint64_t &get_column_id();
void set_ref_id(uint64_t table_id, uint64_t column_id);
void set_table_id(uint64_t table_id);
void set_hidden_id(uint64_t hidden_id);
void set_column_attr(const common::ObString &table_name,
const common::ObString &column_name);
inline void set_table_name(const common::ObString &table_name) { table_name_ = table_name; }
inline common::ObString &get_table_name() { return table_name_; }
inline const common::ObString &get_table_name() const { return table_name_; }
inline void set_synonym_name(const common::ObString &synonym_name) { synonym_name_ = synonym_name; }
inline common::ObString &get_synonym_name() { return synonym_name_; }
inline const common::ObString &get_synonym_name() const { return synonym_name_; }
inline void set_synonym_db_name(const common::ObString &synonym_db_name)
{
synonym_db_name_ = synonym_db_name;
}
inline common::ObString &get_synonym_db_name() { return synonym_db_name_; }
inline const common::ObString &get_synonym_db_name() const { return synonym_db_name_; }
inline void set_column_name(const common::ObString &column_name) { column_name_ = column_name; }
inline common::ObString &get_column_name() { return column_name_; }
inline const common::ObString &get_column_name() const { return column_name_; }
inline void set_database_name(const common::ObString &db_name) { database_name_ = db_name; }
inline const common::ObString &get_database_name() const { return database_name_; }
inline common::ObString &get_database_name() { return database_name_; }
inline int64_t get_cte_generate_column_projector_offset() const { return get_column_id() - common::OB_APP_MIN_COLUMN_ID; }
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
inline bool is_generated_column() const { return share::schema::ObSchemaUtils::is_generated_column(column_flags_); }
inline bool is_identity_column() const { return share::schema::ObSchemaUtils::is_identity_column(column_flags_); }
inline bool is_default_expr_v2_column() const { return share::schema::ObSchemaUtils::is_default_expr_v2_column(column_flags_); }
inline bool is_virtual_generated_column() const { return share::schema::ObSchemaUtils::is_virtual_generated_column(column_flags_); }
inline bool is_stored_generated_column() const { return share::schema::ObSchemaUtils::is_stored_generated_column(column_flags_); }
inline bool is_always_identity_column() const { return share::schema::ObSchemaUtils::is_always_identity_column(column_flags_); }
inline bool is_default_identity_column() const { return share::schema::ObSchemaUtils::is_default_identity_column(column_flags_); }
inline bool is_default_on_null_identity_column() const { return share::schema::ObSchemaUtils::is_default_on_null_identity_column(column_flags_); }
inline bool is_fulltext_column() const { return share::schema::ObSchemaUtils::is_fulltext_column(column_flags_); }
inline bool is_spatial_generated_column() const { return share::schema::ObSchemaUtils::is_spatial_generated_column(column_flags_); }
inline bool is_cte_generated_column() const { return share::schema::ObSchemaUtils::is_cte_generated_column(column_flags_); }
inline bool has_generated_column_deps() const { return column_flags_ & GENERATED_DEPS_CASCADE_FLAG; }
inline bool is_table_part_key_column() const { return column_flags_ & TABLE_PART_KEY_COLUMN_FLAG; }
inline bool is_table_part_key_org_column() const { return column_flags_ & TABLE_PART_KEY_COLUMN_ORG_FLAG; }
inline bool has_table_alias_name() const { return column_flags_ & TABLE_ALIAS_NAME_FLAG; }
void set_column_flags(uint64_t column_flags) { column_flags_ = column_flags; }
void set_table_alias_name() { column_flags_ |= TABLE_ALIAS_NAME_FLAG; }
inline uint64_t get_column_flags() const { return column_flags_; }
inline const ObRawExpr *get_dependant_expr() const { return dependant_expr_; }
inline ObRawExpr *&get_dependant_expr() { return dependant_expr_; }
inline void set_dependant_expr(ObRawExpr *expr) { dependant_expr_ = expr; }
bool is_lob_column() const { return is_lob_column_; }
void set_lob_column(bool is_lob_column) { is_lob_column_ = is_lob_column; }
bool is_unique_key_column() const { return is_unique_key_column_; }
void set_unique_key_column(bool v) { is_unique_key_column_ = v; }
bool is_mul_key_column() const { return is_mul_key_column_; }
void set_mul_key_column(bool v) { is_mul_key_column_ = v; }
int8_t is_strict_json_column() const { return is_strict_json_column_; }
void set_strict_json_column(int8_t v) { is_strict_json_column_ = v; }
bool is_joined_dup_column() const { return is_joined_dup_column_; }
void set_joined_dup_column(bool is_joined_dup_column) { is_joined_dup_column_ = is_joined_dup_column; }
bool is_unpivot_mocked_column() const { return is_unpivot_mocked_column_; }
void set_unpivot_mocked_column(const bool value) { is_unpivot_mocked_column_ = value; }
bool is_hidden_column() const { return is_hidden_; }
void set_hidden_column(const bool value) { is_hidden_ = value; }
bool is_from_alias_table() const { return from_alias_table_; }
void set_from_alias_table(bool value) { from_alias_table_ = value; }
bool is_rowkey_column() const { return is_rowkey_column_; }
void set_is_rowkey_column(bool value) { is_rowkey_column_ = value; }
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
inline uint64_t get_srs_id() const { return srs_id_; };
inline void set_srs_id(uint64_t srs_id) { srs_id_ = srs_id; };
inline uint64_t get_udt_set_id() const { return udt_set_id_; };
inline void set_udt_set_id(uint64_t udt_set_id) { udt_set_id_ = udt_set_id; };
bool is_xml_column() const { return ob_is_xml_pl_type(get_data_type(), get_udt_id())
|| ob_is_xml_sql_type(get_data_type(), get_subschema_id()); }
bool is_udt_hidden_column() const { return is_hidden_column() && get_udt_set_id() > 0;}
inline common::ObGeoType get_geo_type() const { return static_cast<common::ObGeoType>(srs_info_.geo_type_); }
VIRTUAL_TO_STRING_KV(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_TID, table_id_,
N_CID, column_id_,
K_(database_name),
K_(table_name),
K_(synonym_name),
K_(synonym_db_name),
K_(column_name),
K_(column_flags),
K_(enum_set_values),
K_(is_lob_column),
K_(is_joined_dup_column),
K_(is_unpivot_mocked_column),
K_(is_hidden),
K_(from_alias_table),
K_(is_rowkey_column),
K_(is_unique_key_column),
K_(is_mul_key_column),
K_(is_strict_json_column),
K_(srs_id),
K_(udt_set_id));
private:
DISALLOW_COPY_AND_ASSIGN(ObColumnRefRawExpr);
uint64_t table_id_;
uint64_t column_id_;
common::ObString database_name_;
common::ObString table_name_;
common::ObString synonym_name_;
common::ObString synonym_db_name_;
common::ObString column_name_;
uint64_t column_flags_; //same as flags in ObColumnSchemaV2
ObRawExpr *dependant_expr_; //TODO: @yuming.wyc @ryan.ly
bool is_lob_column_; //TODO @hanhui add lob column
bool is_joined_dup_column_; //is duplicated column in join (not in using). e.g., t1 (c1, c2) cross join t2 (c2,c3), c2 in t1 and t2 are joined_dup_column_
bool is_unpivot_mocked_column_; //used for unpivot
bool is_hidden_; //used for print hidden column
bool from_alias_table_;
bool is_rowkey_column_;
bool is_unique_key_column_;
bool is_mul_key_column_;
int8_t is_strict_json_column_;
union { // for geometry column
struct {
uint32_t geo_type_ : 5;
uint32_t reserved_: 27;
uint32_t srid_ : 32;
} srs_info_;
uint64_t srs_id_;
};
uint64_t udt_set_id_;
};
inline void ObColumnRefRawExpr::set_ref_id(uint64_t table_id, uint64_t column_id)
{
table_id_ = table_id;
column_id_ = column_id;
}
inline void ObColumnRefRawExpr::set_table_id(uint64_t table_id)
{
table_id_ = table_id;
}
inline uint64_t ObColumnRefRawExpr::get_table_id() const
{
return table_id_;
}
inline uint64_t ObColumnRefRawExpr::get_column_id() const
{
return column_id_;
}
inline uint64_t &ObColumnRefRawExpr::get_table_id()
{
return table_id_;
}
inline uint64_t &ObColumnRefRawExpr::get_column_id()
{
return column_id_;
}
////////////////////////////////////////////////////////////////
class ObSetOpRawExpr : public ObTerminalRawExpr
{
public:
ObSetOpRawExpr()
: ObTerminalRawExpr(), idx_(-1) {
set_expr_class(ObIRawExpr::EXPR_SET_OP);
}
ObSetOpRawExpr(common::ObIAllocator &alloc)
: ObTerminalRawExpr(alloc), idx_(-1) {
set_expr_class(ObIRawExpr::EXPR_SET_OP);
}
virtual ~ObSetOpRawExpr() {}
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
int assign(const ObRawExpr &other) override;
void set_idx(int64_t idx) { idx_ = idx; }
int64_t get_idx() const { return idx_; }
VIRTUAL_TO_STRING_KV(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
K_(idx));
private:
DISALLOW_COPY_AND_ASSIGN(ObSetOpRawExpr);
int64_t idx_; // set op expr 对应 child stmt select expr 的 index
};
////////////////////////////////////////////////////////////////
class ObAliasRefRawExpr : public ObRawExpr
{
public:
ObAliasRefRawExpr()
: ObRawExpr(),
ref_expr_(NULL)
{
set_expr_class(ObIRawExpr::EXPR_ALIAS_REF);
}
ObAliasRefRawExpr(common::ObIAllocator &alloc)
: ObRawExpr(alloc),
ref_expr_(NULL),
project_index_(OB_INVALID_INDEX)
{
set_expr_class(ObIRawExpr::EXPR_ALIAS_REF);
}
virtual ~ObAliasRefRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
const ObRawExpr *get_ref_expr() const;
ObRawExpr *get_ref_expr();
void set_ref_expr(ObRawExpr *ref_expr) { ref_expr_ = ref_expr; }
bool is_ref_query_output() const
{ return ref_expr_->is_query_ref_expr() && project_index_ != OB_INVALID_INDEX; }
int64_t get_project_index() const { return project_index_; }
void set_query_output(ObQueryRefRawExpr *query_ref,
int64_t project_index)
{ ref_expr_ = query_ref; project_index_ = project_index; }
virtual void clear_child() override { ref_expr_ = NULL; project_index_ = OB_INVALID_INDEX; }
virtual int64_t get_param_count() const override { return 1; }
virtual const ObRawExpr *get_param_expr(int64_t index) const override;
virtual ObRawExpr *&get_param_expr(int64_t index) override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_VALUE, ref_expr_,
K_(enum_set_values));
private:
DISALLOW_COPY_AND_ASSIGN(ObAliasRefRawExpr);
ObRawExpr *ref_expr_;
int64_t project_index_; // project index of the subquery
};
////////////////////////////////////////////////////////////////
class ObNonTerminalRawExpr : public ObRawExpr
{
public:
ObNonTerminalRawExpr() : ObRawExpr(), op_(NULL), input_types_()
{}
ObNonTerminalRawExpr(common::ObIAllocator &alloc) : ObRawExpr(alloc), op_(NULL), input_types_()
{}
virtual ~ObNonTerminalRawExpr() { free_op(); }
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
virtual void reset() { free_op(); input_types_.reset(); }
virtual ObExprOperator *get_op();
void free_op();
/*
* 为了在Resolve阶段记录下函数操作数的目标类型,引入input_types_。
* input_types_在CG阶段会通过get_input_types取出并设置到ObExprOperator中
* 用于计算阶段对操作数进行动态类型转换
*/
int set_input_types(const ObIExprResTypes &input_types);
inline const ObExprResTypes &get_input_types() { return input_types_; }
inline int64_t get_input_types_count() const { return input_types_.count(); }
virtual uint64_t hash_internal(uint64_t seed) const { return seed; }
protected:
// data members
ObExprOperator *op_;
ObExprResTypes input_types_;
DISALLOW_COPY_AND_ASSIGN(ObNonTerminalRawExpr);
};
////////////////////////////////////////////////////////////////
class ObOpRawExpr :
public ObNonTerminalRawExpr,
public jit::expr::ObOpExpr
{
public:
ObOpRawExpr() : ObIRawExpr(),
ObNonTerminalRawExpr(),
ObOpExpr(),
exprs_(),
subquery_key_(T_WITH_NONE),
deduce_type_adding_implicit_cast_(true)
{ set_expr_class(ObIRawExpr::EXPR_OPERATOR);}
ObOpRawExpr(common::ObIAllocator &alloc) : ObIRawExpr(alloc),
ObNonTerminalRawExpr(alloc),
ObOpExpr(alloc),
exprs_(),
subquery_key_(T_WITH_NONE),
deduce_type_adding_implicit_cast_(true)
{ set_expr_class(ObIRawExpr::EXPR_OPERATOR); }
ObOpRawExpr(ObRawExpr *first_expr, ObRawExpr *second_expr, ObItemType type); //binary op
virtual ~ObOpRawExpr() {}
int assign(const ObRawExpr &other) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
int set_param_expr(ObRawExpr *expr); // unary op
int set_param_exprs(ObRawExpr *first_expr, ObRawExpr *second_expr); // binary op
int set_param_exprs(ObRawExpr *first_expr, ObRawExpr *second_expr, ObRawExpr *third_expr); // triple op
int add_param_expr(ObRawExpr *expr);
int remove_param_expr(int64_t index);
int replace_param_expr(int64_t index, ObRawExpr *expr);
bool deduce_type_adding_implicit_cast() const { return deduce_type_adding_implicit_cast_; }
void set_deduce_type_adding_implicit_cast(const bool v) { deduce_type_adding_implicit_cast_ = v; }
void set_expr_type(ObItemType type);
common::ObIArray<ObRawExpr *> &get_param_exprs() { return exprs_; }
const common::ObIArray<ObRawExpr *> &get_param_exprs() const { return exprs_; }
int64_t get_param_count() const;
const ObRawExpr *get_param_expr(int64_t index) const;
ObRawExpr *&get_param_expr(int64_t index);
virtual int64_t get_output_column() const
{
return T_OP_ROW == get_expr_type() ? get_param_count() : -1;
}
virtual void clear_child() override;
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
//used for jit expr
virtual int64_t get_children_count() const
{
return exprs_.count();
}
//used for jit expr
virtual int get_children(jit::expr::ExprArray &jit_exprs) const;
//如果操作符中后面跟随的是一个带关键字的子查询,需要记录下该关键字
void set_subquery_key(ObSubQueryKey &key) { subquery_key_ = key; }
ObSubQueryKey get_subquery_key() { return subquery_key_; }
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
int get_subquery_comparison_name(const common::ObString &symbol,
char *buf,
int64_t buf_len,
int64_t &pos,
ExplainType type) const;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_CHILDREN, exprs_);
protected:
common::ObSEArray<ObRawExpr *, COMMON_MULTI_NUM, common::ModulePageAllocator, true> exprs_;
ObSubQueryKey subquery_key_;
bool deduce_type_adding_implicit_cast_;
private:
DISALLOW_COPY_AND_ASSIGN(ObOpRawExpr);
};
inline const ObRawExpr *ObOpRawExpr::get_param_expr(int64_t index) const
{
const ObRawExpr *expr = NULL;
if (index >= 0 && index < exprs_.count()) {
expr = exprs_.at(index);
}
return expr;
}
//here must return in two branch, because ret value is a *&
inline ObRawExpr *&ObOpRawExpr::get_param_expr(int64_t index)
{
if (index >= 0 && index < exprs_.count()) {
return exprs_.at(index);
} else {
return USELESS_POINTER;
}
}
inline int ObOpRawExpr::add_param_expr(ObRawExpr *expr)
{
return exprs_.push_back(expr);
}
inline int ObOpRawExpr::remove_param_expr(int64_t index)
{
int ret = common::OB_SUCCESS;
if (index < 0 || index >= exprs_.count()) {
ret = common::OB_INVALID_ARGUMENT;
} else {
ret = exprs_.remove(index);
}
return ret;
}
inline int ObOpRawExpr::replace_param_expr(int64_t index, ObRawExpr *expr)
{
int ret = common::OB_SUCCESS;
if (index < 0 || index >= exprs_.count()) {
ret = common::OB_INVALID_ARGUMENT;
} else {
ObRawExpr *&target_expr = exprs_.at(index);
target_expr = expr;
}
return ret;
}
inline int64_t ObOpRawExpr::get_param_count() const
{
return exprs_.count();
}
inline uint64_t ObOpRawExpr::hash_internal(uint64_t seed) const
{
uint64_t hash_value = seed;
for (int64_t i = 0; i < exprs_.count(); ++i) {
if (NULL != exprs_.at(i)) {
hash_value = common::do_hash(*(exprs_.at(i)), hash_value);
}
}
return hash_value;
}
////////////////////////////////////////////////////////////////
class ObCaseOpRawExpr : public ObNonTerminalRawExpr, public jit::expr::ObCaseOpExpr
{
public:
ObCaseOpRawExpr()
: ObIRawExpr(),
ObNonTerminalRawExpr(),
ObCaseOpExpr(),
arg_expr_(NULL),
when_exprs_(),
then_exprs_(),
default_expr_(NULL),
is_decode_func_(false)
{
set_expr_class(ObIRawExpr::EXPR_CASE_OPERATOR);
}
ObCaseOpRawExpr(common::ObIAllocator &alloc)
: ObIRawExpr(alloc),
ObNonTerminalRawExpr(alloc),
ObCaseOpExpr(),
arg_expr_(NULL),
when_exprs_(),
then_exprs_(),
default_expr_(NULL),
is_decode_func_(false)
{
set_expr_class(ObIRawExpr::EXPR_CASE_OPERATOR);
}
virtual ~ObCaseOpRawExpr() {}
int assign(const ObRawExpr &other) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
const ObRawExpr *get_arg_param_expr() const;
const ObRawExpr *get_default_param_expr() const;
const ObRawExpr *get_when_param_expr(int64_t index) const;
const ObRawExpr *get_then_param_expr(int64_t index) const;
ObRawExpr *&get_arg_param_expr();
inline common::ObIArray<ObRawExpr*> &get_when_param_exprs() { return when_exprs_; }
inline const common::ObIArray<ObRawExpr*> &get_when_param_exprs() const { return when_exprs_; }
inline common::ObIArray<ObRawExpr*> &get_then_param_exprs() { return then_exprs_; }
inline const common::ObIArray<ObRawExpr*> &get_then_param_exprs() const { return then_exprs_; }
ObRawExpr *&get_default_param_expr();
ObRawExpr *&get_when_param_expr(int64_t index);
ObRawExpr *&get_then_param_expr(int64_t index);
void set_arg_param_expr(ObRawExpr *expr);
void set_default_param_expr(ObRawExpr *expr);
int add_when_param_expr(ObRawExpr *expr);
int add_then_param_expr(ObRawExpr *expr);
int replace_when_param_expr(int64_t index, ObRawExpr *expr);
int replace_then_param_expr(int64_t index, ObRawExpr *expr);
int replace_param_expr(int64_t index, ObRawExpr *new_expr);
int64_t get_when_expr_size() const;
int64_t get_then_expr_size() const;
bool is_arg_case() const { return NULL != arg_expr_; }
bool is_decode_func() const { return is_decode_func_; }
virtual void clear_child() override;
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual int64_t get_param_count() const;
virtual const ObRawExpr *get_param_expr(int64_t index) const;
virtual ObRawExpr *&get_param_expr(int64_t index);
//used for jit
virtual int64_t get_children_count() const
{
return get_param_count();
}
virtual int get_children(jit::expr::ExprArray &jit_exprs) const;
virtual uint64_t hash_internal(uint64_t seed) const;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_ARG_CASE, arg_expr_,
N_DEFAULT, default_expr_,
N_WHEN, when_exprs_,
N_THEN, then_exprs_,
N_DECODE, is_decode_func_);
private:
DISALLOW_COPY_AND_ASSIGN(ObCaseOpRawExpr);
ObRawExpr *arg_expr_;
common::ObSEArray<ObRawExpr *, COMMON_MULTI_NUM, common::ModulePageAllocator, true> when_exprs_;
common::ObSEArray<ObRawExpr *, COMMON_MULTI_NUM, common::ModulePageAllocator, true> then_exprs_;
ObRawExpr *default_expr_;
bool is_decode_func_;
};
inline const ObRawExpr *ObCaseOpRawExpr::get_arg_param_expr() const
{
return arg_expr_;
}
inline const ObRawExpr *ObCaseOpRawExpr::get_default_param_expr() const
{
return default_expr_;
}
inline const ObRawExpr *ObCaseOpRawExpr::get_when_param_expr(int64_t index) const
{
ObRawExpr *expr = NULL;
if (OB_LIKELY(index >= 0 && index < when_exprs_.count())) {
expr = when_exprs_.at(index);
} else {}
return expr;
}
inline const ObRawExpr *ObCaseOpRawExpr::get_then_param_expr(int64_t index) const
{
ObRawExpr *expr = NULL;
if (OB_LIKELY(index >= 0 || index < then_exprs_.count())) {
expr = then_exprs_.at(index);
} else {}
return expr;
}
inline ObRawExpr *&ObCaseOpRawExpr::get_arg_param_expr()
{
return arg_expr_;
}
inline ObRawExpr *&ObCaseOpRawExpr::get_default_param_expr()
{
return default_expr_;
}
//here must return in two branch, because ret value is a *&
inline ObRawExpr *&ObCaseOpRawExpr::get_when_param_expr(int64_t index)
{
if (OB_LIKELY(index >= 0 && index < when_exprs_.count())) {
return when_exprs_.at(index);
} else {
return USELESS_POINTER;
}
}
//here must return in two branch, because ret value is a *&
inline ObRawExpr *&ObCaseOpRawExpr::get_then_param_expr(int64_t index)
{
if (OB_LIKELY(index >= 0 && index < then_exprs_.count())) {
return then_exprs_.at(index);
} else {
return USELESS_POINTER;
}
}
inline void ObCaseOpRawExpr::set_arg_param_expr(ObRawExpr *expr)
{
arg_expr_ = expr;
}
inline void ObCaseOpRawExpr::set_default_param_expr(ObRawExpr *expr)
{
default_expr_ = expr;
}
inline int ObCaseOpRawExpr::add_when_param_expr(ObRawExpr *expr)
{
int ret = when_exprs_.push_back(expr);
return ret;
}
inline int ObCaseOpRawExpr::add_then_param_expr(ObRawExpr *expr)
{
int ret = then_exprs_.push_back(expr);
return ret;
}
inline int ObCaseOpRawExpr::replace_when_param_expr(int64_t index, ObRawExpr *expr)
{
int ret = common::OB_SUCCESS;
if (OB_UNLIKELY((index < 0 || index >= when_exprs_.count()))) {
ret = common::OB_ERR_UNEXPECTED;
} else {
when_exprs_.at(index) = expr;
}
return ret;
}
inline int ObCaseOpRawExpr::replace_then_param_expr(int64_t index,
ObRawExpr *expr)
{
int ret = common::OB_SUCCESS;
if (OB_UNLIKELY((index < 0 || index >= then_exprs_.count()))) {
ret = common::OB_ERR_UNEXPECTED;
} else {
then_exprs_.at(index) = expr;
}
return ret;
}
inline int64_t ObCaseOpRawExpr::get_when_expr_size() const
{
return when_exprs_.count();
}
inline int64_t ObCaseOpRawExpr::get_then_expr_size() const
{
return then_exprs_.count();
}
inline int64_t ObCaseOpRawExpr::get_param_count() const
{
return when_exprs_.count() + then_exprs_.count()
+ (NULL == arg_expr_ ? 0 : 1)
+ (NULL == default_expr_ ? 0 : 1);
}
inline uint64_t ObCaseOpRawExpr::hash_internal(uint64_t seed) const
{
if (arg_expr_) {
seed = common::do_hash(*arg_expr_, seed);
}
for (int64_t i = 0; i < when_exprs_.count(); ++i) {
if (OB_LIKELY(NULL != when_exprs_.at(i))) {
seed = common::do_hash(*(when_exprs_.at(i)), seed);
}
}
for (int64_t i = 0; i < then_exprs_.count(); ++i) {
if (OB_LIKELY(NULL != then_exprs_.at(i))) {
seed = common::do_hash(*(then_exprs_.at(i)), seed);
}
}
if (NULL != default_expr_) {
seed = common::do_hash(*default_expr_, seed);
}
seed = common::do_hash(is_decode_func_, seed);
return seed;
}
////////////////////////////////////////////////////////////////
class ObAggFunRawExpr : public ObRawExpr
{
public:
ObAggFunRawExpr()
: ObRawExpr(),
real_param_exprs_(),
distinct_(false),
order_items_(),
separator_param_expr_(NULL),
udf_meta_(),
is_nested_aggr_(false),
is_need_deserialize_row_(false),
pl_agg_udf_expr_(NULL)
{
set_expr_class(ObIRawExpr::EXPR_AGGR);
order_items_.set_label(common::ObModIds::OB_SQL_AGGR_FUNC_ARR);
}
ObAggFunRawExpr(common::ObIAllocator &alloc)
: ObRawExpr(alloc),
real_param_exprs_(),
distinct_(false),
order_items_(),
separator_param_expr_(NULL),
udf_meta_(),
is_nested_aggr_(false),
is_need_deserialize_row_(false),
pl_agg_udf_expr_(NULL)
{
set_expr_class(ObIRawExpr::EXPR_AGGR);
order_items_.set_label(common::ObModIds::OB_SQL_AGGR_FUNC_ARR);
}
ObAggFunRawExpr(const common::ObSEArray<ObRawExpr *, 1, common::ModulePageAllocator, true> &real_param_exprs,
bool is_distinct, ObItemType expr_type = T_INVALID)
: ObRawExpr(expr_type),
real_param_exprs_(real_param_exprs),
distinct_(is_distinct),
order_items_(),
separator_param_expr_(NULL),
udf_meta_(),
is_nested_aggr_(false),
is_need_deserialize_row_(false),
pl_agg_udf_expr_(NULL)
{
set_expr_class(ObIRawExpr::EXPR_AGGR);
order_items_.set_label(common::ObModIds::OB_SQL_AGGR_FUNC_ARR);
}
virtual ~ObAggFunRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
int add_real_param_expr(ObRawExpr *expr);
int replace_real_param_expr(int64_t index, ObRawExpr *expr);
int replace_param_expr(int64_t index, ObRawExpr *expr);
bool contain_nested_aggr() const;
bool is_param_distinct() const;
void set_param_distinct(bool is_distinct);
void set_separator_param_expr(ObRawExpr *separator_param_expr);
bool is_nested_aggr() const;
void set_in_nested_aggr(bool is_nested);
int add_order_item(const OrderItem &order_item);
virtual void clear_child() override;
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int64_t get_param_count() const;
virtual const ObRawExpr *get_param_expr(int64_t index) const;
virtual ObRawExpr *&get_param_expr(int64_t index);
inline int64_t get_real_param_count() const { return real_param_exprs_.count(); }
inline const common::ObIArray<ObRawExpr*> &get_real_param_exprs() const { return real_param_exprs_; }
inline common::ObIArray<ObRawExpr*> &get_real_param_exprs_for_update() { return real_param_exprs_; }
virtual int do_visit(ObRawExprVisitor &visitor) override;
inline ObRawExpr *get_separator_param_expr() const { return separator_param_expr_; }
inline const common::ObIArray<OrderItem> &get_order_items() const { return order_items_; }
//可能在外面修改order_items_,慎用
inline common::ObIArray<OrderItem> &get_order_items_for_update() { return order_items_; }
inline bool is_need_deserialize_row() const { return is_need_deserialize_row_; }
void set_is_need_deserialize_row(bool is_need) { is_need_deserialize_row_ = is_need; }
inline void set_pl_agg_udf_expr(ObRawExpr *udf_expr) { pl_agg_udf_expr_ = udf_expr; }
inline ObRawExpr *get_pl_agg_udf_expr() const { return pl_agg_udf_expr_; }
virtual uint64_t hash_internal(uint64_t seed) const
{
for (int64_t i = 0; i < real_param_exprs_.count(); ++i) {
if (OB_LIKELY(NULL != real_param_exprs_.at(i))) {
seed = common::do_hash(*real_param_exprs_.at(i), seed);
}
}
seed = common::do_hash(distinct_, seed);
for (int64_t i = 0; i < order_items_.count(); ++i) {
seed = common::do_hash(order_items_.at(i), seed);
}
if (NULL != separator_param_expr_) {
seed = common::do_hash(*separator_param_expr_, seed);
}
seed = common::do_hash(is_need_deserialize_row_, seed);
return seed;
}
//set udf meta to this expr
int set_udf_meta(const share::schema::ObUDF &udf);
const share::schema::ObUDFMeta get_udf_meta() { return udf_meta_; }
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
const char *get_name_dblink(ObItemType expr_type) const;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_CHILDREN, real_param_exprs_,
N_DISTINCT, distinct_,
N_ORDER_BY, order_items_,
N_SEPARATOR_PARAM_EXPR, separator_param_expr_,
K_(udf_meta),
K_(is_nested_aggr),
K_(pl_agg_udf_expr));
private:
DISALLOW_COPY_AND_ASSIGN(ObAggFunRawExpr);
// real_param_exprs_.count() == 0 means '*'
common::ObSEArray<ObRawExpr*, 1, common::ModulePageAllocator, true> real_param_exprs_;
bool distinct_;
// used for group_concat/rank/percent rank/dense rank/cume dist
common::ObArray<OrderItem, common::ModulePageAllocator, true> order_items_;
ObRawExpr *separator_param_expr_;
//use for udf function info
share::schema::ObUDFMeta udf_meta_;
bool is_nested_aggr_;
bool is_need_deserialize_row_;// for topk histogram and hybrid histogram computaion
ObRawExpr *pl_agg_udf_expr_;//for pl agg udf expr
};
inline int ObAggFunRawExpr::add_real_param_expr(ObRawExpr *expr)
{
int ret = common::OB_SUCCESS;
if (OB_UNLIKELY(NULL == expr)) {
ret = common::OB_INVALID_ARGUMENT;
} else {
ret = real_param_exprs_.push_back(expr);
}
return ret;
}
inline int ObAggFunRawExpr::replace_real_param_expr(int64_t index, ObRawExpr *expr)
{
int ret = common::OB_SUCCESS;
if (OB_UNLIKELY(index < 0 || index >= real_param_exprs_.count())) {
ret = common::OB_INVALID_ARGUMENT;
} else if (OB_UNLIKELY(NULL == expr)) {
ret = common::OB_INVALID_ARGUMENT;
} else {
ObRawExpr *&target_expr = real_param_exprs_.at(index);
target_expr = expr;
}
return ret;
}
inline int ObAggFunRawExpr::replace_param_expr(int64_t index, ObRawExpr *expr)
{
int ret = common::OB_SUCCESS;
if (OB_UNLIKELY(index < 0 || index >= get_param_count())) {
ret = common::OB_INVALID_ARGUMENT;
} else if (OB_UNLIKELY(NULL == expr)) {
ret = common::OB_INVALID_ARGUMENT;
} else if (index >= real_param_exprs_.count()) {
ObRawExpr *&target_expr = order_items_.at(index - real_param_exprs_.count()).expr_;
target_expr = expr;
} else {
ObRawExpr *&target_expr = real_param_exprs_.at(index);
target_expr = expr;
}
return ret;
}
inline bool ObAggFunRawExpr::is_param_distinct() const
{
return distinct_;
}
inline bool ObAggFunRawExpr::is_nested_aggr() const
{
return is_nested_aggr_;
}
inline bool ObAggFunRawExpr::contain_nested_aggr() const
{
bool ret = false;
for (int64 i = 0; !ret && i < get_param_count(); i++) {
if (get_param_expr(i)->has_flag(CNT_AGG)) {
ret = true;
} else { /*do nothing.*/ }
}
return ret;
}
inline void ObAggFunRawExpr::set_param_distinct(bool is_distinct) { distinct_ = is_distinct; }
inline void ObAggFunRawExpr::set_in_nested_aggr(bool is_nested) { is_nested_aggr_ = is_nested; }
inline void ObAggFunRawExpr::set_separator_param_expr(ObRawExpr *separator_param_expr)
{
separator_param_expr_ = separator_param_expr;
}
inline int ObAggFunRawExpr::add_order_item(const OrderItem &order_item)
{
return order_items_.push_back(order_item);
}
////////////////////////////////////////////////////////////////
// for normal system function, func_name_ is used to distinguish them.
// for special system function, ObRawExpr::type_ can be reset. Such function may not need name
class ObSysFunRawExpr : public ObOpRawExpr
{
public:
ObSysFunRawExpr(common::ObIAllocator &alloc)
: ObOpRawExpr(alloc),
func_name_(),
operator_id_(common::OB_INVALID_ID)
{ set_expr_class(ObIRawExpr::EXPR_SYS_FUNC); }
ObSysFunRawExpr()
: ObOpRawExpr(),
func_name_(),
operator_id_(common::OB_INVALID_ID)
{ set_expr_class(ObIRawExpr::EXPR_SYS_FUNC); }
virtual ~ObSysFunRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
void set_func_name(const common::ObString &name);
const common::ObString &get_func_name() const;
virtual void clear_child() override;
int check_param_num();
int check_param_num(int param_count);
virtual ObExprOperator *get_op();
virtual void reset();
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const
{
uint64_t hash_ret = common::do_hash(func_name_, seed);
return hash_ret;
}
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
int get_cast_type_name(char *buf, int64_t buf_len, int64_t &pos) const;
int get_column_conv_name(char *buf, int64_t buf_len, int64_t &pos, ExplainType type) const;
int get_autoinc_nextval_name(char *buf, int64_t buf_len, int64_t &pos) const;
void set_op_id(int64_t operator_id) { operator_id_ = operator_id; }
int64_t get_op_id() const { return operator_id_; }
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_FUNC, func_name_,
N_CHILDREN, exprs_,
K_(enum_set_values));
private:
int check_param_num_internal(int32_t param_num, int32_t param_count, ObExprOperatorType type);
DISALLOW_COPY_AND_ASSIGN(ObSysFunRawExpr);
common::ObString func_name_;
//用于记录rownum表达式归属的count算子的op_id_
uint64_t operator_id_;
};
inline void ObSysFunRawExpr::set_func_name(const common::ObString &name)
{
func_name_ = name;
}
inline const common::ObString &ObSysFunRawExpr::get_func_name() const
{
return func_name_;
}
class ObSequenceRawExpr : public ObSysFunRawExpr
{
public:
ObSequenceRawExpr(common::ObIAllocator &alloc)
: ObSysFunRawExpr(alloc), database_name_(), name_(), action_(), sequence_id_(0) {}
ObSequenceRawExpr()
: ObSysFunRawExpr(), database_name_(), name_(), action_(), sequence_id_(0) {}
virtual ~ObSequenceRawExpr() = default;
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
int set_sequence_meta(const common::ObString &database_name,
const common::ObString &name,
const common::ObString &action,
uint64_t sequence_id);
const common::ObString &get_database_name() { return database_name_; }
const common::ObString &get_name() { return name_; }
const common::ObString &get_action() const { return action_; }
uint64_t get_sequence_id() const { return sequence_id_; }
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const override;
private:
common::ObString database_name_; // sequence database name
common::ObString name_; // sequence object name
common::ObString action_; // NEXTVAL or CURRVAL
uint64_t sequence_id_; // 这个值也包装成 expr 放到 ObSysFunRawExpr 的 param 中了
};
class ObNormalDllUdfRawExpr : public ObSysFunRawExpr
{
public:
ObNormalDllUdfRawExpr(common::ObIAllocator &alloc) : ObSysFunRawExpr(alloc), udf_meta_(), udf_attributes_() {}
ObNormalDllUdfRawExpr() : ObSysFunRawExpr(), udf_meta_(), udf_attributes_() {}
virtual ~ObNormalDllUdfRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
int set_udf_meta(const share::schema::ObUDF &udf);
int add_udf_attribute_name(const common::ObString &name);
int add_udf_attribute(const ObRawExpr *expr, const ParseNode *node);
const share::schema::ObUDFMeta &get_udf_meta() const { return udf_meta_; }
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
private:
//for udf function info
share::schema::ObUDFMeta udf_meta_;
common::ObSEArray<common::ObString, 16> udf_attributes_;// name of input expr
};
class ObCollectionConstructRawExpr : public ObSysFunRawExpr
{
public:
ObCollectionConstructRawExpr(common::ObIAllocator &alloc)
: ObSysFunRawExpr(alloc),
type_(pl::ObPLType::PL_INVALID_TYPE),
elem_type_(),
capacity_(OB_INVALID_SIZE),
udt_id_(OB_INVALID_ID),
database_id_(OB_INVALID_ID),
coll_schema_version_(common::OB_INVALID_VERSION) {}
ObCollectionConstructRawExpr()
: ObSysFunRawExpr(),
type_(pl::ObPLType::PL_INVALID_TYPE),
elem_type_(),
capacity_(OB_INVALID_SIZE),
udt_id_(OB_INVALID_ID),
database_id_(OB_INVALID_ID),
coll_schema_version_(common::OB_INVALID_VERSION) {}
virtual ~ObCollectionConstructRawExpr() {}
inline void set_type(pl::ObPLType type) { type_ = type; }
inline void set_elem_type(const pl::ObPLDataType &type) { new(&elem_type_)pl::ObPLDataType(type); }
inline void set_capacity(int64_t capacity) { capacity_ = capacity; }
inline void set_udt_id(uint64_t udt_id) { udt_id_ = udt_id; }
int set_access_names(const common::ObIArray<ObObjAccessIdent> &access_idents);
const common::ObIArray<ObString>& get_access_names() const { return access_names_; }
pl::ObPLType get_type() const { return type_; }
bool is_not_null() const { return elem_type_.is_not_null(); }
const pl::ObPLDataType& get_elem_type() const { return elem_type_; }
int64_t get_capacity() const { return capacity_; }
uint64_t get_udt_id() const { return udt_id_; }
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual ObExprOperator *get_op() override;
inline void set_database_id(int64_t database_id)
{
database_id_ = database_id;
}
OB_INLINE uint64_t get_database_id() const { return database_id_; }
inline void set_coll_schema_version(int64_t schema_version)
{
coll_schema_version_ = schema_version;
}
inline bool need_add_dependency()
{
return coll_schema_version_ != common::OB_INVALID_VERSION;
}
int get_schema_object_version(share::schema::ObSchemaObjVersion &obj_version);
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_FUNC, get_func_name(),
N_CHILDREN, exprs_,
K_(coll_schema_version));
private:
pl::ObPLType type_; // PL_NESTED_TABLE_TYPE|PL_ASSOCIATIVE_ARRAY_TYPE|PL_VARRAY_TYPE
pl::ObPLDataType elem_type_; // 记录复杂数据类型的元素类型
int64_t capacity_; //记录VArray的容量,对于NestedTable为-1
uint64_t udt_id_; // 记录复杂类型的ID
// 用于打印构造函数的名字
common::ObSEArray<common::ObString, 4, common::ModulePageAllocator, true> access_names_;
int64_t database_id_;
int64_t coll_schema_version_;
};
class ObObjectConstructRawExpr : public ObSysFunRawExpr
{
public:
ObObjectConstructRawExpr(common::ObIAllocator &alloc)
: ObSysFunRawExpr(alloc),
rowsize_(0),
udt_id_(OB_INVALID_ID),
elem_types_(),
access_names_(),
database_id_(OB_INVALID_ID),
object_schema_version_(common::OB_INVALID_VERSION) {}
ObObjectConstructRawExpr()
: ObSysFunRawExpr(),
rowsize_(0),
udt_id_(OB_INVALID_ID),
elem_types_(),
access_names_(),
database_id_(OB_INVALID_ID),
object_schema_version_(common::OB_INVALID_VERSION) {}
virtual ~ObObjectConstructRawExpr() {}
inline void set_rowsize(int64_t rowsize) { rowsize_ = rowsize; }
int64_t get_rowsize() { return rowsize_; }
inline void set_udt_id(uint64_t udt_id) { udt_id_ = udt_id; }
uint64_t get_udt_id() { return udt_id_; }
inline int add_elem_type(ObExprResType &elem_type)
{
return elem_types_.push_back(elem_type);
}
inline int set_elem_types(common::ObIArray<ObExprResType> &elem_types)
{
return elem_types_.assign(elem_types);
}
inline const common::ObIArray<ObExprResType>& get_elem_types()
{
return elem_types_;
}
int set_access_names(const common::ObIArray<ObObjAccessIdent> &access_idents);
int add_access_name(const common::ObString &access_name) { return access_names_.push_back(access_name); }
const common::ObIArray<ObString>& get_access_names() const { return access_names_; }
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
inline void set_database_id(int64_t database_id)
{
database_id_ = database_id;
}
OB_INLINE uint64_t get_database_id() const { return database_id_; }
inline void set_coll_schema_version(int64_t schema_version)
{
object_schema_version_ = schema_version;
}
inline bool need_add_dependency()
{
return object_schema_version_ != common::OB_INVALID_VERSION;
}
int get_schema_object_version(share::schema::ObSchemaObjVersion &obj_version);
virtual ObExprOperator *get_op() override;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_FUNC, get_func_name(),
N_CHILDREN, exprs_,
K_(database_id),
K_(object_schema_version));
private:
int64_t rowsize_;
uint64_t udt_id_;
// 记录Object每个元素的类型
common::ObSEArray<ObExprResType, 5, common::ModulePageAllocator, true> elem_types_;
// 用于打印构造函数的名字
common::ObSEArray<common::ObString, 4, common::ModulePageAllocator, true> access_names_;
int64_t database_id_;
int64_t object_schema_version_;
};
class ObUDFParamDesc
{
public:
enum OutType {
NOT_OUT,
OBJ_ACCESS_OUT,
LOCAL_OUT,
PACKAGE_VAR_OUT,
SUBPROGRAM_VAR_OUT
};
OutType type_;
int64_t id1_; // variable index
int64_t id2_; // subprogram id
int64_t id3_; // package id
ObUDFParamDesc()
: type_(OutType::NOT_OUT), id1_(OB_INVALID_ID), id2_(OB_INVALID_ID), id3_(OB_INVALID_ID) {}
ObUDFParamDesc(OutType type,
int64_t id1 = OB_INVALID_ID,
int64_t id2 = OB_INVALID_ID,
int64_t id3 = OB_INVALID_ID)
: type_(type), id1_(id1), id2_(id2), id3_(id3) {}
OB_INLINE bool operator==(const ObUDFParamDesc &other) const {
return type_ == other.type_ && id1_ == other.id1_ &&
id2_ == other.id2_ && id3_ == other.id3_; }
OB_INLINE bool is_out() const { return type_ != NOT_OUT; }
OB_INLINE bool is_local_out() const { return OutType::LOCAL_OUT == type_; }
OB_INLINE bool is_package_var_out() const { return OutType::PACKAGE_VAR_OUT == type_; }
OB_INLINE bool is_subprogram_var_out() const { return OutType::SUBPROGRAM_VAR_OUT == type_; }
OB_INLINE bool is_obj_access_out() const { return OutType::OBJ_ACCESS_OUT == type_; }
OB_INLINE int64_t get_index() const { return id1_; }
OB_INLINE int64_t get_subprogram_id() const { return id2_; }
OB_INLINE int64_t get_package_id() const { return id3_; }
TO_STRING_KV(K_(type), K_(id1), K_(id2), K_(id3));
NEED_SERIALIZE_AND_DESERIALIZE;
};
class ObUDFRawExpr : public ObSysFunRawExpr
{
public:
ObUDFRawExpr(common::ObIAllocator &alloc)
: ObSysFunRawExpr(alloc),
udf_id_(common::OB_INVALID_ID),
pkg_id_(common::OB_INVALID_ID),
type_id_(common::OB_INVALID_ID),
subprogram_path_(),
udf_schema_version_(common::OB_INVALID_VERSION),
pkg_schema_version_(common::OB_INVALID_VERSION),
pls_type_(pl::PL_INTEGER_INVALID),
params_type_(),
database_name_(),
package_name_(),
is_deterministic_(false),
is_parallel_enable_(false),
is_udt_udf_(false),
is_pkg_body_udf_(false),
is_return_sys_cursor_(false),
is_aggregate_udf_(false),
is_aggr_udf_distinct_(false),
nocopy_params_(),
loc_(0),
is_udt_cons_(false),
params_name_(),
params_desc_v2_() {
set_expr_class(ObIRawExpr::EXPR_UDF);
}
ObUDFRawExpr()
: ObSysFunRawExpr(),
udf_id_(common::OB_INVALID_ID),
pkg_id_(common::OB_INVALID_ID),
type_id_(common::OB_INVALID_ID),
subprogram_path_(),
udf_schema_version_(common::OB_INVALID_VERSION),
pkg_schema_version_(common::OB_INVALID_VERSION),
pls_type_(pl::PL_INTEGER_INVALID),
params_type_(),
database_name_(),
package_name_(),
is_deterministic_(false),
is_parallel_enable_(false),
is_udt_udf_(false),
is_pkg_body_udf_(false),
is_return_sys_cursor_(false),
is_aggregate_udf_(false),
is_aggr_udf_distinct_(false),
nocopy_params_(),
loc_(0),
is_udt_cons_(false),
params_name_(),
params_desc_v2_() {
set_expr_class(ObIRawExpr::EXPR_UDF);
}
virtual ~ObUDFRawExpr() {}
inline void set_udf_id(uint64_t udf_id){ udf_id_ = udf_id; }
inline int set_subprogram_path(const ObIArray<int64_t> &path)
{
return subprogram_path_.assign(path);
}
inline void set_udf_schema_version(int64_t schema_version)
{
udf_schema_version_ = schema_version;
}
inline void set_pkg_schema_version(int64_t schema_version)
{
pkg_schema_version_ = schema_version;
}
inline void set_pls_type(const pl::ObPLIntegerType pls_type)
{
pls_type_ = pls_type;
}
inline int set_params_type(common::ObIArray<ObExprResType> &params_type)
{
return params_type_.assign(params_type);
}
inline void set_database_name(const common::ObString &database_name)
{
database_name_ = database_name;
}
inline void set_package_name(const common::ObString &package_name)
{
package_name_ = package_name;
}
inline int add_param_desc(ObUDFParamDesc desc)
{
return params_desc_v2_.push_back(desc);
}
inline bool is_param_out(int64_t i) const
{
return params_desc_v2_.at(i).is_out();
}
inline int64_t get_param_position(int64_t i) const
{
return params_desc_v2_.at(i).get_index();
}
inline bool has_param_out() const
{
for (int64_t i = 0; i < params_desc_v2_.count(); ++i) {
if (is_param_out(i)) {
return true;
}
}
return false;
}
inline int add_param_name(common::ObString &name)
{
return params_name_.push_back(name);
}
inline common::ObIArray<common::ObString> &get_params_name()
{
return params_name_;
}
inline const common::ObIArray<common::ObString> &get_params_name() const
{
return params_name_;
}
inline void set_pkg_id(uint64_t pkg_id){ pkg_id_ = pkg_id; }
inline uint64_t get_pkg_id() const { return pkg_id_; }
inline uint64_t get_udf_id() const { return udf_id_; }
inline const ObIArray<int64_t> &get_subprogram_path() const { return subprogram_path_; }
inline pl::ObPLIntegerType get_pls_type() const { return pls_type_; }
inline common::ObIArray<ObExprResType> &get_params_type() { return params_type_; }
inline const common::ObIArray<ObExprResType> &get_params_type() const { return params_type_; }
inline common::ObString get_database_name() const { return database_name_; }
inline common::ObString get_package_name() const { return package_name_; }
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual ObExprOperator *get_op() override;
int check_param() { return common::OB_SUCCESS; }
virtual uint64_t hash_internal(uint64_t seed) const override
{
uint64_t hash_ret = common::do_hash(udf_id_, seed);
return hash_ret;
}
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const override;
inline void set_parallel_enable(bool is_parallel_enable) { is_parallel_enable_ = is_parallel_enable; }
inline bool is_parallel_enable() const { return is_parallel_enable_; }
inline void set_is_udt_udf(bool is_udt_udf) { is_udt_udf_ = is_udt_udf; }
inline bool get_is_udt_udf() const { return is_udt_udf_; }
inline void set_is_return_sys_cursor(bool is_ret_cursor) { is_return_sys_cursor_ = is_ret_cursor; }
inline bool get_is_return_sys_cursor() const { return is_return_sys_cursor_; }
inline void set_type_id(uint64_t type_id) { type_id_ = type_id; }
inline uint64_t get_type_id() const { return type_id_; }
inline void set_is_aggregate_udf(bool is_aggregate_udf) { is_aggregate_udf_ = is_aggregate_udf; }
inline bool get_is_aggregate_udf() const { return is_aggregate_udf_; }
inline void set_is_aggr_udf_distinct(bool is_aggr_udf_distinct) {
is_aggr_udf_distinct_ = is_aggr_udf_distinct; }
inline bool get_is_aggr_udf_distinct() const { return is_aggr_udf_distinct_; }
inline void set_loc(uint64_t loc) { loc_ = loc; }
inline uint64_t get_loc() const { return loc_; }
inline void set_is_udt_cons(bool flag) { is_udt_cons_ = flag; }
inline bool get_is_udt_cons() const { return is_udt_cons_; }
inline ObIArray<ObUDFParamDesc>& get_params_desc() { return params_desc_v2_; }
inline const ObIArray<ObUDFParamDesc>& get_params_desc() const { return params_desc_v2_; }
ObIArray<int64_t>& get_nocopy_params() { return nocopy_params_; }
const ObIArray<int64_t>& get_nocopy_params() const { return nocopy_params_; }
inline bool need_add_dependency()
{
return udf_schema_version_ != common::OB_INVALID_VERSION
|| pkg_schema_version_ != common::OB_INVALID_VERSION;
}
int get_schema_object_version(share::schema::ObSchemaObjVersion &obj_version);
inline void set_pkg_body_udf(bool v) { is_pkg_body_udf_ = v; }
inline bool is_pkg_body_udf() const { return is_pkg_body_udf_; }
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_DATABASE, get_database_name(),
K_(package_name),
N_FUNC, get_func_name(),
K_(udf_id),
K_(pkg_id),
K_(type_id),
K_(subprogram_path),
K_(is_deterministic),
K_(is_udt_udf),
K_(is_return_sys_cursor),
K_(loc),
K_(udf_schema_version),
K_(pkg_schema_version),
K_(is_pkg_body_udf),
K_(is_return_sys_cursor),
K_(is_aggregate_udf),
K_(is_parallel_enable),
K_(is_aggr_udf_distinct),
K_(loc),
K_(is_udt_cons),
K_(params_desc_v2),
N_CHILDREN, exprs_);
private:
uint64_t udf_id_;
uint64_t pkg_id_;
uint64_t type_id_;
common::ObSEArray<int64_t, 8, common::ModulePageAllocator, true> subprogram_path_;
int64_t udf_schema_version_;
int64_t pkg_schema_version_;
pl::ObPLIntegerType pls_type_; // 当返回PLS类型时, 该字段记录返回的PLS类型
common::ObSEArray<ObExprResType, 5, common::ModulePageAllocator, true> params_type_;
common::ObString database_name_;
common::ObString package_name_;
bool is_deterministic_;
bool is_parallel_enable_;
bool is_udt_udf_;
bool is_pkg_body_udf_;
bool is_return_sys_cursor_;
bool is_aggregate_udf_;
bool is_aggr_udf_distinct_;
common::ObSEArray<int64_t, 8, common::ModulePageAllocator, true> nocopy_params_;
uint64_t loc_; // line 和 column 组合,主要是为call_stack准备
bool is_udt_cons_;
common::ObSEArray<common::ObString, 5, common::ModulePageAllocator, true> params_name_;
common::ObSEArray<ObUDFParamDesc, 5, common::ModulePageAllocator, true> params_desc_v2_;
private:
DISALLOW_COPY_AND_ASSIGN(ObUDFRawExpr);
};
class ObPLIntegerCheckerRawExpr : public ObOpRawExpr
{
public:
ObPLIntegerCheckerRawExpr(common::ObIAllocator &alloc)
: ObOpRawExpr(alloc),
pl_integer_type_(pl::PL_INTEGER_INVALID),
pl_integer_range_() {}
ObPLIntegerCheckerRawExpr()
: ObOpRawExpr(),
pl_integer_type_(pl::PL_INTEGER_INVALID),
pl_integer_range_() {}
virtual ~ObPLIntegerCheckerRawExpr() {}
void set_pl_integer_type(pl::ObPLIntegerType type) { pl_integer_type_ = type; }
pl::ObPLIntegerType get_pl_integer_type() const { return pl_integer_type_; }
void set_range(int32_t lower, int32_t upper)
{
pl_integer_range_.set_range(lower, upper);
}
inline int32_t get_lower() const { return pl_integer_range_.get_lower(); }
inline int32_t get_upper() const { return pl_integer_range_.get_upper(); }
int assign(const ObRawExpr &other) override;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
K_(pl_integer_type),
K_(pl_integer_range_.range),
N_CHILDREN, exprs_);
private:
DISALLOW_COPY_AND_ASSIGN(ObPLIntegerCheckerRawExpr);
private:
pl::ObPLIntegerType pl_integer_type_;
pl::ObPLIntegerRange pl_integer_range_;
};
class ObPLGetCursorAttrRawExpr : public ObSysFunRawExpr
{
public:
ObPLGetCursorAttrRawExpr(common::ObIAllocator &alloc)
: ObSysFunRawExpr(alloc), cursor_info_() {}
ObPLGetCursorAttrRawExpr()
: ObSysFunRawExpr(), cursor_info_() {}
virtual ~ObPLGetCursorAttrRawExpr() {}
virtual ObExprOperator *get_op() override;
void set_pl_get_cursor_attr_info(pl::ObPLGetCursorAttrInfo info) { cursor_info_ = info; }
const pl::ObPLGetCursorAttrInfo& get_pl_get_cursor_attr_info() const { return cursor_info_; }
int assign(const ObRawExpr &other) override;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
K_(cursor_info),
N_CHILDREN, exprs_);
private:
DISALLOW_COPY_AND_ASSIGN(ObPLGetCursorAttrRawExpr);
private:
pl::ObPLGetCursorAttrInfo cursor_info_;
};
class ObPLSQLCodeSQLErrmRawExpr : public ObSysFunRawExpr
{
public:
ObPLSQLCodeSQLErrmRawExpr(common::ObIAllocator &alloc)
: ObSysFunRawExpr(alloc), is_sqlcode_(true) {}
ObPLSQLCodeSQLErrmRawExpr()
: ObSysFunRawExpr(), is_sqlcode_(true) {}
virtual ~ObPLSQLCodeSQLErrmRawExpr() {}
int assign(const ObRawExpr &other) override;
virtual ObExprOperator *get_op() override;
void set_is_sqlcode(bool is_sqlcode) { is_sqlcode_ = is_sqlcode; }
bool get_is_sqlcode() const { return is_sqlcode_; }
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
K_(is_sqlcode),
N_CHILDREN, exprs_);
private:
DISALLOW_COPY_AND_ASSIGN(ObPLSQLCodeSQLErrmRawExpr);
private:
bool is_sqlcode_;
};
class ObPLSQLVariableRawExpr : public ObSysFunRawExpr
{
public:
ObPLSQLVariableRawExpr(common::ObIAllocator &alloc)
: ObSysFunRawExpr(alloc), plsql_line_(OB_INVALID_INDEX), plsql_variable_() {}
ObPLSQLVariableRawExpr()
: ObSysFunRawExpr(), plsql_line_(OB_INVALID_INDEX) {}
virtual ~ObPLSQLVariableRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual ObExprOperator *get_op() override;
void set_plsql_line(int64_t v) { plsql_line_ = v; }
int64_t get_plsql_line() { return plsql_line_; }
void set_plsql_variable(ObString &v) { plsql_variable_ = v; }
ObString& get_plsql_variable() { return plsql_variable_; }
private:
DISALLOW_COPY_AND_ASSIGN(ObPLSQLVariableRawExpr);
private:
int64_t plsql_line_; // for $$PLSQL_LINE
ObString plsql_variable_; // for $$PLSQL_UNIT, $$PLSQL_CCFLAGS etc...
};
class ObCallParamRawExpr : public ObOpRawExpr
{
public:
ObCallParamRawExpr(common::ObIAllocator &alloc)
: ObOpRawExpr(alloc), expr_(NULL), name_() {}
ObCallParamRawExpr()
: ObOpRawExpr(), expr_(NULL), name_() {}
virtual ~ObCallParamRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
ObRawExpr* get_expr() { return expr_; }
ObString& get_name() { return name_; }
inline void set_expr(ObRawExpr *expr) { expr_ = expr; }
inline void set_name(ObString &name) { name_ = name; }
private:
DISALLOW_COPY_AND_ASSIGN(ObCallParamRawExpr);
private:
ObRawExpr *expr_;
ObString name_;
};
class ObPLAssocIndexRawExpr : public ObOpRawExpr
{
public:
ObPLAssocIndexRawExpr(common::ObIAllocator &alloc)
: ObOpRawExpr(alloc), for_write_(false),
out_of_range_set_err_(true),
parent_type_(pl::parent_expr_type::EXPR_UNKNOWN) {}
ObPLAssocIndexRawExpr()
: ObOpRawExpr(), for_write_(false) {}
virtual ~ObPLAssocIndexRawExpr() {}
int assign(const ObRawExpr &other) override;
inline void set_write(bool for_write) { for_write_ = for_write; }
inline bool get_write() const { return for_write_; }
inline bool get_out_of_range_set_err() const { return out_of_range_set_err_; }
inline void set_out_of_range_set_err(bool is_set_err) { out_of_range_set_err_ = is_set_err; }
inline void set_parent_type(pl::parent_expr_type type) { parent_type_ = type; }
inline pl::parent_expr_type get_parent_type() const { return parent_type_; }
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
K_(for_write),
N_CHILDREN, exprs_,
K_(out_of_range_set_err),
K_(parent_type));
private:
DISALLOW_COPY_AND_ASSIGN(ObPLAssocIndexRawExpr);
private:
bool for_write_;
// set ret to out of range or not.
bool out_of_range_set_err_;
// hack, 0: parent expr is prior, 1 parent expr is
pl::parent_expr_type parent_type_;
};
class ObObjAccessRawExpr : public ObOpRawExpr
{
public:
ObObjAccessRawExpr(common::ObIAllocator &alloc)
: ObOpRawExpr(alloc),
get_attr_func_(0),
func_name_(),
access_indexs_(),
var_indexs_(),
for_write_(false),
property_type_(pl::ObCollectionType::INVALID_PROPERTY),
orig_access_indexs_() {}
ObObjAccessRawExpr()
: ObOpRawExpr(),
get_attr_func_(0),
func_name_(),
access_indexs_(),
var_indexs_(),
for_write_(false),
property_type_(pl::ObCollectionType::INVALID_PROPERTY),
orig_access_indexs_() {}
virtual ~ObObjAccessRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
int add_access_indexs(const common::ObIArray<pl::ObObjAccessIdx> &access_idxs);
common::ObIArray<pl::ObObjAccessIdx> &get_access_idxs() { return access_indexs_; }
const common::ObIArray<pl::ObObjAccessIdx> &get_access_idxs() const { return access_indexs_; }
const common::ObIArray<int64_t> &get_var_indexs() const { return var_indexs_; }
int get_final_type(pl::ObPLDataType &type) const;
void set_get_attr_func_addr(uint64_t get_attr_func) { get_attr_func_ = get_attr_func; }
uint64_t get_get_attr_func_addr() const { return get_attr_func_; }
void set_func_name(const common::ObString &func_name) { func_name_ = func_name; }
const common::ObString &get_func_name() const { return func_name_; }
bool for_write() const { return for_write_; }
void set_write(bool for_write) { for_write_ = for_write; }
bool is_property() const { return pl::ObCollectionType::INVALID_PROPERTY != property_type_; }
pl::ObCollectionType::PropertyType get_property() const { return property_type_; }
void set_property(pl::ObCollectionType::PropertyType property_type) { property_type_ = property_type; }
common::ObIArray<pl::ObObjAccessIdx> &get_orig_access_idxs() { return orig_access_indexs_; }
const common::ObIArray<pl::ObObjAccessIdx> &get_orig_access_idxs() const { return orig_access_indexs_; }
private:
DISALLOW_COPY_AND_ASSIGN(ObObjAccessRawExpr);
uint64_t get_attr_func_; //获取用户自定义类型数据的函数指针
common::ObString func_name_;
common::ObSEArray<pl::ObObjAccessIdx, 4, common::ModulePageAllocator, true> access_indexs_;
common::ObSEArray<int64_t, 4, common::ModulePageAllocator, true> var_indexs_;
bool for_write_;
pl::ObCollectionType::PropertyType property_type_;
common::ObSEArray<pl::ObObjAccessIdx, 4, common::ModulePageAllocator, true> orig_access_indexs_;
};
enum ObMultiSetType {
MULTISET_TYPE_INVALID = -1,
MULTISET_TYPE_UNION,
MULTISET_TYPE_INTERSECT,
MULTISET_TYPE_EXCEPT,
MULTISET_TYPE_SUBMULTISET,
MULTISET_TYPE_MEMBER_OF,
MULTISET_TYPE_IS_SET,
MULTISET_TYPE_EMPTY,
};
enum ObMultiSetModifier {
MULTISET_MODIFIER_INVALID = -1,
MULTISET_MODIFIER_ALL,
MULTISET_MODIFIER_DISTINCT,
MULTISET_MODIFIER_NOT,
};
class ObMultiSetRawExpr :
public ObOpRawExpr
{
public:
ObMultiSetRawExpr(common::ObIAllocator &alloc)
: ObOpRawExpr(alloc),
ms_modifier_(ObMultiSetModifier::MULTISET_MODIFIER_INVALID),
ms_type_(ObMultiSetType::MULTISET_TYPE_INVALID) {}
ObMultiSetRawExpr()
: ObOpRawExpr(),
ms_modifier_(ObMultiSetModifier::MULTISET_MODIFIER_INVALID),
ms_type_(ObMultiSetType::MULTISET_TYPE_INVALID) {}
virtual ~ObMultiSetRawExpr(){}
int assign(const ObRawExpr &other) override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
inline ObMultiSetModifier get_multiset_modifier() const { return ms_modifier_; }
inline ObMultiSetType get_multiset_type() const { return ms_type_; }
void set_multiset_modifier(ObMultiSetModifier modifier) { ms_modifier_ = modifier; }
void set_multiset_type(ObMultiSetType type) { ms_type_ = type; }
private:
DISALLOW_COPY_AND_ASSIGN(ObMultiSetRawExpr);
ObMultiSetModifier ms_modifier_;
ObMultiSetType ms_type_;
};
class ObCollPredRawExpr : public ObMultiSetRawExpr
{
public:
ObCollPredRawExpr(common::ObIAllocator &alloc) : ObMultiSetRawExpr(alloc) {}
virtual ~ObCollPredRawExpr() {}
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
private:
DISALLOW_COPY_AND_ASSIGN(ObCollPredRawExpr);
};
////////////////////////////////////////////////////////////////
// eg :
// partition by class order by score rows between 5 preceding and 5 following : 学生成绩排名前5后5
// partition by class order by score range between 5 preceding and 5 following : 学生成绩上下相差5分
// new
enum WindowType
{
// 物理偏移, eg: rows between 1 preceding and 1 following, 按上下偏移1行得到窗口
WINDOW_ROWS,
// 逻辑偏移, eg: range between 1 preceding and 1 following, 按value - 1, value + 1得到窗口
WINDOW_RANGE,
// 标识未定义状态
WINDOW_MAX,
};
enum BoundType
{
// 按partition界作为窗口界
BOUND_UNBOUNDED,
// 对于rows表示按当前行作为窗口界, 对于range表示按当前行的value作为窗口界
BOUND_CURRENT_ROW,
// 偏移值
BOUND_INTERVAL,
};
enum BoundExprIdx {
BOUND_EXPR_ADD = 0,
BOUND_EXPR_SUB,
BOUND_EXPR_MAX
};
struct Bound
{
OB_UNIS_VERSION_V(1);
public:
Bound()
: type_(BOUND_UNBOUNDED),
is_preceding_(false),
is_nmb_literal_(false),
interval_expr_(NULL),
date_unit_expr_(NULL)
{
MEMSET(exprs_, 0, sizeof(ObRawExpr*) * BOUND_EXPR_MAX);
}
int assign(const Bound &other);
int inner_deep_copy(ObIRawExprCopier &copier);
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
bool same_as(const Bound &other, ObExprEqualCheckContext *check_context) const;
BoundType type_;
bool is_preceding_;
bool is_nmb_literal_;
ObRawExpr *interval_expr_;
ObRawExpr *date_unit_expr_;
ObRawExpr *exprs_[BOUND_EXPR_MAX];
TO_STRING_KV(K_(type), K_(is_preceding), K_(is_nmb_literal), KP_(interval_expr),
K_(date_unit_expr));
};
////////////////////////////////////////////////////////////////
struct ObFrame
{
public:
ObFrame()
: win_type_(WINDOW_MAX),
is_between_(false)
{}
inline void set_window_type(WindowType win_type)
{ win_type_ = win_type; }
inline void set_is_between(bool is_between)
{ is_between_ = is_between; }
inline void set_upper(const Bound &upper)
{ upper_ = upper; }
inline void set_lower(const Bound &lower)
{ lower_ = lower; }
inline WindowType get_window_type() const { return win_type_; }
inline bool is_between() const { return is_between_; }
inline Bound &get_upper() { return upper_; }
inline Bound &get_lower() { return lower_; }
int assign(const ObFrame &other);
WindowType win_type_;
bool is_between_;
Bound upper_;
Bound lower_;
};
struct ObWindow : public ObFrame
{
public:
ObWindow()
: has_frame_orig_(false)
{
partition_exprs_.set_label(common::ObModIds::OB_SQL_WINDOW_FUNC);
order_items_.set_label(common::ObModIds::OB_SQL_WINDOW_FUNC);
}
inline int set_partition_exprs(const common::ObIArray<ObRawExpr *> &exprs)
{ return partition_exprs_.assign(exprs); }
inline int set_order_items(const common::ObIArray<OrderItem> &items)
{ return order_items_.assign(items); }
inline void set_win_name(common::ObString &win_name)
{ win_name_ = win_name; }
inline void set_has_frame_orig(int64_t has_frame_orig)
{ has_frame_orig_ = has_frame_orig; }
inline common::ObString &get_win_name() { return win_name_; }
inline bool has_frame_orig() { return has_frame_orig_; }
inline bool has_order_items() { return order_items_.count() > 0; }
inline const common::ObIArray<ObRawExpr *> &get_partition_exprs() const { return partition_exprs_; }
inline common::ObIArray<ObRawExpr *> &get_partition_exprs() { return partition_exprs_; }
inline const common::ObIArray<OrderItem> &get_order_items() const { return order_items_; }
inline common::ObIArray<OrderItem> &get_order_items() { return order_items_; }
int assign(const ObWindow &other);
common::ObArray<ObRawExpr *, common::ModulePageAllocator, true> partition_exprs_;
common::ObArray<OrderItem, common::ModulePageAllocator, true> order_items_;
// used in resolver
common::ObString win_name_;
bool has_frame_orig_;
};
class ObWinFunRawExpr : public ObRawExpr, public ObWindow
{
public:
ObWinFunRawExpr()
: ObRawExpr(),
ObWindow(),
func_type_(T_MAX),
is_ignore_null_(false),
is_from_first_(false),
agg_expr_(NULL),
pl_agg_udf_expr_(NULL)
{
set_expr_class(ObIRawExpr::EXPR_WINDOW);
}
ObWinFunRawExpr(common::ObIAllocator &alloc)
: ObRawExpr(alloc),
ObWindow(),
func_type_(T_MAX),
is_ignore_null_(false),
is_from_first_(false),
agg_expr_(NULL),
pl_agg_udf_expr_(NULL)
{
set_expr_class(ObIRawExpr::EXPR_WINDOW);
}
virtual ~ObWinFunRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
int replace_param_expr(int64_t partition_expr_index, ObRawExpr *expr);
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
inline void set_func_type(ObItemType func_type)
{ func_type_ = func_type; }
inline void set_is_ignore_null(bool is_ignore_null)
{ is_ignore_null_ = is_ignore_null; }
inline void set_is_from_first(bool is_from_first)
{ is_from_first_ = is_from_first; }
inline int set_func_params(const common::ObIArray<ObRawExpr *> &params)
{ return func_params_.assign(params); }
inline void set_agg_expr(ObAggFunRawExpr *agg_expr)
{ agg_expr_ = agg_expr; }
inline ObItemType get_func_type() const { return func_type_; }
inline bool is_ignore_null() { return is_ignore_null_; }
inline bool is_from_first() { return is_from_first_; }
inline const common::ObIArray<ObRawExpr *> &get_func_params() const { return func_params_; }
inline common::ObIArray<ObRawExpr *> &get_func_params() { return func_params_; }
inline ObAggFunRawExpr *get_agg_expr() { return agg_expr_; }
inline ObAggFunRawExpr *get_agg_expr() const { return agg_expr_; }
inline void set_pl_agg_udf_expr(ObRawExpr *udf_expr) { pl_agg_udf_expr_ = udf_expr; }
inline ObRawExpr *get_pl_agg_udf_expr() const { return pl_agg_udf_expr_; }
virtual void clear_child() override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int64_t get_param_count() const
{
int64_t cnt = (agg_expr_ != NULL ? agg_expr_->get_param_count() : 0)
+ func_params_.count()
+ partition_exprs_.count()
+ order_items_.count()
+ (upper_.interval_expr_ != NULL ? 1 : 0)
+ (lower_.interval_expr_ != NULL ? 1 : 0)
+ (pl_agg_udf_expr_ != NULL ? 1 : 0);
for (int64_t i = 0; i < 2; ++i) {
const Bound *bound = 0 == i ? &upper_ : &lower_;
for (int64_t j = 0; j < BOUND_EXPR_MAX; ++j) {
if (NULL != bound->exprs_[j]) {
cnt++;
}
}
}
return cnt;
}
virtual const ObRawExpr *get_param_expr(int64_t index) const;
virtual ObRawExpr *&get_param_expr(int64_t index);
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
int64_t get_partition_param_index(int64_t index);
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
VIRTUAL_TO_STRING_KV_CHECK_STACK_OVERFLOW(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
K_(func_type),
K_(func_params),
K_(partition_exprs),
K_(order_items),
K_(win_type),
K_(is_between),
K_(upper),
K_(lower),
KPC_(agg_expr),
KPC_(pl_agg_udf_expr));
public:
common::ObString sort_str_;
private:
DISALLOW_COPY_AND_ASSIGN(ObWinFunRawExpr);
ObItemType func_type_;
bool is_ignore_null_;
bool is_from_first_;
common::ObArray<ObRawExpr *, common::ModulePageAllocator, true> func_params_;
ObAggFunRawExpr *agg_expr_;
ObRawExpr *pl_agg_udf_expr_;//for pl agg udf expr
};
////////////////////////////////////////////////////////////////
class ObPseudoColumnRawExpr : public ObTerminalRawExpr
{
public:
ObPseudoColumnRawExpr() :
ObTerminalRawExpr(),
table_id_(common::OB_INVALID_ID)
{
set_expr_class(ObIRawExpr::EXPR_PSEUDO_COLUMN);
}
ObPseudoColumnRawExpr(common::ObIAllocator &alloc) :
ObTerminalRawExpr(alloc),
table_id_(common::OB_INVALID_ID)
{
set_expr_class(ObIRawExpr::EXPR_PSEUDO_COLUMN);
}
virtual ~ObPseudoColumnRawExpr() {}
int assign(const ObRawExpr &other) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs);
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
bool is_hierarchical_query_type() const { return type_ == T_LEVEL || type_ == T_CONNECT_BY_ISCYCLE || type_ == T_CONNECT_BY_ISLEAF; }
bool is_cte_query_type() const { return T_CTE_SEARCH_COLUMN == type_ || T_CTE_CYCLE_COLUMN == type_; }
void set_cte_cycle_value(ObRawExpr *v, ObRawExpr *d_v) {cte_cycle_value_ = v; cte_cycle_default_value_ = d_v; };
void get_cte_cycle_value(ObRawExpr *&v, ObRawExpr *&d_v) {v = cte_cycle_value_; d_v = cte_cycle_default_value_; };
void set_table_id(int64_t table_id) { table_id_ = table_id; }
int64_t get_table_id() const { return table_id_; }
void set_table_name(const common::ObString &table_name) { table_name_ = table_name; }
const common::ObString & get_table_name() const { return table_name_; }
VIRTUAL_TO_STRING_KV(N_ITEM_TYPE, type_,
N_RESULT_TYPE, result_type_,
N_EXPR_INFO, info_,
N_REL_ID, rel_ids_,
N_TABLE_ID, table_id_,
N_TABLE_NAME, table_name_);
private:
ObRawExpr *cte_cycle_value_;
ObRawExpr *cte_cycle_default_value_;
int64_t table_id_;
common::ObString table_name_;
DISALLOW_COPY_AND_ASSIGN(ObPseudoColumnRawExpr);
};
// Operator pseudo column to carry operator data to above operators.
// e.g.:
// T_PDML_PARTITION_ID: carry partition id of row to above PDML operators.
// T_PSEUDO_GROUP_ID: carry the batch group id for DAS batch rescan.
// T_INNER_AGGR_CODE: carry aggregate code for 3-stage aggregation.
// T_PSEUDO_ROLLUP_ID: carry aggregate code for rollup distributor and collector.
class ObOpPseudoColumnRawExpr : public ObTerminalRawExpr
{
public:
ObOpPseudoColumnRawExpr();
ObOpPseudoColumnRawExpr(ObItemType expr_type = T_INVALID);
ObOpPseudoColumnRawExpr(common::ObIAllocator &alloc);
virtual ~ObOpPseudoColumnRawExpr();
int assign(const ObOpPseudoColumnRawExpr &other);
int inner_deep_copy(ObIRawExprCopier &copier) override;
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual int get_name_internal(char *buf,
const int64_t buf_len,
int64_t &pos,
ExplainType type) const override;
void set_name(const char *name) { name_ = name; }
const char *get_name() const { return name_; }
private:
const char *name_;
};
/// visitor interface
class ObRawExprVisitor
{
public:
ObRawExprVisitor() {}
virtual ~ObRawExprVisitor() {}
// OP types: constants, ? etc.
virtual int visit(ObConstRawExpr &expr) = 0;
// OP types: ObObjtypes
virtual int visit(ObVarRawExpr &expr) = 0;
// OP types: operator pseudo column expr
virtual int visit(ObOpPseudoColumnRawExpr &expr) = 0;
virtual int visit(ObPlQueryRefRawExpr &expr) = 0;
virtual int visit(ObExecParamRawExpr &expr) = 0;
// OP types: subquery, cell index
virtual int visit(ObQueryRefRawExpr &expr) = 0;
// OP types: identify, table.column
virtual int visit(ObColumnRefRawExpr &expr) = 0;
// unary OP types: exists, not, negative, positive
// binary OP types: +, -, *, /, >, <, =, <=>, IS, IN etc.
// triple OP types: like, not like, btw, not btw
// multi OP types: and, or, ROW
virtual int visit(ObOpRawExpr &expr) = 0;
// OP types: case, arg case
virtual int visit(ObCaseOpRawExpr &expr) = 0;
// OP types: aggregate functions e.g. max, min, avg, count, sum
virtual int visit(ObAggFunRawExpr &expr) = 0;
// OP types: system functions
virtual int visit(ObSysFunRawExpr &expr) = 0;
virtual int visit(ObSetOpRawExpr &expr) = 0;
virtual int visit(ObAliasRefRawExpr &expr) { UNUSED(expr); return common::OB_SUCCESS; }
virtual int visit(ObWinFunRawExpr &expr) { UNUSED(expr); return common::OB_SUCCESS; }
virtual int visit(ObPseudoColumnRawExpr &expr) { UNUSED(expr); return common::OB_SUCCESS; }
virtual bool skip_child(ObRawExpr &expr) { UNUSED(expr); return false; }
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObRawExprVisitor);
};
class ObRawExprFactory
{
public:
explicit ObRawExprFactory(common::ObIAllocator &alloc)
: allocator_(alloc),
expr_store_(alloc),
is_called_sql_(true),
proxy_(nullptr)
{
}
ObRawExprFactory(ObRawExprFactory &expr_factory) : allocator_(expr_factory.allocator_),
expr_store_(allocator_),
proxy_(&expr_factory)
{
}
~ObRawExprFactory() {
// 对于非工作线程, 需要调用其析构函数,
// 避免因未调用析构函数而导致raw_expr中
// ObSEArray的内存泄漏
if (!THIS_WORKER.has_req_flag() && OB_ISNULL(proxy_)) {
destory();
}
}
//~ObRawExprFactory() { }
int create_raw_expr(ObRawExpr::ExprClass expr_class,
ObItemType expr_type,
ObRawExpr *&new_expr);
template <typename ExprType>
inline int create_raw_expr_inner(ObItemType expr_type, ExprType *&raw_expr)
{
int ret = common::OB_SUCCESS;
void *ptr = allocator_.alloc(sizeof(ExprType));
raw_expr = NULL;
bool is_overflow = false;
if (OB_UNLIKELY(NULL == ptr)) {
ret = common::OB_ALLOCATE_MEMORY_FAILED;
SQL_RESV_LOG(ERROR, "no more memory to create raw expr");
} else if (OB_NOT_NULL(proxy_)) {
if (OB_FAIL(check_stack_overflow(is_overflow))) {
SQL_RESV_LOG(WARN, "failed to check stack overflow", K(ret));
} else if (is_overflow) {
ret = OB_SIZE_OVERFLOW;
SQL_RESV_LOG(WARN, "too deep recusive", K(ret));
} else if (OB_FAIL(proxy_->create_raw_expr(expr_type, raw_expr))) {
SQL_RESV_LOG(WARN, "failed to create raw expr by pl factory", K(ret));
} else {
raw_expr->set_is_called_in_sql(is_called_sql_);
}
} else {
raw_expr = new(ptr) ExprType(allocator_);
raw_expr->set_allocator(allocator_);
raw_expr->set_expr_factory(*this);
raw_expr->set_expr_type(expr_type);
if (OB_FAIL(expr_store_.store_obj(raw_expr))) {
SQL_RESV_LOG(WARN, "store raw expr failed", K(ret));
raw_expr->~ExprType();
raw_expr = NULL;
} else {
SQL_RESV_LOG(DEBUG, "create_raw_expr", K(expr_type), K(raw_expr),
"expr_type", get_type_name(expr_type), K(lbt()));
}
}
return ret;
}
template <typename ExprType>
int create_raw_expr(ObItemType expr_type, ExprType *&raw_expr)
{
return create_raw_expr_inner(expr_type, raw_expr);
}
inline void destory()
{
if (OB_NOT_NULL(proxy_)) {
proxy_ = nullptr;
expr_store_.destroy();
} else {
DLIST_FOREACH_NORET(node, expr_store_.get_obj_list()) {
if (node != NULL && node->get_obj() != NULL) {
node->get_obj()->~ObRawExpr();
}
}
expr_store_.destroy();
}
}
inline common::ObIAllocator &get_allocator() { return allocator_; }
common::ObObjStore<ObRawExpr*, common::ObIAllocator&, true> &get_expr_store() { return expr_store_; }
void set_is_called_sql(const bool is_called_sql) { is_called_sql_ = is_called_sql; }
TO_STRING_KV("", "");
private:
common::ObIAllocator &allocator_;
common::ObObjStore<ObRawExpr*, common::ObIAllocator&, true> expr_store_;
bool is_called_sql_;
//if not null, raw_expr is create by pl resolver
ObRawExprFactory *proxy_;
private:
DISALLOW_COPY_AND_ASSIGN(ObRawExprFactory);
};
template <>
int ObRawExprFactory::create_raw_expr<ObSysFunRawExpr>(ObItemType expr_type, ObSysFunRawExpr *&raw_expr);
template <>
int ObRawExprFactory::create_raw_expr<ObOpRawExpr>(ObItemType expr_type, ObOpRawExpr *&raw_expr);
class ObRawExprPointer {
public:
ObRawExprPointer();
virtual ~ObRawExprPointer();
int get(ObRawExpr *&expr) const;
int set(ObRawExpr *expr);
int add_ref(ObRawExpr **expr);
int64_t ref_count() const { return expr_group_.count(); }
int assign(const ObRawExprPointer &other);
TO_STRING_KV("", "");
private:
common::ObSEArray<ObRawExpr **, 1> expr_group_;
};
class ObPlQueryRefRawExpr : public ObRawExpr
{
public:
ObPlQueryRefRawExpr()
: ObRawExpr(),
ps_sql_(ObString()),
type_(stmt::T_NONE),
route_sql_(ObString()),
subquery_result_type_(),
is_ignore_fail_(false),
exprs_()
{
set_expr_class(ObIRawExpr::EXPR_PL_QUERY_REF);
}
ObPlQueryRefRawExpr(common::ObIAllocator &alloc)
: ObRawExpr(alloc),
ps_sql_(ObString()),
type_(stmt::T_NONE),
route_sql_(ObString()),
subquery_result_type_(),
is_ignore_fail_(false),
exprs_()
{
set_expr_class(ObIRawExpr::EXPR_PL_QUERY_REF);
}
virtual ~ObPlQueryRefRawExpr() {}
int assign(const ObRawExpr &other) override;
int inner_deep_copy(ObIRawExprCopier &copier) override;
int add_param_expr(ObRawExpr *expr);
int64_t get_param_count() const;
const ObRawExpr *get_param_expr(int64_t index) const;
ObRawExpr *&get_param_expr(int64_t index);
inline void set_ps_sql(const common::ObString &sql) { ps_sql_ = sql; }
inline void set_stmt_type(stmt::StmtType type) { type_ = type; }
inline void set_route_sql(const common::ObString &sql) { route_sql_ = sql; }
inline void set_subquery_result_type(const sql::ObExprResType &type)
{
subquery_result_type_ = type;
}
inline const common::ObString &get_ps_sql() const { return ps_sql_; }
inline stmt::StmtType get_stmt_type() const { return type_; }
inline const common::ObString &get_route_sql() const { return route_sql_; }
inline const sql::ObExprResType &get_subquery_result_type() const
{
return subquery_result_type_;
}
inline void set_ignore_fail() { is_ignore_fail_ = true; }
inline bool is_ignore_fail() const { return is_ignore_fail_; }
virtual int replace_expr(const common::ObIArray<ObRawExpr *> &other_exprs,
const common::ObIArray<ObRawExpr *> &new_exprs) override;
virtual void clear_child() override;
virtual bool inner_same_as(const ObRawExpr &expr,
ObExprEqualCheckContext *check_context = NULL) const override;
virtual int do_visit(ObRawExprVisitor &visitor) override;
virtual uint64_t hash_internal(uint64_t seed) const;
int get_name_internal(char *buf, const int64_t buf_len, int64_t &pos, ExplainType type) const;
private:
DISALLOW_COPY_AND_ASSIGN(ObPlQueryRefRawExpr);
common::ObString ps_sql_; //prepare后的参数化sql
stmt::StmtType type_; //prepare的语句类型
common::ObString route_sql_;
sql::ObExprResType subquery_result_type_;
bool is_ignore_fail_;
common::ObSEArray<ObRawExpr *, COMMON_MULTI_NUM, common::ModulePageAllocator, true> exprs_;
};
inline const ObRawExpr *ObPlQueryRefRawExpr::get_param_expr(int64_t index) const
{
const ObRawExpr *expr = NULL;
if (index >= 0 && index < exprs_.count()) {
expr = exprs_.at(index);
}
return expr;
}
//here must return in two branch, because ret value is a *&
inline ObRawExpr *&ObPlQueryRefRawExpr::get_param_expr(int64_t index)
{
if (index >= 0 && index < exprs_.count()) {
return exprs_.at(index);
} else {
return USELESS_POINTER;
}
}
inline int ObPlQueryRefRawExpr::add_param_expr(ObRawExpr *expr)
{
return exprs_.push_back(expr);
}
inline int64_t ObPlQueryRefRawExpr::get_param_count() const
{
return exprs_.count();
}
inline uint64_t ObPlQueryRefRawExpr::hash_internal(uint64_t seed) const
{
uint64_t hash_value = seed;
for (int64_t i = 0; i < exprs_.count(); ++i) {
if (NULL != exprs_.at(i)) {
hash_value = common::do_hash(*(exprs_.at(i)), hash_value);
}
}
return hash_value;
}
}// end sql
}// end oceanbase
#endif //OCEANBASE_SQL_RESOLVER_EXPR_RAW_EXPR_