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

#define USING_LOG_PREFIX SQL_RESV
#include "sql/resolver/dml/ob_select_resolver.h"
#include "lib/oblog/ob_log_module.h"
#include "lib/json/ob_json_print_utils.h"  // for SJ
#include "lib/time/ob_time_utility.h"
#include "lib/profile/ob_perf_event.h"
#include "lib/string/ob_sql_string.h"
#include "common/sql_mode/ob_sql_mode_utils.h"
#include "share/ob_time_utility2.h"
#include "share/inner_table/ob_inner_table_schema.h"
#include "sql/ob_sql_utils.h"
#include "sql/resolver/expr/ob_raw_expr_info_extractor.h"
#include "sql/resolver/expr/ob_raw_expr_canonicalizer_impl.h"
#include "sql/resolver/dml/ob_aggr_expr_push_up_analyzer.h"
#include "sql/resolver/dml/ob_group_by_checker.h"
#include "sql/resolver/expr/ob_raw_expr.h"
#include "sql/session/ob_sql_session_info.h"
#include "sql/resolver/ob_resolver_utils.h"
#include "sql/engine/expr/ob_expr_version.h"
#include "sql/optimizer/ob_optimizer_util.h"
#include "share/object/ob_obj_cast.h"
#include "sql/rewrite/ob_stmt_comparer.h"
#include "sql/rewrite/ob_transform_utils.h"
#include "common/ob_smart_call.h"
O
obdev 已提交
37
#include "sql/engine/expr/ob_expr_regexp_context.h"
W
wangzelin.wzl 已提交
38 39
namespace oceanbase
{
O
oceanbase-admin 已提交
40 41 42 43
using namespace common;
using namespace share;
using namespace share::schema;
using namespace jit::expr;
W
wangzelin.wzl 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
namespace sql
{

ObSelectResolver::ObSelectResolver(ObResolverParams &params)
  : ObDMLResolver(params),
    current_recursive_cte_table_item_(NULL),
    current_cte_involed_stmt_(NULL),
    has_calc_found_rows_(false),
    has_top_limit_(false),
    in_set_query_(false),
    is_sub_stmt_(false),
    standard_group_checker_(),
    transpose_item_(NULL),
    is_left_child_(false),
    having_has_self_column_(false),
    has_grouping_(false),
O
obdev 已提交
60 61
    has_group_by_clause_(false),
    has_nested_aggr_(false)
O
oceanbase-admin 已提交
62 63
{
  params_.is_from_create_view_ = params.is_from_create_view_;
O
obdev 已提交
64
  params_.is_from_create_table_ = params.is_from_create_table_;
W
wangt1xiuyi 已提交
65
  params_.is_specified_col_name_ = params.is_specified_col_name_;
W
wangzelin.wzl 已提交
66
  auto_name_id_ = 1;
O
oceanbase-admin 已提交
67 68 69
}

ObSelectResolver::~ObSelectResolver()
W
wangzelin.wzl 已提交
70 71
{
}
O
oceanbase-admin 已提交
72

W
wangzelin.wzl 已提交
73
ObSelectStmt *ObSelectResolver::get_select_stmt()
O
oceanbase-admin 已提交
74 75 76 77
{
  return static_cast<ObSelectStmt*>(stmt_);
}

W
wangzelin.wzl 已提交
78
int ObSelectResolver::resolve_set_query(const ParseNode &parse_tree)
O
oceanbase-admin 已提交
79 80
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
81 82 83 84 85 86 87 88 89
  bool recursive_union = false;
  bool need_swap_child = false;

  if (cte_ctx_.is_with_resolver() && OB_FAIL(check_query_is_recursive_union(parse_tree, recursive_union, need_swap_child))) {
    LOG_WARN("failed to do resolve set query", K(ret));
  } else if (recursive_union) {
    if (OB_FAIL(do_resolve_set_query_in_cte(parse_tree, need_swap_child))) {
      LOG_WARN("failed to do resolve set query in cte", K(ret));
    }
O
oceanbase-admin 已提交
90 91 92 93 94 95
  } else if (OB_FAIL(do_resolve_set_query(parse_tree))) {
    LOG_WARN("failed to do resolve set query", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
int ObSelectResolver::do_check_basic_table_in_cte_recursive_union(const ParseNode &parse_tree, bool &recursive_union)
{
  int ret = OB_SUCCESS;
  const ParseNode *table_node = &parse_tree;
  bool no_defined_database_name = true;

  if (T_ORG == parse_tree.type_) {
    table_node = parse_tree.children_[0];
  } else if (T_ALIAS == parse_tree.type_) {
    table_node = parse_tree.children_[0];
  }
  no_defined_database_name = (table_node->children_[0] == NULL);
  // compare current table name is equal to current cte table name
  ObString tblname(table_node->str_len_, table_node->str_value_);
  if (cte_ctx_.is_with_resolver()
      && ObCharset::case_insensitive_equal(cte_ctx_.current_cte_table_name_, tblname)
      && tblname.length()
      && no_defined_database_name) {
    recursive_union = true;
  }
  return ret;
}


// recursive test node to find a cte table
int ObSelectResolver::do_check_node_in_cte_recursive_union(const ParseNode* current_node, bool &recursive_union) 
{
  int ret = OB_SUCCESS;
  while (OB_NOT_NULL(current_node) && current_node->type_ != T_RELATION_FACTOR && current_node->num_child_ == 1) {
    // the current node with only one child node expands immediately to prevent the recursive level from being too high
    current_node = current_node->children_[0];
  }

  if (OB_ISNULL(current_node)) {
  } else if (current_node->type_ == T_RELATION_FACTOR) {
    // find relation factor, check it
    if (OB_FAIL(do_check_basic_table_in_cte_recursive_union(*current_node, recursive_union))) {
      LOG_WARN("failed to do check basic table is in cte recursive union", K(ret));
    } 
  } else {
    for (int32_t i = 0; OB_SUCC(ret) && i < current_node->num_child_ && !recursive_union; i += 1) {
      if (OB_FAIL(SMART_CALL(do_check_node_in_cte_recursive_union(current_node->children_[i], recursive_union)))) {
        LOG_WARN("failed to do check node is in cte recursive union", K(ret));
      }
    }
  }

  return ret;
}

// test if a query node contains recursive nodes
int ObSelectResolver::check_query_is_recursive_union(const ParseNode &parse_tree, bool &recursive_union, bool &need_swap_child)
{
  int ret = OB_SUCCESS;
  ParseNode *left_node = NULL;
  ParseNode *right_node = NULL;
  
  bool left_recursive_union = false;
  bool right_recursive_union = false;

  if (OB_ISNULL(left_node = parse_tree.children_[PARSE_SELECT_FORMER])
      || OB_ISNULL(right_node = parse_tree.children_[PARSE_SELECT_LATER])
      || OB_ISNULL(parse_tree.children_[PARSE_SELECT_SET])) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret));
  } else if (OB_FAIL(do_check_node_in_cte_recursive_union(left_node, left_recursive_union))) {
    //test left branch
    LOG_WARN("failed to check set query in cte is recursive union", K(ret));
  } else if (OB_FAIL(do_check_node_in_cte_recursive_union(right_node, right_recursive_union))) {
    //test right branch
    LOG_WARN("failed to check set query in cte is recursive union", K(ret));
  }
  
  recursive_union = left_recursive_union || right_recursive_union;

  /**
    *  为什么需要交换左右支?
    *  with cte(c1) as (select 1 from dual union all select c1+1 from cte where c1 < 100)
    *  select * from cte;
    *
    *  with cte(c1) as (select c1+1 from cte where c1 < 100 && select 1 from dual)
    *  select * from cte;
    *
    *  oracle支持这两种写法。之前在cte的实现时是误判了,认为只能左边是anchor member。
    *  对于recursive cte的revolber解析来说,左右支解析是敏感的,右边的解析依赖于左边先被
    *  解析。为什么呢?因为假设在没有解析左边的时候就开始解析右边,我们完全不知道cte这张表
    *  的c1列是什么类型。所以这里先判断是否需要交换左右支。
    */
  if (is_oracle_mode() && left_recursive_union && !right_recursive_union) {
    need_swap_child = true;
  }

  return ret;
}

// resolve 对于非cte, union, check child 能否展平(limit、order、fetch)
int ObSelectResolver::do_resolve_set_query_in_cte(const ParseNode &parse_tree, bool swap_branch)
O
oceanbase-admin 已提交
193 194 195
{
  int ret = OB_SUCCESS;
  bool need_swap_child = false;
W
wangzelin.wzl 已提交
196
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
197 198 199 200
  SelectParserOffset left_member = PARSE_SELECT_FORMER;
  SelectParserOffset right_member = PARSE_SELECT_LATER;
  ObSelectResolver left_resolver(params_);
  ObSelectResolver right_resolver(params_);
W
wangzelin.wzl 已提交
201 202
  ObSelectStmt *left_select_stmt = NULL;
  ObSelectStmt *right_select_stmt = NULL;
O
oceanbase-admin 已提交
203 204

  left_resolver.set_current_level(current_level_);
W
wangzelin.wzl 已提交
205
  left_resolver.set_current_view_level(current_view_level_);
O
oceanbase-admin 已提交
206 207 208 209 210
  left_resolver.set_in_set_query(true);
  left_resolver.set_parent_namespace_resolver(parent_namespace_resolver_);
  left_resolver.set_calc_found_rows(has_calc_found_rows_);

  right_resolver.set_current_level(current_level_);
W
wangzelin.wzl 已提交
211
  right_resolver.set_current_view_level(current_view_level_);
O
oceanbase-admin 已提交
212 213 214
  right_resolver.set_in_set_query(true);
  right_resolver.set_parent_namespace_resolver(parent_namespace_resolver_);

W
wangzelin.wzl 已提交
215 216 217 218
  OC( (left_resolver.set_cte_ctx)(cte_ctx_) );
  OC( (right_resolver.set_cte_ctx)(cte_ctx_) );

  left_resolver.cte_ctx_.set_recursive_left_branch();
O
oceanbase-admin 已提交
219

W
wangzelin.wzl 已提交
220 221 222 223 224 225 226 227
  if (swap_branch) {
    left_member = PARSE_SELECT_LATER;
    right_member = PARSE_SELECT_FORMER;
  }

  if (OB_FAIL(ret)) {
  } else if (OB_ISNULL(select_stmt) || OB_ISNULL(parse_tree.children_[PARSE_SELECT_FORMER])
      || OB_ISNULL(parse_tree.children_[PARSE_SELECT_LATER])) {
O
oceanbase-admin 已提交
228
    ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
229 230
    LOG_WARN("unexpected null", K(ret), K(select_stmt),
        K(parse_tree.children_[PARSE_SELECT_FORMER]), K(parse_tree.children_[PARSE_SELECT_LATER]));
O
oceanbase-admin 已提交
231 232 233 234 235 236 237
  } else if (parse_tree.children_[PARSE_SELECT_LATER]->value_ == 1) {
    ret = OB_ERR_ILLEGAL_ID;
    LOG_WARN("Select for update statement can not process set query");
  } else if (OB_FAIL(set_stmt_set_type(select_stmt, parse_tree.children_[PARSE_SELECT_SET]))) {
    LOG_WARN("failed to set stmt set type", K(ret));
  } else if (OB_FAIL(resolve_with_clause(parse_tree.children_[PARSE_SELECT_WITH]))) {
    LOG_WARN("failed to resolve with clause", K(ret));
W
wangzelin.wzl 已提交
238 239
  } else if (OB_FAIL(add_cte_table_to_children(left_resolver)) ||
             OB_FAIL(add_cte_table_to_children(right_resolver))) {
O
oceanbase-admin 已提交
240
    LOG_WARN("failed to add cte table to children", K(ret));
W
wangzelin.wzl 已提交
241 242 243 244 245 246 247 248 249 250 251 252 253
  } else if (OB_FAIL(left_resolver.resolve_child_stmt(*(parse_tree.children_[left_member])))) {
    if (OB_ERR_NEED_INIT_BRANCH_IN_RECURSIVE_CTE == ret) {
      if (is_oracle_mode()){
        /* do nothing */
        LOG_WARN("Failed to resolve child stmt", K(ret));
      } else if (params_.has_recursive_word_) {
        ret = OB_ERR_CTE_NEED_QUERY_BLOCKS;  // mysql error: Recursive Common Table Expression 'cte' should have one or
                                             // more non-recursive query blocks followed by one or more recursive ones
        LOG_WARN("Failed to resolve child stmt", K(ret));
      } else {
        ret = OB_TABLE_NOT_EXIST;
        LOG_WARN("cte table shows in left union stmt without recursive keyword", K(ret));
      }
O
oceanbase-admin 已提交
254
    } else {
W
wangzelin.wzl 已提交
255
      LOG_WARN("Failed to find anchor member", K(ret));
O
oceanbase-admin 已提交
256
    }
W
wangzelin.wzl 已提交
257 258
  } else {
    left_select_stmt = left_resolver.get_child_stmt();
O
oceanbase-admin 已提交
259

W
wangzelin.wzl 已提交
260 261 262 263 264
    if (swap_branch) {
      select_stmt->set_children_swapped();
    }
  } 
  
265
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
266 267
    if (!params_.has_cte_param_list_ && 
        !left_resolver.cte_ctx_.cte_col_names_.empty()) {
268 269
      right_resolver.cte_ctx_.cte_col_names_.reset();
      cte_ctx_.cte_col_names_.reset();
W
wangzelin.wzl 已提交
270 271
      for (int64_t i = 0; OB_SUCC(ret) && i < left_resolver.cte_ctx_.cte_col_names_.count(); ++i) {
        // to right resolver
272
        if (OB_FAIL(right_resolver.cte_ctx_.cte_col_names_.push_back(
W
wangzelin.wzl 已提交
273 274 275 276 277 278
                left_resolver.cte_ctx_.cte_col_names_.at(i)))) {
          LOG_WARN("pass cte column name to child resolver failed", K(ret));
        // to parent resolver
        } else if (OB_FAIL(cte_ctx_.cte_col_names_.push_back(
                left_resolver.cte_ctx_.cte_col_names_.at(i)))) {
          LOG_WARN("pass cte column name to child resolver failed", K(ret));
279 280 281 282 283
        }
      }
    }
  }

O
oceanbase-admin 已提交
284
  if (OB_FAIL(ret)) {
W
wangzelin.wzl 已提交
285 286
  } else if (OB_FALSE_IT(right_resolver.cte_ctx_.set_recursive_right_branch(left_select_stmt,
                            parse_tree.children_[left_member], !select_stmt->is_set_distinct()))) {
O
oceanbase-admin 已提交
287 288 289 290
  } else if (OB_FAIL(right_resolver.resolve_child_stmt(*parse_tree.children_[right_member]))) {
    LOG_WARN("failed to resolve child stmt", K(ret));
  } else if (OB_FAIL(resolve_into_clause(ObResolverUtils::get_select_into_node(parse_tree)))) {
    LOG_WARN("failed to resolve into clause", K(ret));
W
wangzelin.wzl 已提交
291 292
  } else if (OB_ISNULL(right_select_stmt = right_resolver.get_child_stmt())
             || OB_ISNULL(left_select_stmt)) {
O
oceanbase-admin 已提交
293 294 295 296 297 298
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret), K(left_select_stmt), K(right_select_stmt));
  } else {
    select_stmt->add_set_query(left_select_stmt);
    select_stmt->add_set_query(right_select_stmt);
    select_stmt->set_calc_found_rows(left_select_stmt->is_calc_found_rows());
W
wangzelin.wzl 已提交
299 300 301 302
    if (OB_FAIL(ObOptimizerUtil::gen_set_target_list(allocator_, session_info_,
                                                     params_.expr_factory_, *left_select_stmt,
                                                     *right_select_stmt, select_stmt,
                                                     !is_oracle_mode()))) {
O
oceanbase-admin 已提交
303 304 305 306 307 308
      LOG_WARN("failed to gen set target list.", K(ret));
    } else if (!right_resolver.cte_ctx_.is_recursive()) {
      /*do nothing*/
    } else if (OB_FAIL(check_cte_set_types(*left_select_stmt, *right_select_stmt))) {
      LOG_WARN("check cte set types", K(ret));
    } else if (select_stmt->is_set_distinct() || ObSelectStmt::UNION != select_stmt->get_set_op()) {
W
wangzelin.wzl 已提交
309
      // 必须是union all
O
oceanbase-admin 已提交
310 311 312 313 314 315 316 317 318
      ret = OB_NOT_SUPPORTED;
      LOG_USER_ERROR(OB_NOT_SUPPORTED, "recursive WITH clause using operation not union all");
      LOG_USER_ERROR(OB_NOT_SUPPORTED, "recursive WITH clause using union (distinct) operation");
    } else if (OB_FAIL(check_recursive_cte_limited())) {
      LOG_WARN("failed to check recursive cte limited", K(ret));
    } else if (OB_NOT_NULL(parse_tree.children_[PARSE_SELECT_LIMIT])) {
      ret = OB_ERR_CTE_ILLEGAL_RECURSIVE_BRANCH;
      LOG_WARN("use limit clause in the recursive cte is not allowed", K(ret));
    } else {
W
wangzelin.wzl 已提交
319 320 321 322
      /**
      * 设置这个一个set query是否是with clause中的递归类型
      * 这个带有set op 为union的stmt,被标记为递归union,在后续展开时,平常的union all算子将被R union算子取代
      */
O
oceanbase-admin 已提交
323 324 325 326 327 328 329 330 331 332 333 334 335 336
      select_stmt->set_recursive_union(true);
    }
  }

  if (OB_FAIL(ret)) {
  } else if (parse_tree.children_[PARSE_SELECT_FOR_UPD] != NULL && is_oracle_mode()) {
    ret = OB_ERR_FOR_UPDATE_EXPR_NOT_ALLOWED;
    LOG_WARN("set stmt can not have for update clause", K(ret));
  } else if (OB_FAIL(resolve_order_clause(parse_tree.children_[PARSE_SELECT_ORDER]))) {
    LOG_WARN("failed to resolve order clause", K(ret));
  } else if (OB_FAIL(resolve_limit_clause(parse_tree.children_[PARSE_SELECT_LIMIT]))) {
    LOG_WARN("failed to resolve limit clause", K(ret));
  } else if (OB_FAIL(resolve_fetch_clause(parse_tree.children_[PARSE_SELECT_FETCH]))) {
    LOG_WARN("failed to resolve fetch clause", K(ret));
W
wangzelin.wzl 已提交
337 338 339 340
  } else if (OB_FAIL(resolve_check_option_clause(parse_tree.children_[PARSE_SELECT_WITH_CHECK_OPTION]))) {
    LOG_WARN("failed to resolve check option clause", K(ret));
  } else if (OB_FAIL(resolve_set_query_hint())) {
    LOG_WARN("failed to resolve set query hint", K(ret));
O
oceanbase-admin 已提交
341 342
  } else if (OB_FAIL(select_stmt->formalize_stmt(session_info_))) {
    LOG_WARN("failed to formalize stmt", K(ret));
W
wangzelin.wzl 已提交
343 344
  } else if (OB_FAIL(check_order_by())) {
    LOG_WARN("failed to check order by", K(ret));
X
xianyu-w 已提交
345 346
  } else if (OB_FAIL(check_udt_set_query())) {
    LOG_WARN("failed to check udt set query", K(ret));
O
oceanbase-admin 已提交
347 348 349 350 351 352 353
  } else if (has_top_limit_) {
    has_top_limit_ = false;
    select_stmt->set_has_top_limit(NULL != parse_tree.children_[PARSE_SELECT_LIMIT]);
  }
  return ret;
}

W
wangzelin.wzl 已提交
354 355
// just add id name pair to generate qb name.
int ObSelectResolver::resolve_set_query_hint()
O
oceanbase-admin 已提交
356 357
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
  ObDMLStmt *stmt = NULL;
  ObQueryCtx *query_ctx = NULL;
  ObString qb_name;
  if (OB_ISNULL(stmt = get_stmt()) || OB_ISNULL(query_ctx = stmt->get_query_ctx())) {
    ret = OB_NOT_INIT;
    LOG_WARN("Stmt and query ctx should not be NULL. ", K(ret), K(stmt), K(query_ctx));
  } else if (OB_FAIL(query_ctx->get_query_hint_for_update().set_stmt_id_map_info(*stmt, qb_name))) {
    LOG_WARN("failed to add id name pair", K(ret));
  }
  return ret;
}

int ObSelectResolver::do_resolve_set_query(const ParseNode &parse_tree)
{
  int ret = OB_SUCCESS;
  ObSelectStmt *select_stmt = get_select_stmt();
  ParseNode *left_node = NULL;
  ParseNode *right_node = NULL;
O
oceanbase-admin 已提交
376 377
  ObSEArray<ObSelectStmt*, 2> left_child_stmts;
  ObSEArray<ObSelectStmt*, 2> right_child_stmts;
W
wangzelin.wzl 已提交
378 379 380
  if (OB_ISNULL(left_node = parse_tree.children_[PARSE_SELECT_FORMER])
      || OB_ISNULL(right_node = parse_tree.children_[PARSE_SELECT_LATER])
      || OB_ISNULL(parse_tree.children_[PARSE_SELECT_SET]) || OB_ISNULL(select_stmt)) {
O
oceanbase-admin 已提交
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret));
  } else if (right_node->value_ == 1) {
    ret = OB_ERR_ILLEGAL_ID;
    LOG_WARN("Select for update statement can not process set query", K(ret));
  } else if (OB_FAIL(set_stmt_set_type(select_stmt, parse_tree.children_[PARSE_SELECT_SET]))) {
    LOG_WARN("failed to set stmt set type", K(ret));
  } else if (OB_FAIL(resolve_into_clause(ObResolverUtils::get_select_into_node(parse_tree)))) {
    LOG_WARN("failed to resolve into clause", K(ret));
  } else if (parse_tree.children_[PARSE_SELECT_FOR_UPD] != NULL && is_oracle_mode()) {
    ret = OB_ERR_FOR_UPDATE_EXPR_NOT_ALLOWED;
    LOG_WARN("set stmt can not have for update clause", K(ret));
  } else if (OB_FAIL(resolve_with_clause(parse_tree.children_[PARSE_SELECT_WITH]))) {
    LOG_WARN("failed to resolve with clause", K(ret));
  } else if (T_SET_UNION == parse_tree.children_[PARSE_SELECT_SET]->type_) {
W
wangzelin.wzl 已提交
396
    // union 进行展平
O
oceanbase-admin 已提交
397 398 399 400 401 402
    if (OB_FAIL(SMART_CALL(do_resolve_set_query(*left_node, left_child_stmts, true)))) {
      LOG_WARN("failed to do resolve set query", K(ret));
    } else if (OB_FAIL(SMART_CALL(do_resolve_set_query(*right_node, right_child_stmts)))) {
      LOG_WARN("failed to do resolve set query", K(ret));
    }
  } else {
W
wangzelin.wzl 已提交
403 404 405
    // union 以外 set 不进行展平
    ObSelectStmt *left_child_stmt = NULL;
    ObSelectStmt *right_child_stmt= NULL;
O
oceanbase-admin 已提交
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
    if (OB_FAIL(SMART_CALL(do_resolve_set_query(*left_node, left_child_stmt, true)))) {
      LOG_WARN("failed to do resolve set query", K(ret));
    } else if (OB_FAIL(SMART_CALL(do_resolve_set_query(*right_node, right_child_stmt)))) {
      LOG_WARN("failed to do resolve set query", K(ret));
    } else if (OB_FAIL(left_child_stmts.push_back(left_child_stmt)) ||
               OB_FAIL(right_child_stmts.push_back(right_child_stmt))) {
      LOG_WARN("failed set child stmts", K(ret));
    }
  }

  if (OB_SUCC(ret)) {
    select_stmt->get_set_query().reuse();
    if (OB_FAIL(select_stmt->get_set_query().assign(left_child_stmts)) ||
        OB_FAIL(append(select_stmt->get_set_query(), right_child_stmts))) {
      LOG_WARN("failed add child stmts", K(ret));
W
wangzelin.wzl 已提交
421 422 423 424
    } else if (OB_FAIL(ObOptimizerUtil::gen_set_target_list(allocator_, session_info_,
                                                            params_.expr_factory_,
                                                            left_child_stmts, right_child_stmts,
                                                            select_stmt))) {
O
oceanbase-admin 已提交
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
      LOG_WARN("failed to get set target list", K(ret));
    } else {
      select_stmt->set_calc_found_rows(select_stmt->get_set_query(0)->is_calc_found_rows());
    }
  }

  if (OB_FAIL(ret)) {
  } else if (parse_tree.children_[PARSE_SELECT_FOR_UPD] != NULL && is_oracle_mode()) {
    ret = OB_ERR_FOR_UPDATE_EXPR_NOT_ALLOWED;
    LOG_WARN("set stmt can not have for update clause", K(ret));
  } else if (OB_FAIL(resolve_order_clause(parse_tree.children_[PARSE_SELECT_ORDER]))) {
    LOG_WARN("failed to resolve order clause", K(ret));
  } else if (OB_FAIL(resolve_limit_clause(parse_tree.children_[PARSE_SELECT_LIMIT]))) {
    LOG_WARN("failed to resolve limit clause", K(ret));
  } else if (OB_FAIL(resolve_fetch_clause(parse_tree.children_[PARSE_SELECT_FETCH]))) {
    LOG_WARN("failed to resolve fetch clause", K(ret));
W
wangzelin.wzl 已提交
441 442 443 444
  } else if (OB_FAIL(resolve_check_option_clause(parse_tree.children_[PARSE_SELECT_WITH_CHECK_OPTION]))) {
    LOG_WARN("failed to resolve check option clause", K(ret));
  } else if (OB_FAIL(resolve_set_query_hint())) {
    LOG_WARN("failed to resolve set query hint", K(ret));
O
oceanbase-admin 已提交
445 446
  } else if (OB_FAIL(select_stmt->formalize_stmt(session_info_))) {
    LOG_WARN("failed to formalize stmt", K(ret));
W
wangzelin.wzl 已提交
447 448
  } else if (OB_FAIL(check_order_by())) {
    LOG_WARN("failed to check order by", K(ret));
X
xianyu-w 已提交
449 450
  } else if (OB_FAIL(check_udt_set_query())) {
    LOG_WARN("failed to check udt set query", K(ret));
O
oceanbase-admin 已提交
451 452 453 454 455 456 457
  } else if (has_top_limit_) {
    has_top_limit_ = false;
    select_stmt->set_has_top_limit(NULL != parse_tree.children_[PARSE_SELECT_LIMIT]);
  }
  return ret;
}

X
xianyu-w 已提交
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
int ObSelectResolver::check_udt_set_query()
{
  int ret = OB_SUCCESS;
  ObSelectStmt *select_stmt = get_select_stmt();
  if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret));
  } else if (select_stmt->is_set_stmt()) {
    if (select_stmt->get_set_op() == ObSelectStmt::UNION && !select_stmt->is_set_distinct()) {
      // UNION ALL
      // do nothing
    } else {
      for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_select_item_size(); i++) {
        ObRawExpr *expr = select_stmt->get_select_item(i).expr_;
        if (OB_ISNULL(expr)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("unexpected null", K(ret));
        } else if (expr->get_result_type().is_ext()) {
          ret = OB_NOT_SUPPORTED;
          LOG_WARN("set operator for udt not supported", K(ret));
          LOG_USER_ERROR(OB_NOT_SUPPORTED, "set operator for udt");
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
486 487 488 489
// resolve 对于非cte, union, check child 能否展平(limit、order、fetch)
int ObSelectResolver::do_resolve_set_query(const ParseNode &parse_tree,
                                           common::ObIArray<ObSelectStmt*> &child_stmts,
                                           const bool is_left_child) /*default false*/
O
oceanbase-admin 已提交
490 491
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
492
  bool can_flatten = false;
O
oceanbase-admin 已提交
493
  bool is_type_same = false;
W
wangzelin.wzl 已提交
494
  ObSelectStmt *select_stmt = NULL;
O
oceanbase-admin 已提交
495 496 497 498 499 500
  if (OB_ISNULL(select_stmt = get_select_stmt())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret), K(select_stmt));
  } else if (parse_tree.children_[PARSE_SELECT_FOR_UPD] != NULL && is_oracle_mode()) {
    ret = OB_ERR_FOR_UPDATE_EXPR_NOT_ALLOWED;
    LOG_WARN("set stmt can not have for update clause", K(ret));
W
wangzelin.wzl 已提交
501 502
  } else if (OB_FAIL(is_set_type_same(select_stmt, parse_tree.children_[PARSE_SELECT_SET],
                                      is_type_same))) {
O
oceanbase-admin 已提交
503 504
    LOG_WARN("failed to check is set type same", K(ret));
  } else if (!is_type_same) {
W
wangzelin.wzl 已提交
505 506 507 508
    // select_stmt 与待 resolve set stmt 类型不同, 无法展平
    can_flatten = false;
  } else if (NULL != parse_tree.children_[PARSE_SELECT_ORDER] ||
             NULL != parse_tree.children_[PARSE_SELECT_LIMIT] ||
O
oceanbase-admin 已提交
509
             NULL != parse_tree.children_[PARSE_SELECT_FETCH]) {
W
wangzelin.wzl 已提交
510 511
    // 待 resolve set stmt 有 order by / limit / fetch, 无法展平
    can_flatten = false;
O
oceanbase-admin 已提交
512
  } else if (ObSelectStmt::UNION == select_stmt->get_set_op()) {
W
wangzelin.wzl 已提交
513 514
    // 仅对 union 进行展平
    can_flatten = true;
O
oceanbase-admin 已提交
515 516 517
  }

  if (OB_FAIL(ret)) {
W
wangzelin.wzl 已提交
518
  } else if (can_flatten) {
O
oceanbase-admin 已提交
519 520
    ObSEArray<ObSelectStmt*, 2> left_child_stmts;
    ObSEArray<ObSelectStmt*, 2> right_child_stmts;
W
wangzelin.wzl 已提交
521 522 523 524
    ParseNode *left_node = NULL;
    ParseNode *right_node = NULL;
    if (OB_ISNULL(left_node = parse_tree.children_[PARSE_SELECT_FORMER])
        || OB_ISNULL(right_node = parse_tree.children_[PARSE_SELECT_LATER])) {
O
oceanbase-admin 已提交
525 526 527 528 529
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected null", K(ret));
    } else if (right_node->value_ == 1) {
      ret = OB_ERR_ILLEGAL_ID;
      LOG_WARN("Select for update statement can not process set query", K(ret));
W
wangzelin.wzl 已提交
530 531 532
    } else if (lib::is_oracle_mode() && OB_NOT_NULL(parse_tree.children_[PARSE_SELECT_WITH])) {
      ret = OB_ERR_UNSUPPORTED_USE_OF_CTE;
      LOG_WARN("oracle not support use of cte", K(ret));
O
oceanbase-admin 已提交
533 534 535 536
    } else if (OB_FAIL(resolve_into_clause(ObResolverUtils::get_select_into_node(parse_tree)))) {
      LOG_WARN("failed to resolve into clause", K(ret));
    } else if (OB_FAIL(resolve_with_clause(parse_tree.children_[PARSE_SELECT_WITH]))) {
      LOG_WARN("failed to resolve with clause", K(ret));
W
wangzelin.wzl 已提交
537 538
    } else if (OB_FAIL(SMART_CALL(do_resolve_set_query(*left_node, left_child_stmts,
                                                       is_left_child)))) {
O
oceanbase-admin 已提交
539 540 541
      LOG_WARN("failed to do resolve set query", K(ret));
    } else if (OB_FAIL(SMART_CALL(do_resolve_set_query(*right_node, right_child_stmts)))) {
      LOG_WARN("failed to do resolve set query", K(ret));
W
wangzelin.wzl 已提交
542 543 544
    } else if (OB_FAIL(ObOptimizerUtil::try_add_cast_to_set_child_list(allocator_, session_info_,
                                          params_.expr_factory_, select_stmt->is_set_distinct(),
                                          left_child_stmts, right_child_stmts, NULL))) {
O
oceanbase-admin 已提交
545
      LOG_WARN("failed to try add cast to set child list", K(ret));
W
wangzelin.wzl 已提交
546 547
    } else if (OB_FAIL(append(child_stmts, left_child_stmts)) ||
               OB_FAIL(append(child_stmts, right_child_stmts))) {
O
oceanbase-admin 已提交
548 549 550
      LOG_WARN("failed to append stmts", K(ret));
    }
  } else {
W
wangzelin.wzl 已提交
551
    ObSelectStmt *child_stmt = NULL;
O
oceanbase-admin 已提交
552 553 554 555 556 557 558 559 560
    if (OB_FAIL(do_resolve_set_query(parse_tree, child_stmt, is_left_child))) {
      LOG_WARN("failed to do resolve set query", K(ret));
    } else if (OB_FAIL(child_stmts.push_back(child_stmt))) {
      LOG_WARN("failed to push back", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
561 562 563
int ObSelectResolver::do_resolve_set_query(const ParseNode &parse_tree,
                                           ObSelectStmt *&child_stmt,
                                           const bool is_left_child) /*default false*/
O
oceanbase-admin 已提交
564 565 566 567 568 569
{
  int ret = OB_SUCCESS;
  child_stmt = NULL;
  ObSelectResolver child_resolver(params_);

  child_resolver.set_current_level(current_level_);
W
wangzelin.wzl 已提交
570
  child_resolver.set_current_view_level(current_view_level_);
O
oceanbase-admin 已提交
571 572 573
  child_resolver.set_in_set_query(true);
  child_resolver.set_parent_namespace_resolver(parent_namespace_resolver_);
  child_resolver.set_calc_found_rows(is_left_child && has_calc_found_rows_);
W
wangzelin.wzl 已提交
574
  child_resolver.set_is_left_child(is_left_child);
O
oceanbase-admin 已提交
575 576 577 578 579 580 581 582 583 584 585

  if (OB_FAIL(child_resolver.set_cte_ctx(cte_ctx_))) {
    LOG_WARN("failed to set cte ctx", K(ret));
  } else if (OB_FAIL(add_cte_table_to_children(child_resolver))) {
    LOG_WARN("failed to add cte table to children", K(ret));
  } else if (OB_FAIL(child_resolver.resolve_child_stmt(parse_tree))) {
    LOG_WARN("failed to resolve child stmt", K(ret));
  } else if (OB_ISNULL(child_stmt = child_resolver.get_child_stmt())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get null child stmt", K(ret));
  }
W
wangzelin.wzl 已提交
586

O
oceanbase-admin 已提交
587 588 589
  return ret;
}

W
wangzelin.wzl 已提交
590 591
int ObSelectResolver::set_stmt_set_type(ObSelectStmt *select_stmt,
                                        ParseNode *set_node)
O
oceanbase-admin 已提交
592 593 594 595 596 597 598 599
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(select_stmt) || OB_ISNULL(set_node)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null", K(ret));
  } else {
    // assign set type
    switch (set_node->type_) {
W
wangzelin.wzl 已提交
600 601 602 603 604 605 606 607 608 609 610 611 612
    case T_SET_UNION:
      select_stmt->assign_set_op(ObSelectStmt::UNION);
      break;
    case T_SET_INTERSECT:
      select_stmt->assign_set_op(ObSelectStmt::INTERSECT);
      break;
    case T_SET_EXCEPT:
      select_stmt->assign_set_op(ObSelectStmt::EXCEPT);
      break;
    default:
      ret = OB_ERR_OPERATOR_UNKNOWN;
      LOG_WARN("unknown set operator of set clause");
      break;
O
oceanbase-admin 已提交
613 614 615 616 617 618 619 620 621 622
    }
    // check distinct and all
    if (OB_FAIL(ret)) {
    } else if (1 != set_node->num_child_) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("wrong num_child_", K(set_node->num_child_));
    } else if (NULL == set_node->children_[0]) {
      select_stmt->assign_set_distinct();
    } else {
      switch (set_node->children_[0]->type_) {
W
wangzelin.wzl 已提交
623 624 625 626 627 628 629 630 631 632
      case T_ALL:
        select_stmt->assign_set_all();
        break;
      case T_DISTINCT:
        select_stmt->assign_set_distinct();
        break;
      default:
        ret = OB_ERR_OPERATOR_UNKNOWN;
        LOG_WARN("unknown set operator of set option");
        break;
O
oceanbase-admin 已提交
633 634 635 636 637 638
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
639 640 641
int ObSelectResolver::is_set_type_same(const ObSelectStmt *select_stmt,
                                       ParseNode *set_node,
                                       bool &is_type_same)
O
oceanbase-admin 已提交
642 643 644 645 646
{
  int ret = OB_SUCCESS;
  is_type_same = false;
  if (OB_ISNULL(set_node)) {
    /*do nothing*/
W
wangzelin.wzl 已提交
647 648 649 650
  } else if ((ObSelectStmt::INTERSECT == select_stmt->get_set_op()
              && T_SET_INTERSECT == set_node->type_)
             || (ObSelectStmt::EXCEPT == select_stmt->get_set_op()
                 && T_SET_EXCEPT == set_node->type_)) {
O
oceanbase-admin 已提交
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
    is_type_same = true;
  } else if (ObSelectStmt::UNION == select_stmt->get_set_op() && T_SET_UNION == set_node->type_) {
    if (1 != set_node->num_child_) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("wrong num_child_", K(set_node->num_child_));
    } else if (NULL == set_node->children_[0] || T_DISTINCT == set_node->children_[0]->type_) {
      is_type_same = select_stmt->is_set_distinct();
    } else if (T_ALL == set_node->children_[0]->type_) {
      is_type_same = !select_stmt->is_set_distinct();
    } else {
      ret = OB_ERR_OPERATOR_UNKNOWN;
      LOG_WARN("unknown set operator of set option");
    }
  } else {
    is_type_same = false;
  }
  return ret;
}

int ObSelectResolver::check_recursive_cte_limited()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
673 674 675 676
  ObSelectStmt *select_stmt = NULL;
  ObSelectStmt *right_stmt = NULL;
  if (OB_ISNULL(select_stmt = get_select_stmt()) ||
      OB_ISNULL(right_stmt = select_stmt->get_set_query(1))) {
O
oceanbase-admin 已提交
677 678 679 680 681
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("the recursive union stmt/right subquery is null", K(ret));
  } else if (OB_UNLIKELY(right_stmt->has_group_by())) {
    ret = OB_NOT_SUPPORTED;
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "group by in recursive with clause");
W
wangzelin.wzl 已提交
682
  } else if (OB_UNLIKELY(right_stmt->has_limit())){
O
oceanbase-admin 已提交
683 684 685 686 687 688 689 690 691 692 693
    ret = OB_NOT_SUPPORTED;
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "limit in recursive with clause");
  } else if (OB_UNLIKELY(right_stmt->has_top_limit())) {
    ret = OB_NOT_SUPPORTED;
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "limit in recursive with clause");
  } else if (OB_UNLIKELY(right_stmt->has_distinct())) {
    ret = OB_NOT_SUPPORTED;
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "distinct in recursive with clause");
  } else {
    for (int64_t i = 0; OB_SUCC(ret) && i < right_stmt->get_select_items().count(); ++i) {
      SelectItem& item = right_stmt->get_select_items().at(i);
W
wangzelin.wzl 已提交
694
      if (OB_UNLIKELY(jit::expr::ObIRawExpr::EXPR_AGGR == item.expr_->get_expr_class())) {
O
oceanbase-admin 已提交
695 696 697 698 699 700 701 702
        ret = OB_NOT_SUPPORTED;
        LOG_USER_ERROR(OB_NOT_SUPPORTED, "aggregation in recursive with clause");
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
703
int ObSelectResolver::check_cte_set_types(ObSelectStmt &left_stmt, ObSelectStmt &right_stmt)
O
oceanbase-admin 已提交
704 705 706 707
{
  int ret = OB_SUCCESS;
  ObExprResType res_type;
  int64_t num = left_stmt.get_select_item_size();
W
wangzelin.wzl 已提交
708
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
709 710 711 712 713 714 715 716
  if (OB_ISNULL(params_.expr_factory_) || OB_ISNULL(select_stmt)) {
    ret = OB_NOT_INIT;
    LOG_WARN("params is invalid", K(ret), K(select_stmt), K(params_.expr_factory_));
  } else if (left_stmt.get_select_item_size() != right_stmt.get_select_item_size()) {
    ret = OB_ERR_COLUMN_SIZE;
    LOG_WARN("The used SELECT statements have a different number of columns", K(ret));
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < num; i++) {
W
wangzelin.wzl 已提交
717 718
    SelectItem &left_select_item = left_stmt.get_select_item(i);
    SelectItem &right_select_item = right_stmt.get_select_item(i);
O
oceanbase-admin 已提交
719 720 721 722
    ObExprResType l_type = left_select_item.expr_->get_result_type();
    ObExprResType r_type = right_select_item.expr_->get_result_type();
    if (l_type != r_type) {
      if (((ObObjMeta)l_type) == ((ObObjMeta)r_type)) {
W
wangzelin.wzl 已提交
723
        //类型相等,不考虑精度
O
oceanbase-admin 已提交
724
      } else if (l_type.is_character_type() && r_type.is_character_type()) {
W
wangzelin.wzl 已提交
725
        //都是char大类型
O
oceanbase-admin 已提交
726
      } else if (l_type.is_integer_type() && r_type.is_integer_type()) {
W
wangzelin.wzl 已提交
727
        //都是integer类型
O
oceanbase-admin 已提交
728
      } else if (is_oracle_mode() && l_type.is_numeric_type() && r_type.is_numeric_type()) {
W
wangzelin.wzl 已提交
729
        //both numeric on oralce mode
O
oceanbase-admin 已提交
730
      } else {
W
wangzelin.wzl 已提交
731
        //union all两边的类型不一样,不能强转
O
oceanbase-admin 已提交
732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
        ret = OB_NOT_SUPPORTED;
        LOG_USER_ERROR(OB_NOT_SUPPORTED, "different types from different recursive cte union all branchs");
        LOG_WARN("different type in recursive cte not supported", K(ret));
      }
    }
  }
  return ret;
}

// checker is different between mysql and oracle mode
// oracle mode:
//   resolve path: from -> where -> connect by -> group by -> having -> select_items -> order by
//   so after group by, exprs in having, select items and order by must exists on group by exprs
// mysql mode
//   resolve path: from -> where -> select_items -> group by -> having -> order by
int ObSelectResolver::check_group_by()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
750
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
751
  CK(OB_NOT_NULL(select_stmt), OB_NOT_NULL(session_info_));
W
wangzelin.wzl 已提交
752
  CK(OB_NOT_NULL(select_stmt->get_query_ctx()));
753
  bool only_need_constraints = true;
W
wangzelin.wzl 已提交
754 755
  if (is_only_full_group_by_on(session_info_->get_sql_mode()) &&
      !select_stmt->get_query_ctx()->is_prepare_stmt()) {
O
oceanbase-admin 已提交
756
    if (is_oracle_mode()) {
757
      only_need_constraints = false;
O
oceanbase-admin 已提交
758
      for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_group_expr_size(); i++) {
W
wangzelin.wzl 已提交
759
        ObRawExpr *group_by_expr = NULL;
O
oceanbase-admin 已提交
760 761 762
        if (OB_ISNULL(group_by_expr = select_stmt->get_group_exprs().at(i))) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("group by expr is null", K(ret));
W
wangzelin.wzl 已提交
763
        } else if (ObLongTextType == group_by_expr->get_data_type()
X
xj0 已提交
764
                  || ObLobType == group_by_expr->get_data_type()
O
obdev 已提交
765
                  || ObJsonType == group_by_expr->get_data_type()
X
xianyu-w 已提交
766 767
                  || ObGeometryType == group_by_expr->get_data_type()
                  || ObExtendType == group_by_expr->get_data_type()) {
O
obdev 已提交
768 769 770
          ret = (lib::is_oracle_mode() && ObJsonType == group_by_expr->get_data_type())
                  ? OB_ERR_INVALID_CMP_OP : OB_ERR_INVALID_TYPE_FOR_OP;
          LOG_WARN("group by lob expr is not allowed", K(ret));
O
oceanbase-admin 已提交
771 772 773
        }
      }
      for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_rollup_expr_size(); i++) {
W
wangzelin.wzl 已提交
774
        ObRawExpr *rollup_expr = NULL;
O
oceanbase-admin 已提交
775 776 777
        if (OB_ISNULL(rollup_expr = select_stmt->get_rollup_exprs().at(i))) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("rollup expr is null", K(ret));
W
wangzelin.wzl 已提交
778
        } else if (ObLongTextType == rollup_expr->get_data_type()
X
xianyu-w 已提交
779 780
                  || ObLobType == rollup_expr->get_data_type()
                  || ObExtendType == rollup_expr->get_data_type()) {
O
oceanbase-admin 已提交
781
          ret = OB_ERR_INVALID_TYPE_FOR_OP;
X
xianyu-w 已提交
782
          LOG_WARN("group by lob or udt expr is not allowed", K(ret));
O
oceanbase-admin 已提交
783 784 785
        }
      }
      for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_grouping_sets_items_size(); i++) {
W
wangzelin.wzl 已提交
786 787 788 789
        const ObIArray<ObGroupbyExpr> &grouping_sets_exprs =
                                  select_stmt->get_grouping_sets_items().at(i).grouping_sets_exprs_;
        if (OB_FAIL(check_multi_rollup_items_valid(
                               select_stmt->get_grouping_sets_items().at(i).multi_rollup_items_))) {
O
oceanbase-admin 已提交
790 791 792
          LOG_WARN("failed to check multi rollup items valid", K(ret));
        } else {
          for (int64_t j = 0; OB_SUCC(ret) && j < grouping_sets_exprs.count(); ++j) {
W
wangzelin.wzl 已提交
793
            const ObIArray<ObRawExpr*> &groupby_exprs = grouping_sets_exprs.at(j).groupby_exprs_;
O
oceanbase-admin 已提交
794
            for (int64_t k = 0; OB_SUCC(ret) && k < groupby_exprs.count(); ++k) {
W
wangzelin.wzl 已提交
795
              ObRawExpr *groupby_expr = NULL;
O
oceanbase-admin 已提交
796 797 798
              if (OB_ISNULL(groupby_expr = groupby_exprs.at(k))) {
                ret = OB_ERR_UNEXPECTED;
                LOG_WARN("rollup expr is null", K(ret));
W
wangzelin.wzl 已提交
799
              } else if (ObLongTextType == groupby_expr->get_data_type()
X
xj0 已提交
800
                        || ObLobType == groupby_expr->get_data_type()
O
obdev 已提交
801
                        || ObJsonType == groupby_expr->get_data_type()
X
xianyu-w 已提交
802 803
                        || ObGeometryType == groupby_expr->get_data_type()
                        || ObExtendType == groupby_expr->get_data_type()) {
O
oceanbase-admin 已提交
804
                ret = OB_ERR_INVALID_TYPE_FOR_OP;
X
xianyu-w 已提交
805
                LOG_WARN("group by lob or udt expr is not allowed", K(ret));
O
oceanbase-admin 已提交
806 807 808 809 810 811 812 813
              }
            }
          }
        }
      }
      if (OB_SUCC(ret)) {
        if (OB_FAIL(check_multi_rollup_items_valid(select_stmt->get_multi_rollup_items()))) {
          LOG_WARN("failed to check multi rollup items valid", K(ret));
W
wangzelin.wzl 已提交
814
        } else {/*do nothing*/}
O
oceanbase-admin 已提交
815 816
      }
    } else {
W
wangzelin.wzl 已提交
817
      //在解析过程中,standard group checker会记录需要检查的column和expr,在所有语句都解析完成后
O
oceanbase-admin 已提交
818 819 820 821 822
      if (OB_FAIL(standard_group_checker_.check_only_full_group_by())) {
        LOG_WARN("failed to check group by");
      }
    }
  }
W
wangzelin.wzl 已提交
823

O
obdev 已提交
824 825 826 827 828 829 830 831 832 833
  if (OB_SUCC(ret)) {
    // skip add const constraint during prepare stage in PL
    const ParamStore *param_store = (NULL != params_.secondary_namespace_) ? NULL : params_.param_list_;
    if (OB_FAIL(ObGroupByChecker::check_group_by(param_store,
                                                 select_stmt,
                                                 having_has_self_column_,
                                                 has_group_by_clause(),
                                                 only_need_constraints))) {
      LOG_WARN("failed to check group by in oracle mode");
    }
834 835
  }

W
wangzelin.wzl 已提交
836 837 838 839 840
  // replace with same group by columns.
  // groupby之上的计算我们放在这里统一处理:
  // 1. select item/having/order item中的表达式树(子树)需要每个都在group by列中找到
  // 2. 递归查找是否在groupby列中,将在groupby的列的指针替换。
  if (OB_SUCC(ret)) {
841
    if (OB_FAIL(ObTransformUtils::replace_stmt_expr_with_groupby_exprs(select_stmt, NULL))) {
W
wangzelin.wzl 已提交
842 843 844
      LOG_WARN("failed to replace stmt expr with groupby columns", K(ret));
    }
  }
O
oceanbase-admin 已提交
845 846 847
  return ret;
}

X
xianyu-w 已提交
848
// 1. lob or udt type can't be ordered
O
oceanbase-admin 已提交
849 850 851 852
// 2. the order item should be exists in select items if has distinct
int ObSelectResolver::check_order_by()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
853
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
854 855 856 857 858 859 860 861 862
  if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null", K(ret));
  } else if (is_oracle_mode() && select_stmt->has_order_by()) {
    bool has_distinct = select_stmt->has_distinct();
    // If sql return single row, then don't check order by
    // eg: select distinct count(*) from t1 order by c1; -- return single row,then don't check
    bool need_check = !select_stmt->is_single_set_query();
    if (need_check) {
X
xianyu-w 已提交
863
      // 1. check lob type or udt
O
oceanbase-admin 已提交
864
      common::ObArray<ObRawExpr*> order_item_exprs;
W
wangzelin.wzl 已提交
865
      common::ObIArray<OrderItem> &order_items = select_stmt->get_order_items();
O
oceanbase-admin 已提交
866 867
      // special case: select count(*) from t1 order by c1; --c1 is blob, but optimized to be remove
      for (int64_t i = 0; OB_SUCC(ret) && i < order_items.count(); ++i) {
W
wangzelin.wzl 已提交
868
        if (ob_is_text_tc(order_items.at(i).expr_->get_data_type())
X
xj0 已提交
869
            || ob_is_lob_tc(order_items.at(i).expr_->get_data_type())
O
obdev 已提交
870
            || ob_is_json_tc(order_items.at(i).expr_->get_data_type())
X
xianyu-w 已提交
871 872
            || ob_is_geometry_tc(order_items.at(i).expr_->get_data_type())
            || ob_is_extend(order_items.at(i).expr_->get_data_type())) {
O
obdev 已提交
873 874 875
          ret = (lib::is_oracle_mode() && ob_is_json_tc(order_items.at(i).expr_->get_data_type()))
            ? OB_ERR_INVALID_CMP_OP : OB_ERR_INVALID_TYPE_FOR_OP;
          LOG_WARN("lob or json expr can't order", K(ret), K(*order_items.at(i).expr_));
O
oceanbase-admin 已提交
876 877 878 879 880 881 882 883 884
        } else if (has_distinct) {
          if (OB_FAIL(order_item_exprs.push_back(order_items.at(i).expr_))) {
            LOG_WARN("fail to push back expr", K(ret));
          }
        }
      }
      // 2. check if has distinct
      if (OB_SUCC(ret) && has_distinct) {
        common::ObArray<ObRawExpr*> select_item_exprs;
W
wangzelin.wzl 已提交
885
        common::ObIArray<SelectItem> &select_items = select_stmt->get_select_items();
O
oceanbase-admin 已提交
886
        for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); ++i) {
W
wangzelin.wzl 已提交
887
          ObRawExpr *expr = select_items.at(i).expr_;
O
oceanbase-admin 已提交
888 889 890 891
          if (OB_FAIL(select_item_exprs.push_back(expr))) {
            LOG_WARN("fail to push back expr", K(ret));
          }
        }
O
obdev 已提交
892 893 894 895 896 897 898 899 900 901 902
        if (OB_SUCC(ret)) {
          // skip add const constraint during prepare stage in PL
          const ParamStore *param_store = (NULL != params_.secondary_namespace_) ? NULL : params_.param_list_;
          if (OB_FAIL(ObGroupByChecker::check_by_expr(param_store,
                                                      select_stmt,
                                                      select_item_exprs,
                                                      order_item_exprs,
                                                      OB_ERR_NOT_SELECTED_EXPR,
                                                      true))) {
            LOG_WARN("fail to check order by", K(ret));
          }
O
oceanbase-admin 已提交
903 904 905 906 907 908 909 910 911 912
        }
      }
    }
  }
  return ret;
}

int ObSelectResolver::check_field_list()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
913 914
  ObSelectStmt *select_stmt = get_select_stmt();
  if (! is_oracle_mode()) {
O
oceanbase-admin 已提交
915 916 917 918
  } else if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null", K(ret));
  } else if (select_stmt->has_distinct()) {
W
wangzelin.wzl 已提交
919
    common::ObIArray<SelectItem> &select_items = select_stmt->get_select_items();
O
oceanbase-admin 已提交
920
    for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); i++) {
W
wangzelin.wzl 已提交
921
      ObRawExpr *expr = NULL;
O
oceanbase-admin 已提交
922 923 924 925 926 927
      if (OB_ISNULL(expr = select_items.at(i).expr_)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("select expr is null", K(ret));
      } else if (ObLongTextType == expr->get_data_type() || ObLobType == expr->get_data_type()) {
        ret = OB_ERR_INVALID_TYPE_FOR_OP;
        LOG_WARN("select distinct lob not allowed", K(ret));
O
obdev 已提交
928 929 930
      } else if (lib::is_oracle_mode() && ObJsonType == expr->get_data_type()) {
        ret = OB_ERR_INVALID_CMP_OP;
        LOG_WARN("select distinct json not allowed", K(ret));
O
oceanbase-admin 已提交
931 932 933 934 935 936
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
int ObSelectResolver::search_connect_group_by_clause(const ParseNode &parent,
                                   const ParseNode *&start_with,
                                   const ParseNode *&connect_by,
                                   const ParseNode *&group_by,
                                   const ParseNode *&having)
{
  int ret = OB_SUCCESS;
  if (is_oracle_mode()) {
    start_with = NULL;
    connect_by = NULL;
    group_by = NULL;
    having = NULL;
    const ParseNode *node = NULL;
    for (int64_t i = PARSE_SELECT_DYNAMIC_SW_CBY;
         i <= PARSE_SELECT_DYNAMIC_HAVING && OB_SUCC(ret);
         i++) {
      if (NULL == (node = parent.children_[i])) {
        // do nothing
      } else {
        switch (node->type_) {
          case T_START_WITH : {
            start_with = node->children_[0];
            break;
          }
          case T_CONNECT_BY_CLAUSE : {
            connect_by = node;
            break;
          }
          case T_GROUPBY_CLAUSE : {
            group_by = node;
            break;
          }
          case T_HAVING : {
            having = node->children_[0];
            break;
          }
          default : {
            ret = OB_INVALID_ARGUMENT;
            LOG_WARN("unexpected node type", K(ret), K(node->type_));
          }
        }
      }
    }
    if (OB_SUCC(ret) && OB_UNLIKELY(NULL == connect_by && NULL != start_with)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpect connect by is null while start with is not null", K(ret));
    }
  } else {
    start_with = NULL;
    connect_by = NULL;
    group_by = parent.children_[PARSE_SELECT_DYNAMIC_GROUP];
    having = parent.children_[PARSE_SELECT_DYNAMIC_HAVING];
  }
  return ret;
}

int ObSelectResolver::resolve_normal_query(const ParseNode &parse_tree)
O
oceanbase-admin 已提交
994 995 996 997 998 999
{
  int ret = OB_SUCCESS;
  // ObStmt *st = NULL;
  // ObSelectStmt *s_t = static_cast<ObSelectStmt *>(st);
  // used to record name win expr count
  int64_t count_name_win_expr = 0;
W
wangzelin.wzl 已提交
1000 1001 1002 1003 1004
  const ParseNode *start_with = NULL;
  const ParseNode *connect_by = NULL;
  const ParseNode *group_by = NULL;
  const ParseNode *having = NULL;
  ObSelectStmt *select_stmt = get_select_stmt();
O
obdev 已提交
1005
  bool has_rollup = false;
W
wangzelin.wzl 已提交
1006 1007 1008
  CK(OB_NOT_NULL(select_stmt),
     OB_NOT_NULL(session_info_),
     OB_NOT_NULL(select_stmt->get_query_ctx()));
O
oceanbase-admin 已提交
1009 1010 1011

  set_in_exists_subquery(2 == parse_tree.value_);

W
wangzelin.wzl 已提交
1012 1013 1014 1015 1016
  /**
   * @muhang.zb
   * 定义了一个cte,无论最终是否在主句使用,都必须要进行解析
   */
  OZ( resolve_with_clause(parse_tree.children_[PARSE_SELECT_WITH]) );
O
oceanbase-admin 已提交
1017 1018 1019

  /* normal select */
  select_stmt->assign_set_op(ObSelectStmt::NONE);
W
wangzelin.wzl 已提交
1020
  OZ( resolve_query_options(parse_tree.children_[PARSE_SELECT_DISTINCT]) );
O
oceanbase-admin 已提交
1021
  if (OB_SUCC(ret) && is_only_full_group_by_on(session_info_->get_sql_mode())) {
W
wangzelin.wzl 已提交
1022 1023 1024 1025 1026
    OZ( standard_group_checker_.init() );
  }
  OZ( search_connect_group_by_clause(parse_tree, start_with, connect_by, group_by, having) );
  if (OB_SUCC(ret) && OB_NOT_NULL(group_by)) {
    set_has_group_by_clause();
O
obdev 已提交
1027
    OZ (check_rollup_clause(group_by, has_rollup));
O
oceanbase-admin 已提交
1028
  }
W
wangzelin.wzl 已提交
1029 1030
  if (OB_SUCC(ret) && (start_with != NULL || connect_by != NULL)) {
    select_stmt->set_hierarchical_query(true);
O
oceanbase-admin 已提交
1031 1032
  }
  /* resolve from clause */
W
wangzelin.wzl 已提交
1033
  OZ( resolve_from_clause(parse_tree.children_[PARSE_SELECT_FROM]) );
O
oceanbase-admin 已提交
1034
  /* resolve start with clause */
W
wangzelin.wzl 已提交
1035
  OZ( resolve_start_with_clause(start_with) );
O
oceanbase-admin 已提交
1036
  /* resolve connect by clause */
W
wangzelin.wzl 已提交
1037
  OZ( resolve_connect_by_clause(connect_by) );
O
oceanbase-admin 已提交
1038
  /* resolve where clause */
W
wangzelin.wzl 已提交
1039
  OZ( resolve_where_clause(parse_tree.children_[PARSE_SELECT_WHERE]) );
O
oceanbase-admin 已提交
1040 1041 1042

  if (OB_SUCC(ret) && !is_oracle_mode()) {
    /* resolve named window clause */
W
wangzelin.wzl 已提交
1043
    OZ( resolve_named_windows_clause(parse_tree.children_[PARSE_SELECT_NAMED_WINDOWS]) );
O
oceanbase-admin 已提交
1044 1045 1046 1047 1048
  }
  /* resolve select clause */
  if (!is_oracle_mode()) {
    // mysql resolve: from->where->select_item->group by->having->order by
    count_name_win_expr = select_stmt->get_window_func_count();
O
obdev 已提交
1049 1050 1051
    if (has_rollup) {
      expr_resv_ctx_.set_new_scope();
    }
W
wangzelin.wzl 已提交
1052
    OZ( resolve_field_list(*(parse_tree.children_[PARSE_SELECT_SELECT])));
O
oceanbase-admin 已提交
1053 1054 1055
  }

  /* resolve group by clause */
W
wangzelin.wzl 已提交
1056
  OZ( resolve_group_clause(group_by) );
O
obdev 已提交
1057 1058 1059 1060 1061

  if (has_rollup && is_oracle_mode()) {
    expr_resv_ctx_.set_new_scope();
  }

O
oceanbase-admin 已提交
1062
  /* resolve having clause */
W
wangzelin.wzl 已提交
1063
  OZ( resolve_having_clause(having) );
O
oceanbase-admin 已提交
1064 1065 1066

  if (is_oracle_mode()) {
    // oracle resolve: from->where->connect by->group by->having->select_item->order by
W
wangzelin.wzl 已提交
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
    OZ( resolve_field_list(*(parse_tree.children_[PARSE_SELECT_SELECT])) );
  }
  OZ( resolve_order_clause(parse_tree.children_[PARSE_SELECT_ORDER]) );
  OZ( resolve_limit_clause(parse_tree.children_[PARSE_SELECT_LIMIT]) );
  OZ( resolve_fetch_clause(parse_tree.children_[PARSE_SELECT_FETCH]) );
  OZ( resolve_check_option_clause(parse_tree.children_[PARSE_SELECT_WITH_CHECK_OPTION]) );
  OZ( resolve_into_clause(ObResolverUtils::get_select_into_node(parse_tree)) );
  OZ( resolve_for_update_clause(parse_tree.children_[PARSE_SELECT_FOR_UPD]) );

  if (OB_SUCC(ret)) {
    bool has_flashback_query = false;
    //select for update要求stmt中任何一处都不能出现flashback query相关属性
    if (select_stmt->has_for_update() &&
        OB_FAIL(check_stmt_has_flashback_query(select_stmt, true, has_flashback_query))) {
      LOG_WARN("failed to check stmt has flashback query", K(ret));
    } else if (has_flashback_query) {
      ret = OB_ERR_FLASHBACK_QUERY_WITH_UPDATE;
      LOG_WARN("select for update and flashback query exists", K(ret));
    }
O
oceanbase-admin 已提交
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
  }

  if (OB_SUCC(ret) && select_stmt->has_for_update() && select_stmt->is_hierarchical_query()) {
    ret = OB_NOT_SUPPORTED;
    LOG_WARN("for update with hierarchical not support", K(ret));
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "for update with hierarchical");
  }

  if (OB_SUCC(ret) && has_top_limit_) {
    has_top_limit_ = false;
    select_stmt->set_has_top_limit(NULL != parse_tree.children_[PARSE_SELECT_LIMIT]);
  }
W
wangzelin.wzl 已提交
1098
  OZ( resolve_hints(parse_tree.children_[PARSE_SELECT_HINTS]) );
O
oceanbase-admin 已提交
1099

W
wangzelin.wzl 已提交
1100 1101 1102 1103
  //bug:https://work.aone.alibaba-inc.com/issue/28716121
  //由于支持mysql模式下的name window,需要提前解析name window保存下来,然后再解析引用的win expr的表达式,当前实现
  //方式是保存在select stmt中,但是在全部解析完之后没有把那些name window的对应win_expr去除掉,导致生成的计划有问题
  //因此,这里在全部解析完stmt各个部分之后需要根据之前记录的name winexpr个数去除stmt中无用的name win expr
O
oceanbase-admin 已提交
1104 1105
  if (OB_SUCC(ret) && count_name_win_expr > 0) {
    ObSEArray<ObWinFunRawExpr*, 4> new_win_func_exprs;
W
wangzelin.wzl 已提交
1106 1107 1108
    for (int64_t i = count_name_win_expr;
          OB_SUCC(ret) && i < select_stmt->get_window_func_count();
          ++i) {
O
oceanbase-admin 已提交
1109 1110
      if (OB_FAIL(new_win_func_exprs.push_back(select_stmt->get_window_func_expr(i)))) {
        LOG_WARN("failed to push back win exprs", K(ret));
W
wangzelin.wzl 已提交
1111
      } else {/*do nothing*/}
O
oceanbase-admin 已提交
1112 1113 1114 1115
    }
    if (OB_SUCC(ret)) {
      if (OB_FAIL(select_stmt->get_window_func_exprs().assign(new_win_func_exprs))) {
        LOG_WARN("failed to assign win exprs", K(ret));
W
wangzelin.wzl 已提交
1116
      } else { /*do nothing*/ }
O
oceanbase-admin 已提交
1117 1118 1119
    }
  }

W
wangzelin.wzl 已提交
1120
  OZ( select_stmt->formalize_stmt(session_info_) );
O
oceanbase-admin 已提交
1121

W
wangzelin.wzl 已提交
1122 1123 1124 1125 1126 1127 1128 1129
  //统一为本层的表达式进行only full group by验证,避免检查的逻辑过于分散
  OZ( check_field_list() );
  OZ( check_group_by() );
  OZ( check_order_by() );
  OZ( check_pseudo_columns() );
  OZ( check_window_exprs() );
  OZ( check_sequence_exprs() );
  OZ( check_unsupported_operation_in_recursive_branch() );
O
oceanbase-admin 已提交
1130
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
    //for topk, 在这里需要标示select 语句是否符合使用近似计算的要求,有group by,有order by且有limit
    //并且使用了topk的hint 且不是select for update 语句,且 from base table 且不需要calc found rows。
    //查询语句中没有distinct 且 查询中不涉及子查询
    //由于fetch clause利用limit设计,同时考虑到需要支持百分比及with ties功能,因此这里分配topn需要考虑这一情形
    if (select_stmt->get_query_ctx()->get_global_hint().is_topk_specified()
        && (1 == select_stmt->get_from_item_size())
        && (!select_stmt->is_calc_found_rows())
        && select_stmt->get_group_expr_size() > 0
        && !select_stmt->has_rollup()
        && select_stmt->get_window_func_exprs().empty()
        && select_stmt->has_order_by()
        && !select_stmt->has_sequence()
        && !select_stmt->has_select_into()
        && (select_stmt->has_limit() && !select_stmt->is_fetch_with_ties() &&
            select_stmt->get_limit_percent_expr() == NULL)
        && (!select_stmt->has_distinct())
        && (!select_stmt->has_subquery())) {
O
oceanbase-admin 已提交
1148
      const FromItem from_item = select_stmt->get_from_item(0);
W
wangzelin.wzl 已提交
1149
      TableItem *table_item = select_stmt->get_table_item_by_id(from_item.table_id_);
O
oceanbase-admin 已提交
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
      if (OB_ISNULL(table_item)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("got table item is NULL", K(from_item), K(ret));
      } else if (table_item->is_basic_table() && (!table_item->for_update_)) {
        select_stmt->set_match_topk(true);
      } else {
        select_stmt->set_match_topk(false);
      }
    }
  }

W
wangzelin.wzl 已提交
1161
  // rowscn伪列不能再flashback query和view中使用
O
oceanbase-admin 已提交
1162 1163
  if (OB_SUCC(ret)) {
    bool has_ora_rowscn = false;
W
wangzelin.wzl 已提交
1164
    const common::ObIArray<SelectItem> &items = select_stmt->get_select_items();
O
oceanbase-admin 已提交
1165 1166
    for (int64_t i = 0; i < items.count(); i++) {
      const SelectItem item = items.at(i);
W
wangzelin.wzl 已提交
1167 1168 1169
      if (nullptr != item.expr_
          && (item.expr_->has_flag(IS_ORA_ROWSCN_EXPR)
              || item.expr_->has_flag(CNT_ORA_ROWSCN_EXPR))) {
O
oceanbase-admin 已提交
1170 1171 1172
        has_ora_rowscn = true;
      }
    }
W
wangzelin.wzl 已提交
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188

    if (has_ora_rowscn) {
      bool has_flashback_query = false;
      if (OB_FAIL(check_stmt_has_flashback_query(select_stmt, false, has_flashback_query))) {
        LOG_WARN("failed to check stmt has flashback query", K(ret));
      } else if (has_flashback_query) {
        ret = OB_NOT_SUPPORTED;
        LOG_USER_ERROR(OB_NOT_SUPPORTED, "rowscn used with flashback query");
        LOG_WARN("rowscn can't use with flashback query", K(ret));
      }
    }
  }
  
  // add table_name for anonymous view(view in from)
  if (OB_SUCC(ret) && OB_FAIL(add_name_for_anonymous_view())) {
    LOG_WARN("fail to add name for anonymous view", K(ret));
O
oceanbase-admin 已提交
1189 1190 1191 1192
  }
  return ret;
}

W
wangzelin.wzl 已提交
1193
int ObSelectResolver::resolve(const ParseNode &parse_tree)
O
oceanbase-admin 已提交
1194 1195
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1196
  ObSelectStmt *select_stmt = NULL;
O
oceanbase-admin 已提交
1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229
  bool is_stack_overflow = false;
  if (NULL == (select_stmt = create_stmt<ObSelectStmt>())) {
    ret = OB_SQL_RESOLVER_NO_MEMORY;
    LOG_WARN("failed to create select stmt");
  } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("check stack overflow failed", K(ret), K(is_stack_overflow));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("too deep recursive", K(ret), K(is_stack_overflow));
  } else {
    if (OB_INVALID_TENANT_ID != params_.show_tenant_id_) {
      select_stmt->set_tenant_id(params_.show_tenant_id_);
    }
    select_stmt->set_show_seed(params_.show_seed_);
    /* -----------------------------------------------------------------
     * The later resolve may need some information resolved by the former one,
     * so please follow the resolving orders:
     *
     * 0. with clause
     * 1. set clause
     * 2. from clause
     * 3. start with clause
     * 4. connect by clause
     * 5. where clause
     * 6. select clause
     * 7. group by clause
     * 8. having clause
     * 9. order by clause
     * 10.limit clause
     * 11.fetch clause(oracle mode)
     * -----------------------------------------------------------------
     */

W
wangzelin.wzl 已提交
1230 1231 1232 1233 1234
    // resolve outline data hint first
    if (OB_FAIL(resolve_outline_data_hints())) {
      LOG_WARN("resolve outline data hints failed", K(ret));
    } else if (parse_tree.children_[PARSE_SELECT_SET] != NULL) {
      /* resolve set clause */
O
oceanbase-admin 已提交
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
      if (OB_FAIL(SMART_CALL(resolve_set_query(parse_tree)))) {
        LOG_WARN("resolve set query failed", K(ret));
      }
    } else {
      if (OB_FAIL(SMART_CALL(resolve_normal_query(parse_tree)))) {
        LOG_WARN("resolve normal query failed", K(ret));
      }
    }
  }

  return ret;
}

W
wangzelin.wzl 已提交
1248
int ObSelectResolver::resolve_query_options(const ParseNode *node)
O
oceanbase-admin 已提交
1249 1250 1251
{
  int ret = OB_SUCCESS;
  bool is_set_distinct = false;
W
wangzelin.wzl 已提交
1252
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
1253 1254 1255 1256
  if (OB_ISNULL(select_stmt)) {
    ret = OB_NOT_INIT;
    LOG_WARN("select stmt is null");
  } else if (NULL == node) {
W
wangzelin.wzl 已提交
1257
    //nothing to do
O
oceanbase-admin 已提交
1258 1259 1260 1261
  } else if (node->type_ != T_QEURY_EXPRESSION_LIST) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid argument", K(node->type_));
  } else {
W
wangzelin.wzl 已提交
1262
    ParseNode *option_node = NULL;
O
oceanbase-admin 已提交
1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
    for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++) {
      option_node = node->children_[i];
      if (option_node->type_ == T_DISTINCT) {
        is_set_distinct = true;
      } else if (option_node->type_ == T_FOUND_ROWS) {
        if (has_calc_found_rows_) {
          has_calc_found_rows_ = false;
          select_stmt->set_calc_found_rows(true);
        } else {
          ret = OB_ERR_CANT_USE_OPTION_HERE;
          LOG_USER_ERROR(OB_ERR_CANT_USE_OPTION_HERE, "SQL_CALC_FOUND_ROWS");
        }
      }
    }
  }
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
1279
    //默认为all
O
oceanbase-admin 已提交
1280 1281 1282 1283 1284 1285 1286 1287 1288
    if (is_set_distinct) {
      select_stmt->assign_distinct();
    } else {
      select_stmt->assign_all();
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
1289
int ObSelectResolver::resolve_for_update_clause(const ParseNode *node)
O
oceanbase-admin 已提交
1290 1291 1292 1293 1294
{
  int ret = OB_SUCCESS;
  if (NULL == node) {
    // do nothing
  } else if (is_oracle_mode()) {
W
wangzelin.wzl 已提交
1295
    OZ (resolve_for_update_clause_oracle(*node));
O
oceanbase-admin 已提交
1296
  } else {
W
wangzelin.wzl 已提交
1297
    OZ (resolve_for_update_clause_mysql(*node));
O
oceanbase-admin 已提交
1298 1299 1300 1301
  }
  return ret;
}

W
wangzelin.wzl 已提交
1302
int ObSelectResolver::resolve_for_update_clause_mysql(const ParseNode &node)
O
oceanbase-admin 已提交
1303 1304
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1305
  ObSelectStmt *select_stmt = NULL;
O
oceanbase-admin 已提交
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
  int64_t wait_us = -1;
  if (OB_ISNULL(select_stmt = get_select_stmt())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("fail to get select stmt", K(ret));
  } else if (T_SFU_INT != node.type_ && T_SFU_DECIMAL != node.type_) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("for update wait info is wrong", K(ret));
  } else if (T_SFU_INT == node.type_) {
    wait_us = node.value_ < 0 ? -1 : node.value_ * 1000000LL;
  } else if (T_SFU_DECIMAL == node.type_) {
    ObString time_str(node.str_len_, node.str_value_);
W
wangzelin.wzl 已提交
1317 1318
    if (OB_FAIL(ObTimeUtility2::str_to_time(
                  time_str, wait_us, ObTimeUtility2::DIGTS_SENSITIVE))) {
O
oceanbase-admin 已提交
1319 1320 1321 1322 1323 1324 1325 1326 1327
      LOG_WARN("str to time failed", K(ret));
    }
  }
  if (OB_SUCC(ret) && OB_FAIL(set_for_update_mysql(*select_stmt, wait_us))) {
    LOG_WARN("failed to set for update", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
1328
int ObSelectResolver::set_for_update_mysql(ObSelectStmt &stmt, const int64_t wait_us)
O
oceanbase-admin 已提交
1329 1330
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1331
  TableItem *table_item = NULL;
O
oceanbase-admin 已提交
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343
  for (int64_t idx = 0; OB_SUCC(ret) && idx < stmt.get_table_size(); ++idx) {
    if (OB_ISNULL(table_item = stmt.get_table_item(idx))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("Table item is NULL", K(ret));
    } else if (table_item->is_basic_table()) {
      table_item->for_update_ = true;
      table_item->for_update_wait_us_ = wait_us;
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
1344
int ObSelectResolver::resolve_for_update_clause_oracle(const ParseNode &node)
O
oceanbase-admin 已提交
1345 1346
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1347 1348 1349
  ObSelectStmt *stmt = NULL;
  const ParseNode *of_node = NULL;
  const ParseNode *wait_or_skip_node = NULL;
O
oceanbase-admin 已提交
1350
  int64_t wait_us = -1;
W
wangzelin.wzl 已提交
1351
  bool skip_locked = false;
O
oceanbase-admin 已提交
1352 1353 1354 1355
  current_scope_ = T_FIELD_LIST_SCOPE;
  if (current_level_ > 0) {
    ret = OB_ERR_PARSER_SYNTAX;
    LOG_WARN("for update is not allowed in subquery", K(ret));
W
wangzelin.wzl 已提交
1356 1357 1358 1359 1360
  } else if (OB_UNLIKELY(node.type_ != T_FOR_UPDATE) ||
             OB_UNLIKELY(node.num_child_ != 2) ||
             FALSE_IT(of_node = node.children_[0]) ||
             FALSE_IT(wait_or_skip_node = node.children_[1]) ||
             OB_ISNULL(stmt = get_select_stmt()) ||
O
oceanbase-admin 已提交
1361 1362 1363 1364
             OB_ISNULL(session_info_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("invalid for update parse node", K(ret), K(node.type_), K(node.num_child_), K(stmt));
  }
W
wangzelin.wzl 已提交
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383

  if (OB_SUCC(ret)) {
    if (NULL != wait_or_skip_node) {
      if (wait_or_skip_node->type_ == T_SKIP_LOCKED) {
        // skip locked
        skip_locked = true;
        wait_us = 0;
      } else if (wait_or_skip_node->type_ == T_SFU_INT) {
        // wait INTNUM or no wait
        // nowait  wait_us = 0;
        wait_us = wait_or_skip_node->value_ * 1000000LL;
        skip_locked = false;
      }
    } else {
      wait_us = -1;
      skip_locked = false;
    }
  }

O
oceanbase-admin 已提交
1384 1385
  if (OB_SUCC(ret) && NULL != of_node) {
    for (int64_t i = 0; OB_SUCC(ret) && i < of_node->num_child_; ++i) {
W
wangzelin.wzl 已提交
1386 1387
      const ParseNode *column_node = NULL;
      ObRawExpr *expr = NULL;
O
oceanbase-admin 已提交
1388 1389 1390 1391 1392 1393 1394 1395 1396
      if (OB_ISNULL(column_node = of_node->children_[i])) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("of node is null", K(ret));
      } else if (OB_FAIL(resolve_sql_expr(*column_node, expr))) {
        LOG_WARN("failed to resolve sql expr", K(ret));
      } else if (OB_ISNULL(expr) || OB_UNLIKELY(!expr->is_column_ref_expr())) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("expr is invalid", K(ret), K(expr));
      } else {
W
wangzelin.wzl 已提交
1397 1398
        ObColumnRefRawExpr *col = static_cast<ObColumnRefRawExpr*>(expr);
        if (OB_FAIL(set_for_update_oracle(*stmt, wait_us, skip_locked, col))) {
O
oceanbase-admin 已提交
1399 1400 1401 1402 1403 1404 1405 1406
          LOG_WARN("failed to set for update table", K(ret));
        } else if (OB_FAIL(stmt->get_for_update_columns().push_back(col))) {
          LOG_WARN("failed to push back lock column", K(ret));
        }
      }
    }
  }

W
wangzelin.wzl 已提交
1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448
  //如果是PL里的可更新游标,增加rowid属性
  if (OB_SUCC(ret) && ((NULL != params_.secondary_namespace_ && params_.is_cursor_)
                       || (session_info_->is_client_return_rowid()
                           && NULL == params_.secondary_namespace_))) {
    SelectItem rowid_item;
    ObSelectStmt *select_stmt = stmt;
    TableItem *table_item = NULL;
    TableItem *add_rowid_table_item = NULL;
    const ObTableSchema *table_schema = NULL;
    int64_t for_update_cnt = 0;
    CK (OB_NOT_NULL(params_.schema_checker_));
    for (int64_t i = 0; OB_SUCC(ret) && for_update_cnt <= 1 && i < select_stmt->get_table_size(); i++) {
      // 1. 单表的for update, 需要把表的rowid加入到 select_item中
      // 2. 多表join for update, 不能加入rowid,因为不确定要加哪个表的rowid
      // 3. 多表join for update of t1.c1, of 后面指定更新的表时,需要把指定的表的rowid加入到select_item中
      CK (OB_NOT_NULL(table_item = select_stmt->get_table_item(i)));
      if (OB_SUCC(ret) && (table_item->for_update_ || 1 == select_stmt->get_table_size())) {
        for_update_cnt++;
        if (for_update_cnt > 1) {
          add_rowid_table_item = NULL;
        } else if (table_item->is_basic_table()) {
          OX (add_rowid_table_item = table_item);
        }
      }
    }
    if (OB_SUCC(ret) && add_rowid_table_item != NULL) {
      ObRawExpr *rowid_expr = NULL;
      OZ (params_.schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), 
                                                    add_rowid_table_item->ref_id_,
                                                    table_schema,
                                                    add_rowid_table_item->is_link_table()));
      if (OB_FAIL(resolve_rowid_expr(select_stmt, *add_rowid_table_item, rowid_expr))) {
        LOG_WARN("resolve rowid expr failed", K(ret));
      } else {
        OX (rowid_item.expr_name_ = ObString(OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME));
        OX (rowid_item.alias_name_ = ObString(OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME));
        OX (rowid_item.expr_ = rowid_expr);
        OX (rowid_item.is_hidden_rowid_ = true);
        OZ (set_select_item(rowid_item, false/* is_auto_gen*/));
      }
    }
  }
O
oceanbase-admin 已提交
1449 1450
  if (OB_SUCC(ret) && NULL == of_node) {
    // lock all tables
W
wangzelin.wzl 已提交
1451
    if (OB_FAIL(set_for_update_oracle(*stmt, wait_us, skip_locked))) {
O
oceanbase-admin 已提交
1452 1453 1454
      LOG_WARN("failed to set for update", K(ret));
    }
  }
W
wangzelin.wzl 已提交
1455

O
oceanbase-admin 已提交
1456
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
1457 1458 1459
    if (is_in_set_query() ||
        stmt->has_group_by() ||
        stmt->has_distinct()) {
O
oceanbase-admin 已提交
1460 1461
      ret = OB_ERR_FOR_UPDATE_EXPR_NOT_ALLOWED;
      LOG_WARN("for update can not exists in stmt with distinct, group", K(ret));
W
wangzelin.wzl 已提交
1462
    } else if (stmt->has_fetch()) {//fetch 和 for update不能同时出现
O
oceanbase-admin 已提交
1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473
      ret = OB_ERR_FOR_UPDATE_SELECT_VIEW_CANNOT;
      LOG_WARN("for update stmt can't have fetch clause", K(ret));
    }
  }
  return ret;
}

/**
 * @brief ObSelectResolver::set_for_update_oracle
 * @param stmt: the targe stmt
 * @param wait_us: for update wait ts
W
wangzelin.wzl 已提交
1474
 * @param skip_locked: skip locked
O
oceanbase-admin 已提交
1475 1476 1477 1478
 * @param col: the column of table which should be locked,
 *             if col = NULL, all tables in the stmt should be locked
 * @return
 */
W
wangzelin.wzl 已提交
1479 1480 1481 1482
int ObSelectResolver::set_for_update_oracle(ObSelectStmt &stmt,
                                            const int64_t wait_us,
                                            bool skip_locked,
                                            ObColumnRefRawExpr *col)
O
oceanbase-admin 已提交
1483 1484 1485 1486 1487 1488
{
  int ret = OB_SUCCESS;
  if (stmt.is_set_stmt()) {
    ret = OB_ERR_FOR_UPDATE_SELECT_VIEW_CANNOT;
    LOG_WARN("invalid for update", K(ret));
  } else if (col != NULL && col->get_data_type() == ObURowIDType &&
W
wangzelin.wzl 已提交
1489
             ObCharset::case_insensitive_equal(to_cstring(col->get_column_name()), OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME)) {
O
oceanbase-admin 已提交
1490 1491 1492 1493 1494 1495
    ret = OB_NOT_SUPPORTED;
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "invalid user.table.column, table.column, or column specification");
    LOG_WARN("pseudo_column rowid is not supported for update", K(col->get_column_name()), K(col->get_data_type()));
  }

  for (int64_t i = 0; OB_SUCC(ret) && i < stmt.get_table_size(); ++i) {
W
wangzelin.wzl 已提交
1496
    TableItem *table = NULL;
O
oceanbase-admin 已提交
1497 1498 1499 1500 1501 1502 1503 1504
    if (OB_ISNULL(table = stmt.get_table_item(i))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("table item is null", K(ret));
    } else if (col != NULL && col->get_table_id() != table->table_id_) {
      // does not lock this table, skip here
    } else {
      table->for_update_ = true;
      table->for_update_wait_us_ = wait_us;
W
wangzelin.wzl 已提交
1505
      table->skip_locked_ = skip_locked;
O
oceanbase-admin 已提交
1506
      if (table->is_basic_table()) {
W
wangzelin.wzl 已提交
1507
        ObSEArray<ObColumnRefRawExpr *, 4> rowkeys;
O
oceanbase-admin 已提交
1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518
        if (OB_FAIL(add_all_rowkey_columns_to_stmt(*table, rowkeys, &stmt))) {
          LOG_WARN("failed to add rowkey columns to stmt", K(ret));
        }
        for (int64_t j = 0; OB_SUCC(ret) && j < rowkeys.count(); ++j) {
          if (OB_ISNULL(rowkeys.at(j))) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("rowkey expr is null", K(ret));
          } else {
            rowkeys.at(j)->set_explicited_reference();
          }
        }
W
wangzelin.wzl 已提交
1519 1520 1521
      } else if (table->is_generated_table() || table->is_temp_table()) {
        ObSelectStmt *view = NULL;
        ObColumnRefRawExpr *view_col = NULL;
O
oceanbase-admin 已提交
1522 1523 1524 1525 1526
        if (OB_ISNULL(view = table->ref_query_)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("view is invalid", K(ret), K(*table));
        } else if (NULL != col) {
          int64_t sel_id = col->get_column_id() - OB_APP_MIN_COLUMN_ID;
W
wangzelin.wzl 已提交
1527
          ObRawExpr *sel_expr = NULL;
O
oceanbase-admin 已提交
1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
          if (OB_UNLIKELY(sel_id < 0 || sel_id >= view->get_select_item_size()) ||
              OB_ISNULL(sel_expr = view->get_select_item(sel_id).expr_)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("column id is invalid", K(ret), K(*col), K(sel_expr));
          } else if (OB_UNLIKELY(!sel_expr->is_column_ref_expr())) {
            ret = OB_ERR_FOR_UPDATE_EXPR_NOT_ALLOWED;
            LOG_WARN("invalid for update", K(ret));
          } else {
            view_col = static_cast<ObColumnRefRawExpr*>(sel_expr);
          }
        }
W
wangzelin.wzl 已提交
1539
        if (OB_SUCC(ret) && OB_FAIL(set_for_update_oracle(*view, wait_us, skip_locked, view_col))) {
O
oceanbase-admin 已提交
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
          LOG_WARN("failed to set for update", K(ret));
        }
      }
    }
  }
  return ret;
}

// If expr is literal and type is numeric, then cast to int, find the referred select item
// special case:
// 1) negetive numeric value
//    select 1 from dual order by -0; --ok
//    select 1 from dual order by +0; --error
//    select 1 from dual order by -0E0;  --ok
//    select 1 from dual order by +0E0;  --error
// 2) value to floor
//    select c1 from t1 order by 1.3;  --ok
//    select c1 from t1 order by 1.9;  --ok
//    select c1 from t1 order by 2.3;  --error
//    select c1 from t1 order by 2.1;  --error
W
wangzelin.wzl 已提交
1560
int ObSelectResolver::resolve_literal_order_item(const ParseNode &sort_node, ObRawExpr *expr, OrderItem &order_item, ObSelectStmt *select_stmt)
O
oceanbase-admin 已提交
1561 1562 1563 1564
{
  int ret = OB_SUCCESS;
  if (!is_oracle_mode()) {
    // nothing to do
O
obdev 已提交
1565 1566
  } else if (T_OBJ_ACCESS_REF == sort_node.type_) {
    //do nothing
O
oceanbase-admin 已提交
1567 1568 1569
  } else if (OB_ISNULL(expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("expr is null", K(ret));
W
wangzelin.wzl 已提交
1570 1571
  } else if (expr->is_const_raw_expr()) {
    const ObObj &value = static_cast<ObConstRawExpr*>(expr)->get_value();
O
oceanbase-admin 已提交
1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609
    if (!value.is_numeric_type()) {
      // not numeric type
    } else if (sort_node.str_len_ > 0 && '-' == sort_node.str_value_[0]) {
      // skip negative value, like -0, -0E0
      LOG_DEBUG("sort node is negative", K(ret), K(sort_node.str_value_[0]), K(sort_node.str_len_), K(value));
    } else {
      // 1. cast to number. if be cast to int type, it will be round, it's unexpected, like 1.9 round to 2
      // 2. get int value
      ObObjMeta number_type;
      number_type.set_number();
      number_type.set_scale(NUMBER_SCALE_UNKNOWN_YET);
      int64_t pos = -1;
      int64_t scale = -1;
      ObObj number_obj;
      number::ObNumber number_value;
      const ObDataTypeCastParams dtc_params = ObBasicSessionInfo::create_dtc_params(session_info_);
      ObCastCtx cast_ctx(allocator_, &dtc_params, CM_NONE, ObCharset::get_system_collation());
      if (OB_FAIL(ObObjCaster::to_type(number_type.get_type(), cast_ctx, value, number_obj))) {
        LOG_WARN("fail to cast int object", K(ret), K(value));
      } else if (OB_FAIL(number_obj.get_number(number_value))) {
        LOG_WARN("fail to get number value", K(ret), K(value));
      } else if (number_value.is_negative()) {
        // if value < 0, then don't cast to int value
        // eg: select * from t1 order by -0.1; --it's ok
        // but select * from t1 order by 0.1; --it's error
        LOG_DEBUG("const value is negative", K(number_value));
      } else if (!number_value.is_int_parts_valid_int64(pos, scale)) {
        ret = OB_ERR_ORDER_BY_ITEM_NOT_IN_SELECT_LIST;
        LOG_WARN("value is invalid", K(ret), K(number_value), K(value));
      } else if (OB_FAIL(resolve_order_item_by_pos(pos, order_item, select_stmt))) {
        LOG_WARN("fail to get order item", K(ret));
      }
      LOG_DEBUG("sort node", K(ret), K(sort_node.str_value_[0]), K(sort_node.str_len_), K(value));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
1610
int ObSelectResolver::resolve_order_item_by_pos(int64_t pos, OrderItem &order_item, ObSelectStmt *select_stmt)
O
oceanbase-admin 已提交
1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
{
  int ret = OB_SUCCESS;
  if (pos <= 0 || pos > select_stmt->get_select_item_size()) {
    // for SELECT statement, we need to make sure the column positions are valid
    if (is_oracle_mode()) {
      ret = OB_ERR_ORDER_BY_ITEM_NOT_IN_SELECT_LIST;
      LOG_WARN("ORDER BY item must be the number of a SELECT-list expression", K(ret), K(pos));
    } else {
      ret = OB_ERR_BAD_FIELD_ERROR;
      char buff[OB_MAX_ERROR_MSG_LEN];
      snprintf(buff, OB_MAX_ERROR_MSG_LEN, "%d", static_cast<int32_t>(pos));
      ObString scope_name = ObString::make_string(get_scope_name(current_scope_));
      LOG_USER_ERROR(OB_ERR_BAD_FIELD_ERROR, (int)strlen(buff), buff, scope_name.length(), scope_name.ptr());
    }
  } else {
    // create expression
W
wangzelin.wzl 已提交
1627
    const SelectItem &select_item = select_stmt->get_select_item(pos - 1);
O
oceanbase-admin 已提交
1628 1629 1630 1631 1632
    order_item.expr_ = select_item.expr_;
  }
  return ret;
}

W
wangzelin.wzl 已提交
1633
int ObSelectResolver::resolve_order_item(const ParseNode &sort_node, OrderItem &order_item)
O
oceanbase-admin 已提交
1634 1635
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1636
  ObSelectStmt *select_stmt = NULL;
O
oceanbase-admin 已提交
1637 1638 1639 1640 1641
  if (OB_ISNULL(select_stmt = get_select_stmt())) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("got an unexpected null", K(ret));
  } else if (OB_FAIL(ObResolverUtils::set_direction_by_mode(sort_node, order_item))) {
    LOG_WARN("failed to set order type by mode", K(ret));
W
wangzelin.wzl 已提交
1642 1643
  } else if (!is_oracle_mode()
             && OB_UNLIKELY(sort_node.children_[0]->type_ == T_INT && sort_node.children_[0]->value_ >= 0)) {
O
oceanbase-admin 已提交
1644 1645 1646 1647 1648 1649
    // The order-by item is specified using column position
    // ie. ORDER BY 1 DESC
    int32_t pos = static_cast<int32_t>(sort_node.children_[0]->value_);
    if (OB_FAIL(resolve_order_item_by_pos(pos, order_item, select_stmt))) {
      LOG_WARN("fail to get order item", K(ret));
    }
W
wangzelin.wzl 已提交
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
  } else if (params_.is_prepare_protocol_ 
             && !params_.is_prepare_stage_
             && sort_node.children_[0]->type_ == T_QUESTIONMARK) {
    ObRawExpr *null_expr = NULL;
    if (OB_ISNULL(params_.expr_factory_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("params is invalid", K(params_.expr_factory_));
    } else if (OB_FAIL(ObRawExprUtils::build_null_expr(*params_.expr_factory_, null_expr))) {
      LOG_WARN("fail to build null expr", K(ret));
    } else {
      order_item.expr_ = null_expr;
    }
  } else if (T_QUESTIONMARK == sort_node.children_[0]->type_ && !params_.is_prepare_protocol_) {
O
oceanbase-admin 已提交
1663 1664 1665 1666 1667 1668 1669
    ret = OB_ERR_PARSE_SQL;
    LOG_WARN("'?' can't after 'order by", K(ret));
  } else {
    if (is_oracle_mode()) {
      field_list_first_ = true;
    }
    if (OB_FAIL(resolve_sql_expr(*(sort_node.children_[0]), order_item.expr_))) {
W
wangzelin.wzl 已提交
1670
       LOG_WARN("resolve sql expression failed", K(ret));
M
my0 已提交
1671
    } else if (OB_FAIL(resolve_literal_order_item(*(sort_node.children_[0]), order_item.expr_, order_item, select_stmt))) {
W
wangzelin.wzl 已提交
1672 1673
      LOG_WARN("fail to resolve literal order item", K(ret), K(*order_item.expr_));
    } else { }
O
oceanbase-admin 已提交
1674 1675 1676 1677 1678 1679 1680
  }
  if (OB_SUCC(ret) && is_only_full_group_by_on(session_info_->get_sql_mode())) {
    if (OB_FAIL(standard_group_checker_.add_unsettled_expr(order_item.expr_))) {
      LOG_WARN("add unsettled expr to standard group checker failed", K(ret));
    }
  }

W
wangzelin.wzl 已提交
1681 1682
  //oracle mode, check set query order by item
  if (OB_SUCC(ret) && select_stmt->is_set_stmt() && is_oracle_mode()) {
O
oceanbase-admin 已提交
1683 1684 1685
    ObSEArray<ObRawExpr*, 4> select_exprs;
    if (OB_FAIL(select_stmt->get_select_exprs(select_exprs))) {
      LOG_WARN("failed to get select exprs", K(ret));
1686
    } else if (ObOptimizerUtil::find_item(select_exprs, order_item.expr_)) {
O
oceanbase-admin 已提交
1687 1688 1689 1690 1691 1692 1693 1694 1695
      /*do nothing*/
    } else {
      ret = OB_ERR_ORDER_BY_ITEM_NOT_IN_SELECT_LIST;
      LOG_WARN("ORDER BY item must be the number of a SELECT-list expression", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
1696
int ObSelectResolver::resolve_field_list(const ParseNode &node)
O
oceanbase-admin 已提交
1697 1698
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
1699 1700
  ParseNode *project_node = NULL;
  ParseNode *alias_node = NULL;
O
oceanbase-admin 已提交
1701
  bool is_bald_star = false;
W
wangzelin.wzl 已提交
1702 1703
  ObSelectStmt *select_stmt = NULL;
  //LOG_INFO("resolve_select_1", "usec", ObSQLUtils::get_usec());
O
oceanbase-admin 已提交
1704 1705 1706
  current_scope_ = T_FIELD_LIST_SCOPE;
  if (OB_ISNULL(session_info_) || OB_ISNULL(select_stmt = get_select_stmt())) {
    ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
1707 1708
    LOG_WARN("get unexpected null", K(session_info_),
        K(select_stmt), K(ret));
O
oceanbase-admin 已提交
1709 1710 1711 1712 1713 1714 1715 1716 1717
  }
  for (int32_t i = 0; OB_SUCC(ret) && i < node.num_child_; ++i) {
    alias_node = NULL;
    project_node = NULL;
    SelectItem select_item;
    // Rule for expr_name and alias_name
    // expr_name is filled with expr name, both ref_expr and other complex expr.
    // alias_name is filled with expr_name for default, but updated with real alias name if exists.
    // the special case is the column ref, which expr_name will be replaced with unqualified column name.
W
wangzelin.wzl 已提交
1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744
    select_item.expr_name_.assign_ptr(node.children_[i]->str_value_,
                                      static_cast<int32_t>(node.children_[i]->str_len_));
    // In Oracle ps mode, the alias name of the bind variable is ":" + num, not the actual value. As follows:
    // PREPARE STMT FROM 'SELECT ?, ?, ? FROM DUAL';
    // SET @I1 = 1;
    // EXECUTE STMT USING @I1, @I1, @I1;
    // col_name1 is ":1", col_name2 is ":2", col_name3 is ":3"
    if (is_oracle_mode()
        && params_.is_prepare_protocol_
        && 1 == node.children_[i]->num_child_
        && T_QUESTIONMARK == node.children_[i]->children_[0]->type_) {
      ObString alias_name;
      char temp_str_buf[OB_MAX_COLUMN_NAME_LENGTH];
      if (snprintf(temp_str_buf, sizeof(temp_str_buf), ":%ld", node.children_[i]->children_[0]->value_ + 1) < 0) {
        ret = OB_SIZE_OVERFLOW;
        LOG_WARN("failed to generate buffer for temp_str_buf", K(ret));
      }
      if (OB_SUCC(ret)) {
        alias_name = ObString::make_string(temp_str_buf);
        if (OB_FAIL(ob_write_string(*allocator_, alias_name, select_item.alias_name_))) {
          LOG_WARN("Can not malloc space for alias name", K(ret));
        }
      }
    } else {
      select_item.alias_name_.assign_ptr(node.children_[i]->str_value_,
                                      static_cast<int32_t>(node.children_[i]->str_len_));
    }
O
oceanbase-admin 已提交
1745 1746

    project_node = node.children_[i]->children_[0];
W
wangzelin.wzl 已提交
1747 1748
    if (project_node->type_ == T_STAR
        || (project_node->type_ == T_COLUMN_REF && project_node->children_[2]->type_ == T_STAR)) {
O
oceanbase-admin 已提交
1749 1750 1751 1752 1753 1754 1755 1756 1757
      if (project_node->type_ == T_STAR) {
        if (is_bald_star) {
          ret = OB_ERR_STAR_DUPLICATE;
          LOG_WARN("Wrong usage of '*'");
          break;
        } else {
          is_bald_star = true;
        }
      }
W
wangzelin.wzl 已提交
1758 1759 1760 1761
      //oracle不允许有同表名的基表时select item引用其列,比如:
      //select * from t1,t1 ==> NO
      //select 1 from t1,t1 ==> YES
      //select * from (select * from t1), (select * from t1) ==> YES
O
oceanbase-admin 已提交
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
      if (OB_FAIL(ret)) {
      } else if (params_.have_same_table_name_) {
        ret = OB_NON_UNIQ_ERROR;
        LOG_WARN("column in all tables is ambiguous", K(ret));
      } else if (OB_FAIL(resolve_star(project_node))) {
        LOG_WARN("resolve star failed", K(ret));
      }
      continue;
    }
    if (OB_SUCC(ret)) {
      if (OB_FAIL(ObCharset::charset_convert(*allocator_,
W
wangzelin.wzl 已提交
1773 1774 1775 1776 1777
                                             select_item.expr_name_,
                                             session_info_->get_local_collation_connection(),
                                             CS_TYPE_UTF8MB4_BIN,
                                             select_item.expr_name_,
                                             ObCharset::REPLACE_UNKNOWN_CHARACTER))) {
O
oceanbase-admin 已提交
1778 1779
        LOG_WARN("fail to charset convert", K(ret));
      } else if (OB_FAIL(ObCharset::charset_convert(*allocator_,
W
wangzelin.wzl 已提交
1780 1781 1782 1783 1784
                                                    select_item.alias_name_,
                                                    session_info_->get_local_collation_connection(),
                                                    CS_TYPE_UTF8MB4_BIN,
                                                    select_item.alias_name_,
                                                    ObCharset::REPLACE_UNKNOWN_CHARACTER))) {
O
oceanbase-admin 已提交
1785 1786 1787 1788 1789
        LOG_WARN("fail to charset convert", K(ret));
      }
    }
    bool is_auto_gen = false;
    if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
1790
      //处理alias
O
oceanbase-admin 已提交
1791 1792 1793 1794 1795 1796 1797 1798
      ObCollationType cs_type = CS_TYPE_INVALID;
      if (OB_FAIL(session_info_->get_collation_connection(cs_type))) {
        LOG_WARN("fail to get collation_connection", K(ret));
      } else if (project_node->type_ == T_ALIAS) {
        alias_node = project_node->children_[1];
        project_node = project_node->children_[0];
        select_item.is_real_alias_ = true;
        /* check if the alias name is legal */
W
wangzelin.wzl 已提交
1799 1800
        select_item.alias_name_.assign_ptr(const_cast<char *>(alias_node->str_value_),
                                           static_cast<int32_t>(alias_node->str_len_));
O
oceanbase-admin 已提交
1801 1802 1803 1804
        if (OB_UNLIKELY(alias_node->str_len_ > OB_MAX_COLUMN_NAME_LENGTH && is_oracle_mode())) {
          ret = OB_ERR_TOO_LONG_IDENT;
          LOG_WARN("alias name too long", K(ret), K(select_item.alias_name_));
        }
O
obdev 已提交
1805
      } else if (OB_UNLIKELY((params_.is_from_create_view_ || params_.is_from_create_table_)
W
wangt1xiuyi 已提交
1806
                             && !params_.is_specified_col_name_
W
wangzelin.wzl 已提交
1807 1808
                             && 0 == select_item.expr_name_.case_compare(
                                     OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME))) {
O
oceanbase-admin 已提交
1809 1810 1811 1812
        // must name alias for rowid
        //  eg: create view/table as select rowid from t1;
        ret = OB_NO_COLUMN_ALIAS;
        LOG_WARN("no column alias for rowid pseudo column", K(ret));
W
wangzelin.wzl 已提交
1813 1814
        LOG_USER_ERROR(OB_NO_COLUMN_ALIAS, select_item.expr_name_.length(),
                       select_item.expr_name_.ptr());
O
oceanbase-admin 已提交
1815 1816 1817 1818
      }
    }

    if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
1819
      ObRawExpr *sel_expr = NULL;
O
oceanbase-admin 已提交
1820 1821
      if (OB_FAIL(resolve_sql_expr(*project_node, select_item.expr_))) {
        LOG_WARN("resolve sql expr failed", K(ret));
W
wangzelin.wzl 已提交
1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
        if (OB_EER_WINDOW_NO_REDEFINE_ORDER_BY == ret
            && OB_NOT_NULL(project_node)
            && OB_NOT_NULL(project_node->children_[1])
            && OB_NOT_NULL(project_node->children_[1]->children_[0])) {
          LOG_USER_ERROR(OB_EER_WINDOW_NO_REDEFINE_ORDER_BY,
              (int)strlen("<unnamed window>"), "<unnamed window>",
              (int)(project_node->children_[1]->children_[0]->str_len_),
              project_node->children_[1]->children_[0]->str_value_);
        }
      } else if (OB_ISNULL(sel_expr = select_item.expr_)) {
O
oceanbase-admin 已提交
1832 1833
        ret = OB_NOT_INIT;
        LOG_WARN("select expr is null", K(select_item), K(ret));
W
wangzelin.wzl 已提交
1834 1835 1836 1837 1838 1839 1840 1841 1842
      } else if (sel_expr->is_exec_param_expr()) {
        sel_expr = static_cast<ObExecParamRawExpr *>(sel_expr)->get_ref_expr();
        if (OB_ISNULL(sel_expr)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("select expr is null", K(ret));
        }
      }

      if (OB_SUCC(ret) && NULL == alias_node) {
O
oceanbase-admin 已提交
1843
        LOG_DEBUG("select item info", K(select_item));
W
wangzelin.wzl 已提交
1844
        if (sel_expr->is_column_ref_expr()) {
O
oceanbase-admin 已提交
1845 1846 1847
          // for t1.c1, extract the exact column name of c1 for searching in resolve_columns
          if (project_node->type_ == T_COLUMN_REF) {
            alias_node = project_node->children_[2];
W
wangzelin.wzl 已提交
1848 1849
            select_item.alias_name_.assign_ptr(const_cast<char *>(alias_node->str_value_),
                                               static_cast<int32_t>(alias_node->str_len_));
O
oceanbase-admin 已提交
1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
          } else if (T_OBJ_ACCESS_REF == project_node->type_) {
            while (NULL != project_node->children_[1]) {
              project_node = project_node->children_[1];
            }
            if (T_OBJ_ACCESS_REF != project_node->type_) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("unexpected select item type", K(select_item), K(ret));
            } else {
              alias_node = project_node->children_[0];
              /* bugfix: table has fbi index, select fbi_expr, alias name is empty
              create table t1(c1 number,c2 number);
              create index t1_g_idx on t1(ceil(c1)) global;
              select ceil(c1),ceil(c2) from t1;
              +------+----------+
W
wangzelin.wzl 已提交
1864
              |      | CEIL(C2) |   -----》 not display CEIL(C1) COLUM NAME
O
oceanbase-admin 已提交
1865 1866 1867 1868 1869
              +------+----------+
              |    4 |        5 |
              +------+----------+
              */
              if (alias_node->str_len_ > 0) {
W
wangzelin.wzl 已提交
1870 1871
                select_item.alias_name_.assign_ptr(const_cast<char *>(alias_node->str_value_),
                                                   static_cast<int32_t>(alias_node->str_len_));
O
oceanbase-admin 已提交
1872 1873
              }
            }
W
wangzelin.wzl 已提交
1874
          } else if (T_REF_COLUMN == sel_expr->get_expr_type()) {
O
oceanbase-admin 已提交
1875
            // deal with generated column
W
wangzelin.wzl 已提交
1876
            ObColumnRefRawExpr *ref_expr = dynamic_cast<ObColumnRefRawExpr *>(sel_expr);
O
oceanbase-admin 已提交
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886
            if (OB_ISNULL(ref_expr)) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("got an unexpected null", K(ret));
            } else {
              select_item.alias_name_ = ref_expr->get_column_name();
            }
          } else {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("unexpected select item type", K(select_item), K(ret));
          }
W
wangzelin.wzl 已提交
1887
        } else if (T_FUN_SYS_SEQ_NEXTVAL == sel_expr->get_expr_type()) {
O
oceanbase-admin 已提交
1888 1889
          // sequence expr, expr is seq_name.nextval or seq_name.currval
          // but column name displayed should be nextval or currval
W
wangzelin.wzl 已提交
1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916
          do {
            if (T_OP_POS == project_node->type_) {
              project_node = project_node->children_[0];
            } else if (T_EXPR_LIST == project_node->type_) {
              project_node = project_node->children_[0];
            } else {
              break;
            }
          } while (true);
          if (is_oracle_mode()) {
            if (T_OBJ_ACCESS_REF != project_node->type_) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("unexpected select item type", K(select_item), K(project_node->type_), K(ret));
            }
            while (OB_SUCC(ret) && NULL != project_node->children_[1]) {
              project_node = project_node->children_[1];
            }
            if (OB_FAIL(ret)) {
              // do nothing
            } else if (T_OBJ_ACCESS_REF != project_node->type_) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("unexpected select item type", K(select_item), K(project_node->type_), K(ret));
            } else {
              alias_node = project_node->children_[0];
              select_item.alias_name_.assign_ptr(const_cast<char *>(alias_node->str_value_),
                                                 static_cast<int32_t>(alias_node->str_len_));
            }
O
oceanbase-admin 已提交
1917
          } else {
W
wangzelin.wzl 已提交
1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932
            // mysql mode
            if (T_COLUMN_REF != project_node->type_ || project_node->num_child_ < 3) {
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("unexpected select item type",
                       K(select_item), K(project_node->type_), K(project_node->num_child_), K(ret));
            } else {
              alias_node = project_node->children_[2];
              select_item.alias_name_.assign_ptr(const_cast<char *>(alias_node->str_value_),
                                                 static_cast<int32_t>(alias_node->str_len_));
            }
          }
        } else if (T_FUN_SYS_CALC_UROWID == sel_expr->get_expr_type()) {
          ObString rowid_name(OB_HIDDEN_LOGICAL_ROWID_COLUMN_NAME);
          if (OB_FAIL(ob_write_string(*allocator_, rowid_name, select_item.alias_name_))) {
            LOG_WARN("failed to ob write string", K(ret));
O
oceanbase-admin 已提交
1933
          }
O
obdev 已提交
1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
        }  else if (T_FUN_SYS_NAME_CONST == sel_expr->get_expr_type()) {
          const ParseNode *expr_list_node = project_node->children_[1];
          const ObRawExpr *name_expr = nullptr;
          if (2 != expr_list_node->num_child_) {
            //do nothing
          } else if (OB_ISNULL(name_expr = sel_expr->get_param_expr(0))) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("unexpected null", K(ret), K(name_expr));
          } else if (name_expr->is_const_raw_expr() && T_QUESTIONMARK != name_expr->get_expr_type()) {
            char buf[OB_MAX_ALIAS_NAME_LENGTH + 1];
            int64_t pos = 0;
            const ObObj &value = static_cast<const ObConstRawExpr*>(name_expr)->get_value();
            if (value.is_numeric_type()){
              const ParseNode *alias_node = expr_list_node->children_[0];
              if (OB_ISNULL(alias_node)) {
                ret = OB_ERR_UNEXPECTED;
                LOG_WARN("unexpected null", K(ret));
              } else if (alias_node->str_len_ > 0 && '-' == alias_node->str_value_[0]) {
                ret = OB_INVALID_ARGUMENT;
                LOG_USER_ERROR(OB_INVALID_ARGUMENT, N_NAME_CONST);
                LOG_WARN("the first param of name_const can't be negtive", K(ret));
              } else if (OB_FAIL(value.print_sql_literal(buf, OB_MAX_ALIAS_NAME_LENGTH + 1, pos))) {
                LOG_WARN("fail to print_sql_literal", K(value), K(ret));
              }
            } else if (value.is_string_type()) {
              const ParseNode *alias_node = expr_list_node->children_[0];
              if (OB_ISNULL(alias_node)) {
                ret = OB_ERR_UNEXPECTED;
                LOG_WARN("unexpected null", K(ret));
              } else if ((pos = alias_node->str_len_) > 0) {
                if (pos > OB_MAX_ALIAS_NAME_LENGTH + 1) {
                  pos = OB_MAX_ALIAS_NAME_LENGTH + 1;
                }
                MEMCPY(buf, alias_node->str_value_, pos);
              }
            } else if (value.is_temporal_type()) {
              char time_buf[31];
              if (OB_FAIL(value.print_sql_literal(time_buf, OB_MAX_ALIAS_NAME_LENGTH + 1, pos))) {
                LOG_WARN("fail to print_plain_str_literal", K(value), K(ret));
              } else if (pos < 2 || pos > 31) {
                ret = OB_ERR_UNEXPECTED;
                LOG_WARN("length of time sting is not valid", K(ret));
              } else {
                MEMCPY(buf, time_buf + 1, pos - 2);
                pos = pos - 2;
              }
            } else if (OB_FAIL(value.print_sql_literal(buf, OB_MAX_ALIAS_NAME_LENGTH + 1, pos))) {
              LOG_WARN("fail to print_sql_literal", K(value), K(ret));
            }
            if (OB_SUCC(ret)) {
              ObString name_str(pos, buf);
              if (OB_FAIL(ObSQLUtils::make_field_name(name_str.ptr(),
                                                      static_cast<const int64_t>(name_str.length()),
                                                      CS_TYPE_UTF8MB4_GENERAL_CI,
                                                      allocator_,
                                                      name_str))) {
                LOG_WARN("fail to copy column alias name", K(name_str), K(ret));
              } else if (OB_FAIL(ob_write_string(*allocator_, name_str, select_item.alias_name_))) {
                LOG_WARN("failed to ob write string", K(ret));
              }
            }
          } else if (T_FUN_SYS_VERSION == name_expr->get_expr_type()) {
            ObString version;
            if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VERSION, version))) {
              LOG_WARN("fail to get version", K(ret));
            } else if (OB_FAIL(ob_write_string(*allocator_, version, select_item.alias_name_))) {
              LOG_WARN("failed to ob write string", K(ret));
            }
          } else if (T_FUN_SYS_OB_VERSION == name_expr->get_expr_type()) {
            if (OB_FAIL(ob_write_string(*allocator_, common::ObString(PACKAGE_VERSION), select_item.alias_name_))) {
              LOG_WARN("failed to ob write string", K(ret));
            }
          } else if (T_FUN_SYS_ICU_VERSION == name_expr->get_expr_type()) {
            if (OB_FAIL(ob_write_string(*allocator_,
                                        common::ObString(ObExprRegexContext::icu_version_string()),
                                        select_item.alias_name_))) {
              LOG_WARN("failed to ob write string", K(ret));
            }
          } else {
            //invalid name, do nothing
          }
2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033
        } else if (is_oracle_mode()
                    && T_QUESTIONMARK == sel_expr->get_expr_type()
                    && T_OBJ_ACCESS_REF == project_node->type_) {
          while (OB_SUCC(ret) && NULL != project_node->children_[1]) {
            project_node = project_node->children_[1];
          }
          if (OB_FAIL(ret)) {
          } else if (T_OBJ_ACCESS_REF != project_node->type_) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("unexpected select item type", K(select_item), K(project_node->type_), K(ret));
          } else {
            alias_node = project_node->children_[0];
            select_item.alias_name_.assign_ptr(const_cast<char *>(alias_node->str_value_),
                                                static_cast<int32_t>(alias_node->str_len_));
            if (OB_UNLIKELY(alias_node->str_len_ > OB_MAX_COLUMN_NAME_LENGTH)) {
              ret = OB_ERR_TOO_LONG_IDENT;
              LOG_WARN("alias name too long", K(ret), K(select_item.alias_name_));
            }
          }
O
oceanbase-admin 已提交
2034
        } else {
W
wangzelin.wzl 已提交
2035 2036 2037 2038
          if (params_.is_prepare_protocol_
              || !session_info_->get_local_ob_enable_plan_cache()
              || 0 == node.children_[i]->is_val_paramed_item_idx_) {
            // ps 不参数化列; plan cache关闭后不参数化列
O
oceanbase-admin 已提交
2039 2040 2041 2042 2043 2044 2045
            // do nothing
          } else if (OB_ISNULL(params_.select_item_param_infos_) ||
                     node.children_[i]->value_ >= params_.select_item_param_infos_->count()) {
            ret = OB_INVALID_ARGUMENT;
            LOG_WARN("invalid argument", K(params_.select_item_param_infos_));
          } else {
            int64_t idx = node.children_[i]->value_;
W
wangzelin.wzl 已提交
2046
            const SelectItemParamInfo &param_info = params_.select_item_param_infos_->at(idx);
O
oceanbase-admin 已提交
2047 2048 2049 2050 2051 2052 2053 2054 2055 2056
            select_item.paramed_alias_name_.assign_ptr(param_info.paramed_field_name_, param_info.name_len_);
            if (OB_FAIL(select_item.questions_pos_.assign(param_info.questions_pos_))) {
              LOG_WARN("failed to assign array", K(ret));
            } else if (OB_FAIL(select_item.params_idx_.assign(param_info.params_idx_))) {
              LOG_WARN("failed to assign array", K(ret));
            } else {
              select_item.esc_str_flag_ = param_info.esc_str_flag_;
              select_item.neg_param_idx_ = param_info.neg_params_idx_;

              LOG_DEBUG("select item param info",
W
wangzelin.wzl 已提交
2057 2058 2059 2060
                        K(select_item.alias_name_), K(select_item.params_idx_),
                        K(select_item.paramed_alias_name_),
                        K(select_item.esc_str_flag_), K(select_item.questions_pos_),
                        K(select_item), K(((ObDMLStmt *)stmt_)->get_column_items()));
O
oceanbase-admin 已提交
2061 2062 2063 2064 2065 2066
            }
          }
          is_auto_gen = true;
        }
      }

W
wangzelin.wzl 已提交
2067 2068
      if (OB_SUCC(ret) && is_oracle_mode() && sel_expr->has_flag(CNT_SUB_QUERY)) {
        if (OB_FAIL(check_subquery_return_one_column(*sel_expr))) {
O
oceanbase-admin 已提交
2069 2070 2071 2072
          LOG_WARN("failed to check subquery return one column", K(ret));
        }
      }

W
wangzelin.wzl 已提交
2073 2074 2075 2076 2077 2078 2079 2080 2081
      // 如果 select field list 表达式中包含了 sequence,则需要判断当前
      // select 语句是否为子查询,或者是否为 set 语句
      // **例外**:insert into select xxxx 的情景下,允许 sequence
      if (OB_SUCC(ret) && sel_expr->has_flag(CNT_SEQ_EXPR)) {
        if (in_set_query_ ||
            (params_.resolver_scope_stmt_type_ == ObItemType::T_INSERT  && current_level_ != 0) ||
            (params_.resolver_scope_stmt_type_ != ObItemType::T_INSERT  && (current_level_ > 1 || is_substmt()))) {
          // 对于 from (select xxxx) a 的场景,a 这个子查询的 current_level_ 和上一级相同,
          // 但设置了 parent namespace,故而还是可以加以区分
O
oceanbase-admin 已提交
2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108
          ret = OB_ERR_SEQ_NOT_ALLOWED_HERE;
        }
      }
    }

    // for unqualified column, if current stmt exists joined table with using,
    // it's determined by join type.
    // select c1 from t1 left join t2 using(c1) right join t3 using(c1) => c1 is t3.c1
    // select t2.c1 from t1 left join t2 using(c1) right join t3 using(c1) => c1 is t2.c1
    // select c1 from t1 left join t2 using(c1) right join t3 using(c1),
    //                t3 t left join t4 using(c1) right join t5 using(c1); ==> ambiguious
    if (OB_FAIL(ret)) {
      /*do nothing*/
    } else if (OB_FAIL(set_select_item(select_item, is_auto_gen))) {
      // construct select item from select_expr
      LOG_WARN("set select item failed", K(ret));
    } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
      if (OB_FAIL(standard_group_checker_.add_unsettled_expr(select_item.expr_))) {
        LOG_WARN("add unsettled expr to standard group checker failed", K(ret));
      }
    }

    // for oracle mode, check grouping here
    if (OB_FAIL(ret) || !is_oracle_mode()) {
      /*do nothing*/
    } else if (OB_FAIL(recursive_check_grouping_columns(select_stmt, select_item.expr_))) {
      LOG_WARN("failed to recursive check grouping columns", K(ret));
W
wangzelin.wzl 已提交
2109
    } else {/*do nothing*/}
2110
    // add for cte:
W
wangzelin.wzl 已提交
2111
    if (OB_SUCC(ret) && !is_oracle_mode() && !params_.has_cte_param_list_) {
2112 2113 2114 2115
      if (OB_FAIL(cte_ctx_.cte_col_names_.push_back(select_item.alias_name_))) {
        LOG_WARN("push back column alia name failed", K(ret));
      }
    }
W
wangzelin.wzl 已提交
2116
  } // end for
O
oceanbase-admin 已提交
2117

O
obdev 已提交
2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145
  if (OB_SUCC(ret) && has_nested_aggr_) {
    ObIArray<SelectItem> &select_items = select_stmt->get_select_items();
    for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); i++) {
      if (OB_ISNULL(select_items.at(i).expr_)) {
        ret = OB_INVALID_ARGUMENT;
        LOG_WARN("invalid expr in select items.", K(ret));
        //compatible oracle: select 1, sum(max(c1)) from t1 group by c1;
      } else if (select_items.at(i).expr_->is_const_expr()) {
        //do nothing
      } else if (!select_items.at(i).expr_->has_flag(CNT_AGG)) {
        //in oracle it's "not a single-group group function."
        ret = OB_ERR_WRONG_FIELD_WITH_GROUP;
        ObString column_name = select_items.at(i).is_real_alias_ ?
              select_items.at(i).alias_name_ :
              select_items.at(i).expr_name_;
        LOG_USER_ERROR(OB_ERR_WRONG_FIELD_WITH_GROUP,
                       column_name.length(),
                       column_name.ptr());
      } else { /*do nothing.*/ }
    }
    if (OB_SUCC(ret)) {
      if (select_stmt->get_group_expr_size() == 0 &&
          select_stmt->get_rollup_expr_size() == 0 &&
          select_stmt->get_grouping_sets_items_size() == 0 &&
          select_stmt->get_multi_rollup_items_size() == 0) {
        ret = OB_NOT_SUPPORTED;
        LOG_WARN("nested group function without group by", K(ret));
        LOG_USER_ERROR(OB_NOT_SUPPORTED, "nested group function without group by");
O
oceanbase-admin 已提交
2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160
      }
    }
  }

  if (OB_SUCC(ret)) {
    // Oracle mode, * can't be used with other expresion
    // like: select 1,* from t1; select *,1 from t1;
    if (is_oracle_mode() && is_bald_star && node.num_child_ > 1) {
      ret = OB_ERR_PARSE_SQL;
      LOG_WARN("star can't be used with other expression", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
2161 2162
int ObSelectResolver::expand_target_list(
  const TableItem &table_item, ObIArray<SelectItem> &target_list)
O
oceanbase-admin 已提交
2163 2164 2165
{
  int ret = OB_SUCCESS;
  ObArray<ColumnItem> column_items;
O
obdev 已提交
2166
  if (table_item.is_basic_table() || table_item.is_link_table()) {
O
oceanbase-admin 已提交
2167
    if (OB_FAIL(resolve_all_basic_table_columns(table_item, false, &column_items))) {
O
obdev 已提交
2168
      LOG_WARN("resolve all basic table columns failed", K(ret), K(table_item));
O
oceanbase-admin 已提交
2169
    }
W
wangzelin.wzl 已提交
2170
  } else if (table_item.is_generated_table() || table_item.is_temp_table()) {
O
oceanbase-admin 已提交
2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181
    if (OB_FAIL(resolve_all_generated_table_columns(table_item, &column_items))) {
      LOG_WARN("resolve all generated table columns failed", K(ret));
    }
  } else if (table_item.is_fake_cte_table()) {
    if (OB_FAIL(resolve_all_fake_cte_table_columns(table_item, &column_items))) {
      LOG_WARN("resolve fake cte table failed", K(ret));
    }
  } else if (table_item.is_function_table()) {
    if (OB_FAIL(resolve_all_function_table_columns(table_item, &column_items))) {
      LOG_WARN("resolve function table columns failed", K(ret));
    }
O
obdev 已提交
2182 2183 2184 2185
  } else if (table_item.is_json_table()) {
    if (OB_FAIL(resolve_all_json_table_columns(table_item, &column_items))) {
      LOG_WARN("resolve function table columns failed", K(ret));
    }
O
oceanbase-admin 已提交
2186 2187
  } else {
    ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
2188
    LOG_WARN("unexpected table type", K_(table_item.type), K(ret));
O
oceanbase-admin 已提交
2189 2190
  }

W
wangzelin.wzl 已提交
2191 2192
  const bool is_child_unpivot_select = (NULL != table_item.ref_query_
                                        && table_item.ref_query_->is_unpivot_select());
O
oceanbase-admin 已提交
2193 2194
  LOG_DEBUG("do expand_target_list", K(is_child_unpivot_select), KPC(table_item.ref_query_));
  for (int64_t i = 0; OB_SUCC(ret) && i < column_items.count(); ++i) {
W
wangzelin.wzl 已提交
2195
    const ColumnItem &col_item = column_items.at(i);
O
oceanbase-admin 已提交
2196
    SelectItem tmp_select_item;
W
wangzelin.wzl 已提交
2197
    if (table_item.is_generated_table() || table_item.is_temp_table()) {
O
oceanbase-admin 已提交
2198 2199
      if (OB_ISNULL(table_item.ref_query_) || i >= table_item.ref_query_->get_select_item_size()) {
        ret = OB_INVALID_ARGUMENT;
W
wangzelin.wzl 已提交
2200 2201
        LOG_WARN("invalid argument", K(ret), K(table_item.ref_query_),
                 K(i), K(table_item.ref_query_->get_select_item_size()));
O
oceanbase-admin 已提交
2202
      } else {
W
wangzelin.wzl 已提交
2203
        const SelectItem &select_item = table_item.ref_query_->get_select_item(i);
O
oceanbase-admin 已提交
2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229
        if (is_child_unpivot_select && select_item.is_unpivot_mocked_column_) {
          LOG_DEBUG("continue", K(select_item));
          continue;
        } else {
          tmp_select_item.questions_pos_ = select_item.questions_pos_;
          tmp_select_item.params_idx_ = select_item.params_idx_;
          tmp_select_item.neg_param_idx_ = select_item.neg_param_idx_;
          tmp_select_item.esc_str_flag_ = select_item.esc_str_flag_;
          tmp_select_item.paramed_alias_name_ = select_item.paramed_alias_name_;
          tmp_select_item.need_check_dup_name_ = select_item.need_check_dup_name_;
          tmp_select_item.is_unpivot_mocked_column_ = select_item.is_unpivot_mocked_column_;
        }
      }
    }
    tmp_select_item.alias_name_ = col_item.column_name_;
    tmp_select_item.expr_name_ = col_item.column_name_;
    tmp_select_item.is_real_alias_ = false;
    tmp_select_item.expr_ = col_item.expr_;
    if (OB_FAIL(target_list.push_back(tmp_select_item))) {
      LOG_WARN("push back target list failed", K(ret));
    }
  }
  return ret;
}

// construct select item from select_expr
W
wangzelin.wzl 已提交
2230
int ObSelectResolver::set_select_item(SelectItem &select_item, bool is_auto_gen)
O
oceanbase-admin 已提交
2231 2232 2233 2234
{
  int ret = OB_SUCCESS;
  ObCollationType cs_type = CS_TYPE_INVALID;

W
wangzelin.wzl 已提交
2235
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
2236 2237 2238 2239 2240 2241
  if (OB_ISNULL(select_stmt) || OB_ISNULL(session_info_) || OB_ISNULL(select_item.expr_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("select stmt is null", K_(session_info), K(select_stmt), K_(select_item.expr));
  } else if (OB_FAIL(session_info_->get_collation_connection(cs_type))) {
    LOG_WARN("fail to get collation_connection", K(ret));
  } else if (!select_item.expr_->is_column_ref_expr()) {
W
wangzelin.wzl 已提交
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267
    if (NULL != params_.secondary_namespace_ && !select_item.is_real_alias_ && is_auto_gen
        && select_item.alias_name_.length() > static_cast<size_t>(OB_MAX_COLUMN_NAME_LENGTH)) {
      ObString tmp_col_name;
      ObString col_name;
#define AILAS_NAME_LEN 100
      char temp_str_buf[AILAS_NAME_LEN] = { 0 };
      if (snprintf(temp_str_buf, sizeof(temp_str_buf), "Name_exp_%ld", auto_name_id_++) < 0) {
        ret = OB_SIZE_OVERFLOW;
        SQL_RESV_LOG(WARN, "failed to generate buffer for temp_str_buf", K(ret));
      }
#undef AILAS_NAME_LEN
      if (OB_SUCC(ret)) {
        tmp_col_name = ObString::make_string(temp_str_buf);
        if (OB_FAIL(ob_write_string(*allocator_, tmp_col_name, col_name))) {
          SQL_RESV_LOG(WARN, "Can not malloc space for constraint name", K(ret));
        } else {
          select_item.alias_name_.assign_ptr(col_name.ptr(), col_name.length());
        }
      }
      if (OB_SUCC(ret) &&
          OB_FAIL(ObSQLUtils::check_column_name(cs_type, select_item.alias_name_))) {
        LOG_WARN("fail to make field name", K(ret));
      }
    } else if (OB_FAIL(ObSQLUtils::check_and_copy_column_alias_name(cs_type, is_auto_gen,
                                                                    allocator_,
                                                                    select_item.alias_name_))) {
O
oceanbase-admin 已提交
2268 2269 2270 2271 2272
      LOG_WARN("check and copy column alias name failed", K(ret));
    }
  }
  if (OB_SUCC(ret) && OB_FAIL(select_stmt->add_select_item(select_item))) {
    LOG_WARN("add select item to select stmt failed", K(ret));
W
wangzelin.wzl 已提交
2273
  } else { /*do nothing.*/ }
O
oceanbase-admin 已提交
2274 2275 2276
  return ret;
}

W
wangzelin.wzl 已提交
2277 2278 2279 2280
// find matched table in ijoined table groups, set jointable_idx to the group index if found.
int ObSelectResolver::find_joined_table_group_for_table(
    const uint64_t table_id,
    int64_t &jointable_idx)
O
oceanbase-admin 已提交
2281 2282
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
2283
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
2284

W
wangzelin.wzl 已提交
2285 2286
  jointable_idx = -1;
  ObIArray<JoinedTable*> &joined_tables = select_stmt->get_joined_tables();
O
oceanbase-admin 已提交
2287 2288 2289 2290 2291 2292 2293 2294 2295 2296
  for (int i = 0; i < joined_tables.count(); i++) {
    bool found = false;
    for (int j = 0; j < joined_tables.at(i)->single_table_ids_.count(); j++) {
      if (joined_tables.at(i)->single_table_ids_.at(j) == table_id) {
        found = true;
        break;
      }
    }

    if (found) {
W
wangzelin.wzl 已提交
2297
      jointable_idx = i;
O
oceanbase-admin 已提交
2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325
      break;
    }
  }

  return ret;
}

// background:
// Tables in table_items of select stmt is added by the executed sequence, either
// based table or generated table. For joined table of each group, join info is
// saved in joined_tables of current select stmt. As for joined table with using,
// columns will be coalesced based on using list and joined table.
//
// idea:
// For each table item in table_items:
//  - based table, add all olumns in table schema
//  - generated table, add all select column items
//  - joined table, find all rest joined tables from one joined_table group, and
//  coalesce columns for based/generated table, which based/generated table columns
//  are producted by the rule above. Skip tables in current joined group for looping.
//
// words:
// table group: seperated by ','
// joined table group: tree of joined table in one table group
// join group: short of joined table group
//
int ObSelectResolver::resolve_star_for_table_groups()
{
W
wangzelin.wzl 已提交
2326
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
2327 2328
  int ret = OB_SUCCESS;
  int64_t num = 0;
W
wangzelin.wzl 已提交
2329
  int64_t jointable_idx = -1;
O
oceanbase-admin 已提交
2330 2331 2332 2333 2334 2335 2336
  if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null");
  } else {
    num = select_stmt->get_table_size();
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < num; i++) {
W
wangzelin.wzl 已提交
2337
    const TableItem *table_item = select_stmt->get_table_item(i);
O
oceanbase-admin 已提交
2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354
    if (OB_ISNULL(table_item)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("table item is null");
    } else if (has_oracle_join()) {
      table_item = get_from_items_order(i);
      if (OB_ISNULL(table_item) || table_item->is_joined_table()) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("table_item has wrong type", K(table_item));
      } else {
        ObArray<SelectItem> target_list;
        if (OB_FAIL(expand_target_list(*table_item, target_list))) {
          LOG_WARN("resolve table columns failed", K(ret), K(table_item));
        }
        for (int64_t i = 0; OB_SUCC(ret) && i < target_list.count(); ++i) {
          if (OB_FAIL(select_stmt->add_select_item(target_list.at(i)))) {
            LOG_WARN("add select item to select stmt failed", K(ret));
          } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
W
wangzelin.wzl 已提交
2355
            //如果是only full group by,所有target list中的列都必须检查是否满足group约束
O
oceanbase-admin 已提交
2356 2357 2358 2359 2360
            if (OB_FAIL(standard_group_checker_.add_unsettled_column(target_list.at(i).expr_))) {
              LOG_WARN("add unsettled column failed", K(ret));
            } else if (OB_FAIL(standard_group_checker_.add_unsettled_expr(target_list.at(i).expr_))) {
              LOG_WARN("add unsettled expr failed", K(ret));
            }
W
wangzelin.wzl 已提交
2361
            //同上
O
oceanbase-admin 已提交
2362 2363 2364 2365
          }
        }
      }
    } else {
W
wangzelin.wzl 已提交
2366
      if (OB_FAIL(find_joined_table_group_for_table(table_item->table_id_, jointable_idx))) {
O
oceanbase-admin 已提交
2367
        LOG_WARN("find_joined_table_group_for_table failed", K(ret), K(table_item));
W
wangzelin.wzl 已提交
2368 2369
      } else if (jointable_idx != -1) {
        // located in joined table with jointable_idx of joined_tables
O
oceanbase-admin 已提交
2370
        ObArray<SelectItem> sorted_select_items;
W
wangzelin.wzl 已提交
2371
        if (OB_FAIL(find_select_columns_for_join_group(jointable_idx, &sorted_select_items))) {
O
oceanbase-admin 已提交
2372 2373 2374
          LOG_WARN("find_select_columns_for_join_group failed", K(ret));
        } else {
          // skip next tables in joined group
W
wangzelin.wzl 已提交
2375
          i += select_stmt->get_joined_tables().at(jointable_idx)->single_table_ids_.count() - 1;
O
oceanbase-admin 已提交
2376 2377
          // push back select items to select stmt
          for (int j = 0; OB_SUCC(ret) && j < sorted_select_items.count(); j++) {
W
wangzelin.wzl 已提交
2378
            SelectItem &item = sorted_select_items.at(j);
O
oceanbase-admin 已提交
2379 2380 2381 2382 2383 2384 2385
            if (OB_FAIL(item.expr_->extract_info())) {
              LOG_WARN("extract info failed", K(ret));
            } else if (OB_FAIL(item.expr_->deduce_type(session_info_))) {
              LOG_WARN("deduce type failed", K(ret));
            } else if (OB_FAIL(select_stmt->add_select_item(item))) {
              LOG_WARN("add_select_item failed", K(ret), K(item));
            } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
W
wangzelin.wzl 已提交
2386
              //如果是only full group by,所有target list中的列都必须检查是否满足group约束
O
oceanbase-admin 已提交
2387 2388 2389 2390 2391
              if (OB_FAIL(standard_group_checker_.add_unsettled_column(item.expr_))) {
                LOG_WARN("add unsettled column failed", K(ret));
              } else if (standard_group_checker_.add_unsettled_expr(item.expr_)) {
                LOG_WARN("add unsettled expr failed", K(ret));
              }
W
wangzelin.wzl 已提交
2392
              //对于select * from t1 group by c1, c2;这样的语句,*展开就是column,所以表达式以及表达式引用到的列都是自己
O
oceanbase-admin 已提交
2393 2394 2395 2396 2397 2398
            }
          }
        }
      } else {
        // based table or alias table or generated table
        ObArray<SelectItem> target_list;
W
wangzelin.wzl 已提交
2399
        OZ( expand_target_list(*table_item, target_list), table_item );
O
oceanbase-admin 已提交
2400 2401 2402 2403
        for (int64_t i = 0; OB_SUCC(ret) && i < target_list.count(); ++i) {
          if (OB_FAIL(select_stmt->add_select_item(target_list.at(i)))) {
            LOG_WARN("add select item to select stmt failed", K(ret));
          } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
W
wangzelin.wzl 已提交
2404 2405 2406
            //如果是only full group by,所有target list中的列都必须检查是否满足group约束
            OZ( standard_group_checker_.add_unsettled_column(target_list.at(i).expr_) );
            OZ( standard_group_checker_.add_unsettled_expr(target_list.at(i).expr_) );
O
oceanbase-admin 已提交
2407 2408 2409 2410 2411 2412 2413 2414 2415
          }
        }
      }
    }
  }

  return ret;
}

O
obdev 已提交
2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428
int ObSelectResolver::resolve_all_json_table_columns(
  const TableItem &table_item, ObIArray<ColumnItem> *column_items)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(column_items)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("invalid params, null column items", K(ret));
  } else if (OB_FAIL(resolve_json_table_column_all_items(table_item, *column_items))) {
    LOG_WARN("fail to resolve json table column items", K(ret));
  }
  return ret;
}

O
oceanbase-admin 已提交
2429
int ObSelectResolver::resolve_all_function_table_columns(
W
wangzelin.wzl 已提交
2430
  const TableItem &table_item, ObIArray<ColumnItem> *column_items)
O
oceanbase-admin 已提交
2431 2432
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
2433 2434
  CK (OB_NOT_NULL(column_items));
  OZ (resolve_function_table_column_item(table_item, *column_items));
O
oceanbase-admin 已提交
2435 2436 2437
  return ret;
}

2438 2439 2440 2441 2442 2443 2444
int ObSelectResolver::is_need_check_col_dup(const ObRawExpr *expr, bool &need_check)
{
  int ret = OB_SUCCESS;
  need_check = true;
  if (OB_ISNULL(expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("is null", K(ret));
O
obdev 已提交
2445
  } else if (params_.need_check_col_dup_) {
2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462
    need_check = true;
  } else if (T_QUESTIONMARK == expr->get_expr_type()) {
    need_check = false;
  } else {
    for (int64_t j = 0; OB_SUCC(ret) && need_check && j < expr->get_children_count(); ++j) {
      const ObRawExpr *child = expr->get_param_expr(j);
      if (OB_ISNULL(child)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("invalid child", K(child));
      } else if (OB_FAIL(SMART_CALL(is_need_check_col_dup(child, need_check)))) {
        LOG_WARN("failed to check if need to check col duplicate", K(ret));
      }
    }
  }
  return ret;
}

O
oceanbase-admin 已提交
2463
int ObSelectResolver::resolve_all_generated_table_columns(
W
wangzelin.wzl 已提交
2464
  const TableItem &table_item, ObIArray<ColumnItem> *column_items)
O
oceanbase-admin 已提交
2465 2466
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
2467 2468
  ColumnItem *col_item = NULL;
  ObSelectStmt *table_ref = table_item.ref_query_;
O
oceanbase-admin 已提交
2469 2470 2471 2472 2473 2474
  bool is_exists = false;
  if (OB_ISNULL(table_ref)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("generate table is null", K(ret), K(table_ref));
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < table_ref->get_select_item_size(); ++i) {
W
wangzelin.wzl 已提交
2475 2476 2477
    const SelectItem &select_item = table_ref->get_select_item(i);
    const bool is_joined_dup_column = select_item.expr_->is_column_ref_expr()?
        static_cast<ObColumnRefRawExpr *>(select_item.expr_)->is_joined_dup_column():false;
2478 2479
    bool need_check_col_dup = true;
    bool is_skip = is_oracle_mode() && !table_ref->is_view_stmt() && is_joined_dup_column;
W
wangzelin.wzl 已提交
2480 2481 2482 2483 2484 2485 2486
    /* 这里进行一次重复列名检测是原因是oracle支持generated table含有重复列名的不引用重复列名的查询,比如:
    *  select 1 from (select c1,c1 from t1);因此在oracle模式resolve generated table时会跳过检查重复列
    *  但是对于select * from(select c1,c1 from t1);这样的查询肯定引用了,因此必须在展开*对应的查询时进行一次
    *  检查,如果存在重复列是不允许的;https://work.aone.alibaba-inc.com/issue/29799516
     */
    // if the select item is a duplicable column in generated table, skip the check.
    // else we should set the skip_join_dup parameter to true. 
2487 2488 2489 2490
    if (OB_FAIL(is_need_check_col_dup(select_item.expr_, need_check_col_dup))) {
      LOG_WARN("failed to check if need to check col duplicate", K(ret));
    } else if (FALSE_IT(is_skip = is_skip ? is_skip : !need_check_col_dup)) {
    } else if (!is_skip && OB_FAIL(column_namespace_checker_.check_column_exists(table_item,
W
wangzelin.wzl 已提交
2491 2492 2493
                                                              select_item.alias_name_,
                                                              is_exists, // the return value of is_exists is unused.
                                                              !table_ref->is_view_stmt()))) { //if is a view stmt, do not pass the duplicated column.
O
oceanbase-admin 已提交
2494
      LOG_WARN("failed to check column exists", K(ret));
W
wangzelin.wzl 已提交
2495 2496 2497 2498 2499 2500 2501
    } else if (OB_FAIL(resolve_generated_table_column_item(table_item,
                                                           select_item.alias_name_,
                                                           col_item,
                                                           NULL,
                                                           OB_INVALID_ID,
                                                           i,
                                                           is_skip))) {
O
oceanbase-admin 已提交
2502 2503 2504 2505 2506 2507 2508
      LOG_WARN("resolve column item failed", K(ret));
    } else if (column_items != NULL) {
      if (OB_FAIL(column_items->push_back(*col_item))) {
        LOG_WARN("push back column item failed", K(ret));
      }
    }
  }
W
wangzelin.wzl 已提交
2509 2510
  LOG_DEBUG("finish resolve_all_generated_table_columns", KPC(column_items), K(table_item),
            KPC(table_ref));
O
oceanbase-admin 已提交
2511 2512 2513 2514 2515 2516 2517 2518
  return ret;
}

// rules:
// table name can not same in same level, including alias
// specified columns are ahead of star
// columns are append by table group, seperated by ','.
// each group containers the mixtrue of based/joined/generated table.
W
wangzelin.wzl 已提交
2519
int ObSelectResolver::resolve_star(const ParseNode *node)
O
oceanbase-admin 已提交
2520 2521
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
2522
  ObSelectStmt *select_stmt = get_select_stmt();
O
obdev 已提交
2523
  const share::schema::ObTableSchema *table_schema = NULL;
O
oceanbase-admin 已提交
2524

W
wangzelin.wzl 已提交
2525 2526
  if (OB_ISNULL(node) || OB_ISNULL(session_info_)
      || OB_ISNULL(select_stmt) || OB_ISNULL(params_.expr_factory_)) {
O
oceanbase-admin 已提交
2527 2528 2529 2530 2531 2532 2533
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("invalid status", K(node), K_(session_info), K(select_stmt), K(params_.expr_factory_));
  } else if (node->type_ == T_STAR) {
    int64_t num = select_stmt->get_table_size();
    if (num <= 0) {
      // select *
      // select * from dual
W
wangzelin.wzl 已提交
2534 2535
      if (lib::is_mysql_mode()) {
        ObConstRawExpr *c_expr = NULL;
O
oceanbase-admin 已提交
2536 2537 2538 2539
        SelectItem select_item;
        if (!is_in_exists_subquery()) {
          ret = OB_ERR_NO_TABLES_USED;
          LOG_WARN("No tables used");
W
wangzelin.wzl 已提交
2540 2541
        } else if (ObRawExprUtils::build_const_int_expr(*params_.expr_factory_,
                                                        ObIntType, 1, c_expr)) {
O
oceanbase-admin 已提交
2542 2543 2544 2545
          LOG_WARN("fail to build const int expr", K(ret));
        } else if (OB_FALSE_IT(select_item.expr_ = c_expr)) {
        } else if (OB_FAIL(select_stmt->add_select_item(select_item))) {
          LOG_WARN("failed to add select item", K(ret));
W
wangzelin.wzl 已提交
2546
        } else {/*do nothing*/}
O
oceanbase-admin 已提交
2547 2548
      } else {
        // (select * from dual) is legitimate for oracle ==> output: X
W
wangzelin.wzl 已提交
2549 2550 2551
        ObConstRawExpr *c_expr = NULL;
        const char *ptr_value = "X";
        const char *ptr_name = "D";
O
oceanbase-admin 已提交
2552 2553
        ObString string_value(1, ptr_value);
        ObString string_name(1, ptr_name);
W
wangzelin.wzl 已提交
2554
        if (select_stmt->has_group_by() || has_group_by_clause()) {
O
oceanbase-admin 已提交
2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570
          ret = OB_ERR_WRONG_FIELD_WITH_GROUP;
          LOG_DEBUG("not a GROUP BY expression", K(ret));
        } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_VARCHAR, c_expr))) {
          LOG_WARN("fail to create const raw c_expr", K(ret));
        } else {
          ObObj obj;
          obj.set_string(ObVarcharType, string_value);
          obj.set_collation_type(CS_TYPE_UTF8MB4_BIN);
          c_expr->set_value(obj);
          SelectItem select_item;
          select_item.expr_ = c_expr;
          select_item.expr_name_ = string_name;
          select_item.alias_name_ = string_name;
          select_item.is_real_alias_ = true;
          if (OB_FAIL(select_stmt->add_select_item(select_item))) {
            LOG_WARN("failed to add select item", K(ret));
W
wangzelin.wzl 已提交
2571
          } else {/*do nothing*/}
O
oceanbase-admin 已提交
2572 2573 2574 2575 2576 2577 2578
        }
      }
    } else if (OB_FAIL(resolve_star_for_table_groups())) {
      LOG_WARN("resolve star for table groups failed", K(ret));
    }
  } else if (node->type_ == T_COLUMN_REF && node->children_[2]->type_ == T_STAR) {
    ObQualifiedName column_ref;
O
obdev 已提交
2579 2580 2581
    bool is_json_wildcard_column = false;  // special input : tab_name.column_name.*
    bool is_column_name_equal = false;
    const TableItem* tab_item = NULL;
O
oceanbase-admin 已提交
2582 2583 2584 2585 2586 2587 2588 2589
    ObNameCaseMode case_mode = OB_NAME_CASE_INVALID;
    if (OB_FAIL(session_info_->get_name_case_mode(case_mode))) {
      LOG_WARN("fail to get name case mode", K(ret));
    } else if (OB_FAIL(ObResolverUtils::resolve_column_ref(node, case_mode, column_ref))) {
      LOG_WARN("fail to resolve table name", K(ret));
    } else {
      ObSEArray<const TableItem*, 8> table_items;
      ObArray<SelectItem> target_list;
W
wangzelin.wzl 已提交
2590 2591
      if (OB_FAIL(select_stmt->get_all_table_item_by_tname(session_info_, column_ref.database_name_,
                                                           column_ref.tbl_name_, table_items))) {
O
oceanbase-admin 已提交
2592 2593
        LOG_WARN("get all matched table failed", K(ret));
      } else if (table_items.count() <= 0) {
O
obdev 已提交
2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608
        ret = OB_SUCCESS;
        ObString db_name;
        if (lib::is_oracle_mode() && OB_FAIL(select_stmt->get_all_table_item_by_tname(session_info_, db_name,
                                                                      column_ref.database_name_, table_items))) {
          LOG_WARN("get all matched table failed", K(ret));
        } else if (lib::is_mysql_mode() || table_items.count() <= 0) {
          ret = OB_ERR_BAD_TABLE;
        } else {
          is_json_wildcard_column = true;
        }
        if (ret != 0) {  // according to oracle , need cover error code
          ret = OB_ERR_BAD_TABLE;
          ObString table_name = concat_table_name(column_ref.database_name_, column_ref.tbl_name_);
          LOG_USER_ERROR(OB_ERR_BAD_TABLE, table_name.length(), table_name.ptr());
        }
O
oceanbase-admin 已提交
2609 2610 2611
      }
      for (int64_t i = 0; OB_SUCC(ret) && i < table_items.count(); ++i) {
        target_list.reset();
O
obdev 已提交
2612 2613
        tab_item = table_items.at(i);
        if (OB_ISNULL(tab_item)) {
O
oceanbase-admin 已提交
2614
          ret = OB_ERR_UNEXPECTED;
O
obdev 已提交
2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629
          LOG_WARN("get unexpected null", K(tab_item), K(ret));
        } else if (OB_FAIL(expand_target_list(*tab_item, target_list))) {
          LOG_WARN("resolve table columns failed", K(ret), K(tab_item), K(i));
        } else if (is_json_wildcard_column) {
          if (OB_FAIL(schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), tab_item->ref_id_, table_schema))) {
            ret = OB_TABLE_NOT_EXIST;
            LOG_WARN("get table schema failed", K_(tab_item->table_name), K(tab_item->ref_id_), K(ret));
          } else if (OB_ISNULL(table_schema)) {
            ret = OB_TABLE_NOT_EXIST;
            LOG_WARN("get table schema failed", K_(tab_item->table_name), K(tab_item->ref_id_), K(ret));
          } else if (OB_NOT_NULL(table_schema->get_column_schema(column_ref.tbl_name_))
                      && !table_schema->get_column_schema(column_ref.tbl_name_)->is_json()) {
            ret = OB_ERR_TABLE_NAME_NOT_IN_LIST;
            LOG_WARN("table name not in from list", K(ret), K(column_ref.tbl_name_));
          }
O
oceanbase-admin 已提交
2630 2631
        }
        for (int64_t j = 0; OB_SUCC(ret) && j < target_list.count(); ++j) {
O
obdev 已提交
2632 2633
          is_column_name_equal = is_json_wildcard_column & (0 != column_ref.tbl_name_.case_compare(target_list.at(j).alias_name_));
          if (!is_column_name_equal && OB_FAIL(select_stmt->add_select_item(target_list.at(j)))) {
O
oceanbase-admin 已提交
2634 2635
            LOG_WARN("add select item to select stmt failed", K(ret));
          } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
W
wangzelin.wzl 已提交
2636
            //如果是only full group by,所有target list中的列都必须检查是否满足group约束
O
obdev 已提交
2637 2638
            if (is_column_name_equal) {    // target column not equal with current column without judge
            } else if (OB_FAIL(standard_group_checker_.add_unsettled_column(target_list.at(j).expr_))) {
O
oceanbase-admin 已提交
2639 2640 2641 2642 2643
              LOG_WARN("add unsettled column failed", K(ret));
            } else if (OB_FAIL(standard_group_checker_.add_unsettled_expr(target_list.at(j).expr_))) {
              LOG_WARN("add unsettled expr to standard group checker failed", K(ret));
            }
          }
O
obdev 已提交
2644
          if (OB_SUCC(ret) && !is_column_name_equal) {
O
oceanbase-admin 已提交
2645
            ret = column_namespace_checker_.check_column_existence_in_using_clause(
W
wangzelin.wzl 已提交
2646
                    table_items.at(i)->table_id_, target_list.at(j).expr_name_);
O
oceanbase-admin 已提交
2647 2648 2649 2650 2651 2652 2653 2654 2655 2656
          }
        }
      }
    }
  } else {
    /* won't be here */
  }
  return ret;
}

W
wangzelin.wzl 已提交
2657

O
oceanbase-admin 已提交
2658 2659
// coalesce columns from left and right columns for the given joined type,
// with or without using_columns
W
wangzelin.wzl 已提交
2660 2661 2662 2663 2664 2665
int ObSelectResolver::coalesce_select_columns_for_joined_table(
  const ObIArray<SelectItem> *left,
  const ObIArray<SelectItem> *right,
  const ObJoinType type,
  const ObIArray<ObString> &using_columns,
  ObIArray<SelectItem> *coalesced_columns)
O
oceanbase-admin 已提交
2666 2667 2668
{
  int ret = OB_SUCCESS;
  ObArray<int64_t> coalesced_column_ids;
W
wangzelin.wzl 已提交
2669
  const ObIArray<SelectItem> *items = left;
O
oceanbase-admin 已提交
2670 2671 2672 2673 2674
  if (using_columns.count() > 0 && type == RIGHT_OUTER_JOIN) {
    items = right;
  }
  // 1. pick up matched using columns from select items
  for (int64_t j = 0; OB_SUCC(ret) && j < items->count(); j++) {
W
wangzelin.wzl 已提交
2675
    const SelectItem *item = &items->at(j);
O
oceanbase-admin 已提交
2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692
    for (int64_t i = 0; OB_SUCC(ret) && i < using_columns.count(); ++i) {
      if (ObCharset::case_insensitive_equal(item->alias_name_, using_columns.at(i))) {
        if (OB_FAIL(coalesced_columns->push_back(*item))) {
          LOG_WARN("coalesced_columns->push_back item failed", K(ret));
        }
        if (OB_FAIL(coalesced_column_ids.push_back(j))) {
          LOG_WARN("coalesced_column_ids.push_back failed", K(ret));
        }
        break;
      }
    }
  }

  // 2. pick up rest columns
  if (using_columns.count() > 0) {
    if (coalesced_column_ids.count() <= 0) {
      ret = OB_ERR_BAD_FIELD_ERROR;
W
wangzelin.wzl 已提交
2693
      SQL_RESV_LOG(WARN,"Column not exist", K(ret));
O
oceanbase-admin 已提交
2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717
    }
  }
  if (OB_SUCC(ret)) {
    for (int64_t i = 0; OB_SUCC(ret) && i < items->count(); i++) {
      int64_t j = 0;
      for (j = 0; j < coalesced_column_ids.count(); j++) {
        if (coalesced_column_ids.at(j) == i) {
          break;
        }
      }
      if (j == coalesced_column_ids.count()) {
        if (OB_FAIL(coalesced_columns->push_back(items->at(i)))) {
          LOG_WARN("coalesced_columns->push_back failed", K(ret));
        }
      }
    }

    // 3. pick up rest counts in other side
    items = right;
    if (using_columns.count() > 0 && type == RIGHT_OUTER_JOIN) {
      items = left;
    }
    if (coalesced_columns->count() <= 0) {
      ret = OB_ERR_BAD_FIELD_ERROR;
W
wangzelin.wzl 已提交
2718
      SQL_RESV_LOG(WARN,"Column not exist", K(ret));
O
oceanbase-admin 已提交
2719 2720
    }
    if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
2721 2722 2723
      // if we find a duplicated column name (exclude the using column), we need to set the hidden id
      // to distinguish them.
      int64_t left_column_num = coalesced_columns->count();
O
oceanbase-admin 已提交
2724
      for (int64_t i = 0; OB_SUCC(ret) && i < items->count(); i++) {
W
wangzelin.wzl 已提交
2725
        const SelectItem *item = &items->at(i);
O
oceanbase-admin 已提交
2726
        bool found = false;
W
wangzelin.wzl 已提交
2727 2728
        bool duplicated = false;
        int64_t dup_col_index = 0;
O
oceanbase-admin 已提交
2729 2730 2731 2732 2733 2734
        for (int64_t j = 0; OB_SUCC(ret) && j < using_columns.count(); ++j) {
          if (ObCharset::case_insensitive_equal(item->alias_name_, using_columns.at(j))) {
            found = true;
            break;
          }
        }
W
wangzelin.wzl 已提交
2735 2736 2737 2738 2739 2740
        for(dup_col_index = 0; dup_col_index < left_column_num; dup_col_index++ ) {
          if (ObCharset::case_insensitive_equal(item->alias_name_, coalesced_columns->at(dup_col_index).alias_name_)) {
            duplicated=true; 
            break;
          }
        }
O
oceanbase-admin 已提交
2741 2742 2743 2744
        if (!found) {
          if (OB_FAIL(coalesced_columns->push_back(*item))) {
            LOG_WARN("coalesced_columns->push_back failed", K(ret));
          }
W
wangzelin.wzl 已提交
2745 2746 2747 2748 2749 2750 2751
          // if found duplicated and the duplicated column is not the using column.
          // set the is_joined_dup_column flag; the i-th column in items (the last column in coalesced_columns) is 
          // duplicated with the left_column_index-th column in coalesced_columns.
          if (OB_SUCC(ret) && duplicated) {
            static_cast<ObColumnRefRawExpr*>(coalesced_columns->at(dup_col_index).expr_)->set_joined_dup_column(true);
            static_cast<ObColumnRefRawExpr*>(coalesced_columns->at(coalesced_columns->count()-1).expr_)->set_joined_dup_column(true);
          }
O
oceanbase-admin 已提交
2752 2753 2754 2755 2756 2757 2758
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
2759
// jointable will be the root node of joined table, if you want to loop the whole tree.
O
oceanbase-admin 已提交
2760
int ObSelectResolver::find_select_columns_for_joined_table_recursive(
W
wangzelin.wzl 已提交
2761 2762
  const JoinedTable *jointable,
  ObIArray<SelectItem> *sorted_select_items)
O
oceanbase-admin 已提交
2763 2764 2765 2766 2767
{
  int ret = OB_SUCCESS;
  ObArray<SelectItem> left_select_items;
  ObArray<SelectItem> right_select_items;

W
wangzelin.wzl 已提交
2768 2769 2770 2771
  if (jointable->left_table_->type_ == TableItem::JOINED_TABLE) {
    OC( (find_select_columns_for_joined_table_recursive)(
          static_cast<const JoinedTable*>(jointable->left_table_),
          &left_select_items));
O
oceanbase-admin 已提交
2772
  } else {
W
wangzelin.wzl 已提交
2773
    OC( (expand_target_list)(*jointable->left_table_, left_select_items) );
O
oceanbase-admin 已提交
2774 2775 2776
  }

  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
2777 2778 2779 2780
    if (jointable->right_table_->type_ == TableItem::JOINED_TABLE) {
      OC( (find_select_columns_for_joined_table_recursive)(
            static_cast<const JoinedTable*>(jointable->right_table_),
            &right_select_items));
O
oceanbase-admin 已提交
2781
    } else {
W
wangzelin.wzl 已提交
2782
      OC( (expand_target_list)(*jointable->right_table_, right_select_items) );
O
oceanbase-admin 已提交
2783 2784 2785
    }
  }

W
wangzelin.wzl 已提交
2786 2787 2788 2789 2790 2791 2792 2793 2794
  ResolverJoinInfo *join_info = NULL;
  if (get_joininfo_by_id(jointable->table_id_, join_info)) {
    OC( (coalesce_select_columns_for_joined_table)(
         &left_select_items,
         &right_select_items,
         jointable->joined_type_,
         join_info->using_columns_,
         sorted_select_items));
  }
O
oceanbase-admin 已提交
2795 2796 2797 2798

  return ret;
}

W
wangzelin.wzl 已提交
2799 2800 2801
int ObSelectResolver::find_select_columns_for_join_group(
  const int64_t jointable_idx,
  ObArray<SelectItem> *sorted_select_items)
O
oceanbase-admin 已提交
2802 2803
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
2804 2805
  const ObSelectStmt *select_stmt = get_select_stmt();
  const JoinedTable *jointable = select_stmt->get_joined_tables().at(jointable_idx);
O
oceanbase-admin 已提交
2806

W
wangzelin.wzl 已提交
2807 2808
  if (OB_FAIL(find_select_columns_for_joined_table_recursive(jointable, sorted_select_items))) {
    LOG_WARN("find_select_columns_for_joined_table_recursive failed!", K(*jointable));
O
oceanbase-admin 已提交
2809
  } else {
W
wangzelin.wzl 已提交
2810
    const ObIArray<JoinedTable*> &joined_tables = select_stmt->get_joined_tables();
O
oceanbase-admin 已提交
2811 2812
    int64_t n_select_count = sorted_select_items->count();
    for (int64_t i = 0; i < n_select_count; ++i) {
W
wangzelin.wzl 已提交
2813
      ObRawExpr *coalesce_expr = NULL;
O
oceanbase-admin 已提交
2814 2815
      for (int j = 0; j < joined_tables.count(); j++) {
        const JoinedTable* joined_table = joined_tables.at(j);
W
wangzelin.wzl 已提交
2816 2817 2818
        OZ(recursive_find_coalesce_expr(joined_table,
                                        sorted_select_items->at(i).alias_name_,
                                        coalesce_expr));
O
oceanbase-admin 已提交
2819 2820 2821 2822 2823 2824 2825 2826 2827
        if (coalesce_expr != NULL) {
          sorted_select_items->at(i).expr_ = coalesce_expr;
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
2828 2829 2830 2831 2832 2833 2834 2835
/*               |-------------------------------------r_union_stmt--------------------------------|
 * with cte() as ( left_stmt union all right stmt  ) search by item + pseudo, cycle by item + pseudo
 * r_union_stmt这个stmt的解析过程中,是没有任何一个table item出现在这个层次的stmt的
 * 没有办法按照常规的表达式T_COLUMN_REF产生表达式,并作为column_item加到stmt中
 * 因为加入的时候会检查是否该列的表是否在stmt中。
 * search或者cycle的item在在left_stmt和right_stmt中代表的列不一样,所以无法直接使用左支或者右支的select item
 * 所以只能类似于generate table item中的column item产生的方式来产生
 * */
O
oceanbase-admin 已提交
2836
int ObSelectResolver::generate_fake_column_expr(
W
wangzelin.wzl 已提交
2837 2838 2839
  const share::schema::ObColumnSchemaV2 *column_schema,
  ObSelectStmt *left_stmt,
  ObColumnRefRawExpr *&fake_col_expr)
O
oceanbase-admin 已提交
2840 2841 2842
{
  int ret = OB_SUCCESS;
  int64_t projector_offset = column_schema->get_cte_generate_column_projector_offset();
W
wangzelin.wzl 已提交
2843 2844
  ObSelectStmt *select_stmt = NULL;
  ObColumnRefRawExpr *col_expr = NULL;
O
oceanbase-admin 已提交
2845
  ColumnItem column_item;
W
wangzelin.wzl 已提交
2846
  CK( OB_NOT_NULL(select_stmt = get_select_stmt()),
O
oceanbase-admin 已提交
2847 2848 2849 2850 2851
      OB_NOT_NULL(column_schema),
      OB_NOT_NULL(left_stmt),
      !OB_UNLIKELY(projector_offset >= left_stmt->get_select_item_size()),
      OB_NOT_NULL(left_stmt->get_select_item(projector_offset).expr_),
      !(projector_offset >= cte_ctx_.cte_col_names_.count()));
W
wangzelin.wzl 已提交
2852 2853
  OC( (params_.expr_factory_->create_raw_expr)(T_REF_COLUMN, col_expr) );
  OC( (left_stmt->get_select_item(projector_offset).expr_->deduce_type)(session_info_) );
O
oceanbase-admin 已提交
2854
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
2855 2856 2857 2858
    //build a new column ref expr
    col_expr->set_ref_id(
      current_recursive_cte_table_item_->ref_id_,
      column_schema->get_column_id());
O
oceanbase-admin 已提交
2859
    col_expr->set_result_type(left_stmt->get_select_item(projector_offset).expr_->get_result_type());
W
wangzelin.wzl 已提交
2860 2861
    col_expr->set_column_attr(current_recursive_cte_table_item_->get_table_name(),
                              cte_ctx_.cte_col_names_.at(projector_offset));
O
oceanbase-admin 已提交
2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872
    col_expr->set_database_name(current_recursive_cte_table_item_->database_name_);
    col_expr->set_column_flags(CTE_GENERATED_COLUMN_FLAG);
    if (OB_FAIL(col_expr->extract_info())) {
      LOG_WARN("extract column expr info failed", K(ret));
    } else {
      fake_col_expr = col_expr;
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
2873
int ObSelectResolver::resolve_search_item(const ParseNode *sort_list, ObSelectStmt *r_union_stmt)
O
oceanbase-admin 已提交
2874 2875 2876 2877
{
  int ret = OB_SUCCESS;
  ObSelectStmt* left_stmt = r_union_stmt->get_set_query(0);
  for (int64_t i = 0; OB_SUCC(ret) && i < sort_list->num_child_; ++i) {
W
wangzelin.wzl 已提交
2878
    ParseNode *sort_node = sort_list->children_[i];
O
oceanbase-admin 已提交
2879
    OrderItem order_item;
W
wangzelin.wzl 已提交
2880 2881 2882
    ObColumnRefRawExpr *fake_col_expr = NULL;
    const share::schema::ObColumnSchemaV2 *column_schema;
    ParseNode *alias_node = sort_node->children_[0];
O
oceanbase-admin 已提交
2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896
    ObString column_alia_name;
    if (OB_FAIL(ObResolverUtils::set_direction_by_mode(*sort_node, order_item))) {
      LOG_WARN("failed to set direction by mode", K(ret));
    } else if (OB_ISNULL(alias_node)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("alias node is null", K(ret));
    } else if (T_OBJ_ACCESS_REF != alias_node->type_) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("alias node is not a obj access", K(ret));
    } else if (OB_ISNULL(alias_node->children_[0])) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("alias node is invalid", K(ret));
    } else {
      column_alia_name.assign_ptr(
W
wangzelin.wzl 已提交
2897 2898
        (char *) (alias_node->children_[0]->str_value_),
        static_cast<int32_t>(alias_node->children_[0]->str_len_));
O
oceanbase-admin 已提交
2899 2900 2901
    }

    if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
2902 2903 2904 2905 2906
      if (OB_FAIL(get_column_schema(current_recursive_cte_table_item_->ref_id_,
                                    column_alia_name,
                                    column_schema,
                                    false /*get_hidden*/,
                                    current_recursive_cte_table_item_->is_link_table()))) {
O
oceanbase-admin 已提交
2907
        LOG_WARN("the col item has been resolve, but we do not find it in the search clause resolver", K(ret));
W
wangzelin.wzl 已提交
2908
      } else if (OB_FAIL(generate_fake_column_expr(column_schema, left_stmt, fake_col_expr))){
O
oceanbase-admin 已提交
2909 2910 2911 2912 2913 2914 2915 2916 2917 2918
        LOG_WARN("generate the column item", K(ret), K(*column_schema));
      } else {
        order_item.expr_ = fake_col_expr;
        if (OB_FAIL(r_union_stmt->add_search_item(order_item))) {
          // add the search order item
          LOG_WARN("Add order expression error", K(ret));
        }
      }
    }

W
wangzelin.wzl 已提交
2919
  } // end of for
O
oceanbase-admin 已提交
2920 2921 2922
  return ret;
}

W
wangzelin.wzl 已提交
2923 2924 2925
int ObSelectResolver::resolve_search_pseudo(const ParseNode *search_set_clause,
                                            ObSelectStmt *r_union_stmt,
                                            ObString &search_pseudo_column_name)
O
oceanbase-admin 已提交
2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(search_set_clause) || OB_ISNULL(r_union_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("search set clause/r_union_stmt is null", K(ret), K(search_set_clause), K(r_union_stmt));
  } else if (OB_FAIL(resolve_and_split_sql_expr(*search_set_clause, r_union_stmt->get_cte_exprs()))) {
    LOG_WARN("resolve and split sql expr failed", K(ret));
  } else {
    int64_t count = r_union_stmt->get_cte_exprs().count() - 1;
    if (count < 0) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("we need at least 1 cte expr!", K(ret));
    } else {
      ObRawExpr* search_pseudo_column_expr = r_union_stmt->get_cte_exprs().at(count);
      if (T_CTE_SEARCH_COLUMN != search_pseudo_column_expr->get_expr_type()) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("expected t_cte_search_column", K(ret));
      } else {
        SelectItem select_item;
        select_item.expr_ = search_pseudo_column_expr;
        select_item.alias_name_.assign_ptr(search_pseudo_column_expr->get_alias_column_name().ptr(),
            search_pseudo_column_expr->get_alias_column_name().length());
        search_pseudo_column_name.assign_ptr(search_pseudo_column_expr->get_alias_column_name().ptr(),
            search_pseudo_column_expr->get_alias_column_name().length());
        select_item.is_real_alias_ = true;
        if (OB_FAIL(r_union_stmt->add_select_item(select_item))) {
          // construct select item from select_expr
          LOG_WARN("set cte search select item failed", K(ret));
        }
      }
    }
  }

  return ret;
}

W
wangzelin.wzl 已提交
2962 2963 2964 2965 2966 2967 2968 2969 2970
/**
 * 在search clause中必须严格出现在cte(col alias)定义的列名,不允许出现类似cte.col,指定是定义的名字。
 * 例如:
 *     cte( a, b, c) as (.....) search depth by a, c, b set ordering
 *     只能是单独的一个列的表现形式,已经oracle中测试并确认
 */
int ObSelectResolver::resolve_search_clause(const ParseNode &parse_tree,
                                            const TableItem* cte_table_item,
                                            ObString& search_pseudo_column_name)
O
oceanbase-admin 已提交
2971 2972 2973 2974 2975 2976
{
  int ret = OB_SUCCESS;
  current_scope_ = T_WITH_CLAUSE_SEARCH_SCOPE;
  const ParseNode* sort_list = parse_tree.children_[0];
  const ParseNode* search_set_clause = parse_tree.children_[1];
  ObSelectStmt* r_union_stmt = cte_table_item->ref_query_;
W
wangzelin.wzl 已提交
2977
  //获得深度 广度优先选项,查询列选项以及伪列的列名
O
oceanbase-admin 已提交
2978 2979 2980
  if (OB_ISNULL(r_union_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("the recursive union can not be null", K(ret));
W
wangzelin.wzl 已提交
2981 2982
  } else if (OB_ISNULL(r_union_stmt->get_set_query(0))
             && OB_ISNULL(r_union_stmt->get_set_query(1))) {
O
oceanbase-admin 已提交
2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005
    ret = OB_ERR_CTE_ILLEGAL_SEARCH_CYCLE_CLAUSE;
    LOG_WARN("SEARCH and CYCLE clauses can only be specified for recursive WITH clause elements", K(ret));
  } else if (OB_ISNULL(current_recursive_cte_table_item_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("the recursive cte table item can not be null", K(ret));
  } else if (T_SEARCH_DEPTH_NODE == parse_tree.type_) {
    r_union_stmt->set_breadth_strategy(false);
  } else if (T_SEARCH_BREADTH_NODE == parse_tree.type_) {
    r_union_stmt->set_breadth_strategy(true);
  } else {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected search clause parse tree", K(ret));
  }
  if (OB_SUCC(ret)) {
    if (OB_FAIL(resolve_search_item(sort_list, r_union_stmt))) {
      LOG_WARN("resolve search item failed", K(ret));
    } else if (OB_FAIL(resolve_search_pseudo(search_set_clause, r_union_stmt, search_pseudo_column_name))) {
      LOG_WARN("resolve search pseudo failed", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3006
int ObSelectResolver::resolve_cycle_item(const ParseNode *alias_list, ObSelectStmt *r_union_stmt)
O
oceanbase-admin 已提交
3007 3008 3009 3010 3011
{
  int ret = OB_SUCCESS;
  ObSelectStmt* left_stmt = r_union_stmt->get_set_query(0);
  ObSEArray<ObString, 8> col_names;
  for (int64_t i = 0; OB_SUCC(ret) && i < alias_list->num_child_; ++i) {
W
wangzelin.wzl 已提交
3012
    ParseNode *alias_node = alias_list->children_[i];
O
oceanbase-admin 已提交
3013 3014
    ObString column_alia_name;
    ColumnItem col_item;
W
wangzelin.wzl 已提交
3015 3016 3017 3018 3019 3020 3021 3022 3023
    ObColumnRefRawExpr *fake_col_expr = NULL;
    const share::schema::ObColumnSchemaV2 *column_schema;
    column_alia_name.assign_ptr((char *) (alias_node->str_value_),
                                static_cast<int32_t>(alias_node->str_len_));
    if (OB_FAIL(get_column_schema(current_recursive_cte_table_item_->ref_id_,
                                  column_alia_name,
                                  column_schema,
                                  false /*get_hidden*/,
                                  current_recursive_cte_table_item_->is_link_table()))) {
O
oceanbase-admin 已提交
3024 3025 3026 3027 3028
      LOG_WARN("the col item has been resolve, but we do not find it in the cycle clause resolver", K(ret));
    } else if (OB_FAIL(generate_fake_column_expr(column_schema, left_stmt, fake_col_expr))) {
      LOG_WARN("generate the column item", K(ret));
    } else {
      int64_t projector_offset = column_schema->get_cte_generate_column_projector_offset();
W
wangzelin.wzl 已提交
3029 3030 3031 3032
      //set col item
      ObResolverUtils::resolve_default_value_and_expr_from_select_item(left_stmt->get_select_item(projector_offset),
                                                                       col_item,
                                                                       left_stmt); 
O
oceanbase-admin 已提交
3033 3034 3035 3036 3037 3038 3039 3040
      col_item.expr_ = fake_col_expr;
      col_item.column_id_ = column_schema->get_column_id();
      col_item.table_id_ = current_recursive_cte_table_item_->ref_id_;
      col_item.column_name_ = column_schema->get_column_name_str();
      if (OB_FAIL(r_union_stmt->add_cycle_item(col_item))) {
        LOG_WARN("add cycle r union stmt col item failed", K(ret));
      }
    }
W
wangzelin.wzl 已提交
3041
  } // end of for
O
oceanbase-admin 已提交
3042 3043 3044
  return ret;
}

W
wangzelin.wzl 已提交
3045 3046 3047 3048 3049
int ObSelectResolver::resolve_cycle_pseudo(const ParseNode *cycle_set_clause,
                                           ObSelectStmt *r_union_stmt,
                                           const ParseNode *cycle_value,
                                           const ParseNode *cycle_default_value,
                                           ObString &cycle_pseudo_column_name)
O
oceanbase-admin 已提交
3050 3051
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3052 3053 3054
  ObRawExpr *expr_v = nullptr;
  ObRawExpr *expr_d_v = nullptr;
  //for pseudo column
O
oceanbase-admin 已提交
3055 3056
  if (OB_ISNULL(cycle_set_clause)) {
    LOG_WARN("cycle clause must have set pseudo column", K(ret));
W
wangzelin.wzl 已提交
3057 3058
  } else if (OB_FAIL(resolve_and_split_sql_expr(*cycle_set_clause,
                                                r_union_stmt->get_cte_exprs()))) {
O
oceanbase-admin 已提交
3059
    LOG_WARN("resolve and split sql expr failed", K(ret));
W
wangzelin.wzl 已提交
3060 3061 3062 3063 3064 3065 3066 3067 3068
  } else if (cycle_value->type_ == T_QUESTIONMARK
        && cycle_default_value->type_ == T_QUESTIONMARK) {
      ret = OB_INVALID_ARGUMENT;
      LOG_WARN("cycle value can not be '?'",
               K(ret),
               K(cycle_value->text_len_),
               K(cycle_default_value->text_len_));
  } else if (cycle_value->type_ == T_VARCHAR
             && cycle_default_value->type_ == T_VARCHAR) {
O
oceanbase-admin 已提交
3069 3070 3071 3072 3073 3074 3075 3076
    if (cycle_value->str_len_ > 0 && cycle_default_value->str_len_ > 0) {
      if (OB_FAIL(resolve_sql_expr(*cycle_value, expr_v))) {
        LOG_WARN("resolve sql expr failed", K(ret));
      } else if (OB_FAIL(resolve_sql_expr(*cycle_default_value, expr_d_v))) {
        LOG_WARN("resolve sql expr failed", K(ret));
      }
    } else {
      ret = OB_ERR_CTE_ILLEGAL_CYCLE_NON_CYCLE_VALUE;
W
wangzelin.wzl 已提交
3077 3078 3079 3080
      LOG_WARN("invalid cycle argument",
               K(ret),
               K(cycle_value->str_len_),
               K(cycle_default_value->str_len_));
O
oceanbase-admin 已提交
3081 3082 3083 3084 3085 3086 3087 3088
    }
  }
  if (OB_SUCC(ret)) {
    int64_t cycle_column_idx = r_union_stmt->get_cte_exprs().count();
    if (OB_UNLIKELY(0 == cycle_column_idx)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("a recursive union stmt without cte expr is unexpected", K(ret));
    } else {
W
wangzelin.wzl 已提交
3089
      ObRawExpr *expr = r_union_stmt->get_cte_exprs().at(cycle_column_idx - 1);
O
oceanbase-admin 已提交
3090 3091 3092 3093 3094 3095 3096 3097
      if (OB_UNLIKELY(T_CTE_CYCLE_COLUMN != expr->get_expr_type())) {
        ret = OB_ERR_PARSER_SYNTAX;
        LOG_WARN("must be cycle pseudo column", K(ret));
      } else {
        ObPseudoColumnRawExpr* cycle_expr = static_cast<ObPseudoColumnRawExpr*>(expr);
        cycle_expr->set_cte_cycle_value(expr_v, expr_d_v);
        SelectItem select_item;
        select_item.expr_ = cycle_expr;
W
wangzelin.wzl 已提交
3098 3099 3100 3101
        select_item.alias_name_.assign_ptr(cycle_expr->get_alias_column_name().ptr(),
                                           cycle_expr->get_alias_column_name().length());
        cycle_pseudo_column_name.assign_ptr(cycle_expr->get_alias_column_name().ptr(),
                                            cycle_expr->get_alias_column_name().length());
O
oceanbase-admin 已提交
3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112
        select_item.is_real_alias_ = true;
        if (OB_FAIL(r_union_stmt->add_select_item(select_item))) {
          // construct select item from select_expr
          LOG_WARN("failed to set cte search select item", K(ret));
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3113 3114 3115 3116 3117 3118 3119 3120 3121 3122

/**
 * 在cycle clause中必须严格出现在cte(col alias)定义的列名,不允许出现类似cte.col,指定是定义的名字。
 * 例如:
 *     cte( a, b, c) as (.....) search depth by a, c, b set ordering cycle a
 *     只能是单独的一个列的表现形式,已经oracle中测试并确认,不能采用类似cte.a cte.b这样的表现形式
 */
int ObSelectResolver::resolve_cycle_clause(const ParseNode &parse_tree,
                                           const TableItem *cte_table_item,
                                           ObString &cycle_pseudo_column_name)
O
oceanbase-admin 已提交
3123 3124 3125
{
  int ret = OB_SUCCESS;
  current_scope_ = T_WITH_CLAUSE_CYCLE_SCOPE;
W
wangzelin.wzl 已提交
3126 3127 3128 3129 3130
  ObSelectStmt *r_union_stmt = cte_table_item->ref_query_;
  const ParseNode *alias_list = parse_tree.children_[0];
  const ParseNode *cycle_set_clause = parse_tree.children_[1];
  const ParseNode *cycle_value = parse_tree.children_[2];
  const ParseNode *cycle_default_value = parse_tree.children_[3];
O
oceanbase-admin 已提交
3131

W
wangzelin.wzl 已提交
3132 3133
  CK( OB_NOT_NULL(r_union_stmt),
      OB_NOT_NULL(current_recursive_cte_table_item_));
O
oceanbase-admin 已提交
3134

W
wangzelin.wzl 已提交
3135 3136
  if (OB_ISNULL(r_union_stmt->get_set_query(0))
      && OB_ISNULL(r_union_stmt->get_set_query(1))) {
O
oceanbase-admin 已提交
3137 3138 3139 3140
    ret = OB_ERR_CTE_ILLEGAL_SEARCH_CYCLE_CLAUSE;
    LOG_WARN("SEARCH and CYCLE clauses can only be specified for recursive WITH clause elements", K(ret));
  }

W
wangzelin.wzl 已提交
3141 3142 3143 3144 3145 3146
  OZ( resolve_cycle_item(alias_list, r_union_stmt) );
  OZ( resolve_cycle_pseudo(cycle_set_clause,
                           r_union_stmt,
                           cycle_value,
                           cycle_default_value,
                           cycle_pseudo_column_name) );
O
oceanbase-admin 已提交
3147 3148 3149
  return ret;
}

W
wangzelin.wzl 已提交
3150
int ObSelectResolver::get_current_recursive_cte_table(ObSelectStmt *ref_stmt)
O
oceanbase-admin 已提交
3151 3152
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3153
  ObSelectStmt *right_stmt = nullptr;
O
oceanbase-admin 已提交
3154
  if (!ref_stmt->is_recursive_union()) {
W
wangzelin.wzl 已提交
3155 3156 3157
    //do nothing
  } else if (OB_ISNULL(ref_stmt)
      || OB_ISNULL(right_stmt = ref_stmt->get_set_query(1))) {
O
oceanbase-admin 已提交
3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("invalid argument", K(ret), K(ref_stmt), K(right_stmt));
  } else {
    current_cte_involed_stmt_ = right_stmt;
    int64_t table_count = right_stmt->get_table_size();
    int64_t cte_table_count = 0;
    common::ObIArray<TableItem*>& table_items = right_stmt->get_table_items();
    for (int64_t i = 0; OB_SUCC(ret) && i < table_count; ++i) {
      if (table_items.at(i)->is_fake_cte_table()) {
        current_recursive_cte_table_item_ = table_items.at(i);
        ++cte_table_count;
      }
    }
    if (OB_SUCC(ret) && 1 != cte_table_count) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("the r union stmt's right child stmt must have only one cte table", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3179
int ObSelectResolver::check_cycle_clause(const ParseNode &cycle_node)
O
oceanbase-admin 已提交
3180 3181
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3182 3183 3184 3185 3186 3187 3188 3189
  CK( !OB_UNLIKELY(cycle_node.num_child_ != 4) );
  CK( OB_NOT_NULL(cycle_node.children_[0]) );
  CK( OB_NOT_NULL(cycle_node.children_[1]) );
  CK( OB_NOT_NULL(cycle_node.children_[2]) );
  CK( OB_NOT_NULL(cycle_node.children_[3]) );
  CK( OB_NOT_NULL(cycle_node.children_[1]->children_[1]) );
  const ParseNode *cycle_set_clause = cycle_node.children_[1];
  const ParseNode *alias_list = cycle_node.children_[0];
O
oceanbase-admin 已提交
3190 3191 3192
  if (OB_SUCC(ret)) {
    ObSEArray<ObString, 8> alias;
    for (int64_t i = 0; OB_SUCC(ret) && i < alias_list->num_child_; ++i) {
W
wangzelin.wzl 已提交
3193
      ParseNode *alias_node = alias_list->children_[i];
O
oceanbase-admin 已提交
3194
      ObString column_alia_name;
W
wangzelin.wzl 已提交
3195 3196
      column_alia_name.assign_ptr((char *) (alias_node->str_value_),
                                  static_cast<int32_t>(alias_node->str_len_));
O
oceanbase-admin 已提交
3197 3198 3199 3200 3201 3202
      for (int64_t j = 0; j < alias.count() && OB_SUCC(ret); ++j) {
        if (ObCharset::case_insensitive_equal(alias.at(j), column_alia_name)) {
          ret = OB_ERR_CTE_DUPLICATE_NAME_IN_CYCLE_CLAUSE;
          LOG_WARN("duplicate name found in cycle column list for CYCLE clause of WITH clause", K(ret));
        }
      }
W
wangzelin.wzl 已提交
3203
      OZ( alias.push_back(column_alia_name) );
O
oceanbase-admin 已提交
3204 3205 3206 3207 3208 3209 3210 3211 3212
      if (OB_SUCC(ret)) {
        bool found = false;
        for (int64_t j = 0; OB_SUCC(ret) && j < cte_ctx_.cte_col_names_.count() && !found; ++j) {
          if (ObCharset::case_insensitive_equal(cte_ctx_.cte_col_names_.at(j), column_alia_name)) {
            found = true;
          }
        }
        if (!found) {
          ret = OB_ERR_CTE_ILLEGAL_COLUMN_IN_CYCLE_CLAUSE;
W
wangzelin.wzl 已提交
3213
          LOG_WARN("element in cycle column list of CYCLE clause must appear in the column alias list of the WITH clause element", K(ret));
O
oceanbase-admin 已提交
3214 3215 3216 3217 3218
        }
      }
    }
  }
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
3219
    const ParseNode *set_column = cycle_set_clause->children_[1];
O
oceanbase-admin 已提交
3220
    ObString set_column_name;
W
wangzelin.wzl 已提交
3221 3222
    set_column_name.assign_ptr((char *) (set_column->str_value_),
                               static_cast<int32_t>(set_column->str_len_));
O
oceanbase-admin 已提交
3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236
    bool found = false;
    for (int64_t i = 0; OB_SUCC(ret) && i < cte_ctx_.cte_col_names_.count() && !found; ++i) {
      if (ObCharset::case_insensitive_equal(cte_ctx_.cte_col_names_.at(i), set_column_name)) {
        found = true;
      }
    }
    if (found) {
      ret = OB_ERR_CTE_ILLEGAL_CYCLE_PSEUDO_NAME;
      LOG_WARN("cycle mark column name for CYCLE clause must not be part of the column alias list", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3237
int ObSelectResolver::check_search_clause(const ParseNode &search_node)
O
oceanbase-admin 已提交
3238 3239 3240 3241
{
  int ret = OB_SUCCESS;
  const ParseNode* sort_list = search_node.children_[0];
  const ParseNode* search_set_clause = search_node.children_[1];
W
wangzelin.wzl 已提交
3242 3243 3244 3245 3246
  CK( OB_NOT_NULL(sort_list));
  CK( OB_NOT_NULL(search_set_clause));
  CK( search_set_clause->num_child_ == 2 );
  CK( OB_NOT_NULL(search_set_clause->children_[1]->str_value_) );
  CK( search_set_clause->children_[1]->str_len_ > 0 );
O
oceanbase-admin 已提交
3247 3248
  if (OB_SUCC(ret)) {
    for (int64_t i = 0; OB_SUCC(ret) && i < sort_list->num_child_; ++i) {
W
wangzelin.wzl 已提交
3249 3250
      ParseNode *sort_node = sort_list->children_[i];
      ParseNode *alias_node = sort_node->children_[0];
O
oceanbase-admin 已提交
3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262
      ObString column_alia_name;
      if (OB_ISNULL(alias_node)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("alias node is null", K(ret));
      } else if (T_OBJ_ACCESS_REF != alias_node->type_) {
        // For oracle error code compatibility
        ret = OB_ERR_CTE_ILLEGAL_COLUMN_IN_SERACH_CALUSE;
        LOG_WARN("alias node is not a obj access", K(ret));
      } else if (OB_ISNULL(alias_node->children_[0])) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("alias node is invalid", K(ret));
      } else {
W
wangzelin.wzl 已提交
3263 3264
        column_alia_name.assign_ptr((char *) (alias_node->children_[0]->str_value_),
                                              static_cast<int32_t>(alias_node->children_[0]->str_len_));
O
oceanbase-admin 已提交
3265 3266 3267 3268 3269 3270 3271 3272
        bool found = false;
        for (int64_t j = 0; OB_SUCC(ret) && j < cte_ctx_.cte_col_names_.count() && !found; ++j) {
          if (ObCharset::case_insensitive_equal(cte_ctx_.cte_col_names_.at(j), column_alia_name)) {
            found = true;
          }
        }
        if (!found) {
          ret = OB_ERR_CTE_ILLEGAL_COLUMN_IN_SERACH_CALUSE;
W
wangzelin.wzl 已提交
3273
          LOG_WARN("element in sort specification list of SEARCH clause did not appear in the column alias list of the WITH clause element", K(ret));
O
oceanbase-admin 已提交
3274 3275 3276 3277 3278
        }
      }
    }
  }
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
3279
    const ParseNode *set_value = search_set_clause->children_[1];
O
oceanbase-admin 已提交
3280
    ObString set_column_name;
W
wangzelin.wzl 已提交
3281 3282
    set_column_name.assign_ptr((char *) (set_value->str_value_),
                               static_cast<int32_t>(set_value->str_len_));
O
oceanbase-admin 已提交
3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296
    bool found = false;
    for (int64_t i = 0; OB_SUCC(ret) && i < cte_ctx_.cte_col_names_.count() && !found; ++i) {
      if (ObCharset::case_insensitive_equal(cte_ctx_.cte_col_names_.at(i), set_column_name)) {
        found = true;
      }
    }
    if (found) {
      ret = OB_ERR_CTE_ILLEGAL_SEARCH_PSEUDO_NAME;
      LOG_WARN("sequence column name for SEARCH clause must not be part of the column alias list", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3297
int ObSelectResolver::check_search_cycle_set_column(const ParseNode &search_node, const ParseNode &cycle_node) {
O
oceanbase-admin 已提交
3298 3299 3300 3301
  int ret = OB_SUCCESS;
  const ParseNode* search_set_clause = search_node.children_[1]->children_[1];
  const ParseNode* cycle_set_clause = cycle_node.children_[1]->children_[1];
  ObString search_set_column_name;
W
wangzelin.wzl 已提交
3302 3303
  search_set_column_name.assign_ptr((char *) (search_set_clause->str_value_),
                                    static_cast<int32_t>(search_set_clause->str_len_));
O
oceanbase-admin 已提交
3304
  ObString cycle_set_column_name;
W
wangzelin.wzl 已提交
3305 3306
  cycle_set_column_name.assign_ptr((char *) (cycle_set_clause->str_value_),
                                   static_cast<int32_t>(cycle_set_clause->str_len_));
O
oceanbase-admin 已提交
3307 3308 3309 3310 3311 3312 3313 3314

  if (ObCharset::case_insensitive_equal(search_set_column_name, cycle_set_column_name)) {
    ret = OB_ERR_CTE_DUPLICATE_SEQ_NAME_CYCLE_COLUMN;
    LOG_WARN("sequence column for SEARCH clause must be different from the cycle mark column for CYCLE clause", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
3315
int ObSelectResolver::check_cycle_values(const ParseNode &cycle_node) {
O
oceanbase-admin 已提交
3316 3317
  int ret = OB_SUCCESS;
  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
3318 3319
    if (cycle_node.children_[2]->str_len_ != 1
        || cycle_node.children_[3]->str_len_ != 1) {
O
oceanbase-admin 已提交
3320 3321 3322 3323 3324 3325 3326
      ret = OB_ERR_CTE_ILLEGAL_CYCLE_NON_CYCLE_VALUE;
      LOG_WARN("cycle mark value and non-cycle mark value must be one byte character string values", K(ret));
    } else {
      const ParseNode* cycle_value_node = cycle_node.children_[2];
      const ParseNode* non_cycle_value_node = cycle_node.children_[3];
      ObString cycle_value;
      ObString non_cycle_value;
W
wangzelin.wzl 已提交
3327 3328 3329 3330
      cycle_value.assign_ptr((char *) (cycle_value_node->str_value_),
                            static_cast<int32_t>(cycle_value_node->str_len_));
      non_cycle_value.assign_ptr((char *) (non_cycle_value_node->str_value_),
                                static_cast<int32_t>(non_cycle_value_node->str_len_));
O
oceanbase-admin 已提交
3331 3332 3333 3334 3335 3336 3337 3338 3339
      if (ObCharset::case_insensitive_equal(cycle_value, non_cycle_value)) {
        ret = OB_ERR_CTE_DUPLICATE_CYCLE_NON_CYCLE_VALUE;
        LOG_WARN("cycle value for CYCLE clause must be different from the non-cycle value", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3340
int ObSelectResolver::check_cte_pseudo(const ParseNode *search_node, const ParseNode *cycle_node) {
O
oceanbase-admin 已提交
3341 3342
  int ret = OB_SUCCESS;
  // For oracle error code compatibility
W
wangzelin.wzl 已提交
3343 3344
  if ((OB_NOT_NULL(search_node) || OB_NOT_NULL(cycle_node))
      && cte_ctx_.cte_col_names_.empty()) {
O
oceanbase-admin 已提交
3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368
    ret = OB_ERR_CTE_NEED_COLUMN_ALIAS_LIST;
    LOG_WARN("WITH clause element did not have a column alias list", K(ret));
  }

  if (OB_NOT_NULL(search_node)) {
    if (OB_FAIL(check_search_clause(*search_node))) {
      LOG_WARN("Invalid search clause", K(ret));
    }
  }

  if (OB_SUCC(ret) && OB_NOT_NULL(cycle_node)) {
    if (OB_FAIL(check_cycle_clause(*cycle_node))) {
      LOG_WARN("Invalid cycle clause", K(ret));
    }
  }

  if (OB_SUCC(ret) && OB_NOT_NULL(cycle_node) && OB_NOT_NULL(search_node)) {
    if (OB_FAIL(check_search_cycle_set_column(*search_node, *cycle_node))) {
      LOG_WARN("Invalid search/cycle clause", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3369 3370 3371 3372 3373
int ObSelectResolver::resolve_cte_pseudo_column(const ParseNode *search_node,
                                                const ParseNode *cycle_node,
                                                const TableItem *table_item,
                                                ObString &search_pseudo_column_name,
                                                ObString &cycle_pseudo_column_name)
O
oceanbase-admin 已提交
3374 3375
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3376 3377
  if(OB_ISNULL(table_item)) {
    //do nothing
O
oceanbase-admin 已提交
3378 3379 3380 3381 3382 3383 3384

  } else if (OB_ISNULL(table_item->ref_query_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("the recursive union can not be null", K(ret));
  } else {

    if (OB_SUCC(ret) && OB_NOT_NULL(search_node)) {
W
wangzelin.wzl 已提交
3385 3386
      OZ( resolve_search_clause(*search_node, table_item, search_pseudo_column_name) );
      OZ( check_pseudo_column_name_legal(search_pseudo_column_name) );
O
oceanbase-admin 已提交
3387 3388 3389
    }

    if (OB_SUCC(ret) && OB_NOT_NULL(cycle_node)) {
W
wangzelin.wzl 已提交
3390 3391
      OZ( resolve_cycle_clause(*cycle_node, table_item, cycle_pseudo_column_name) );
      OZ( check_pseudo_column_name_legal(cycle_pseudo_column_name) );
O
oceanbase-admin 已提交
3392 3393 3394 3395 3396 3397 3398 3399 3400
    }
  }

  if (OB_SUCC(ret) && OB_NOT_NULL(cycle_node)) {
    if (OB_FAIL(check_cycle_values(*cycle_node))) {
      LOG_WARN("Invalid cycle/non-cycle values", K(ret));
    }
  }

W
wangzelin.wzl 已提交
3401 3402 3403 3404
  if (OB_SUCC(ret)
      && !(table_item->ref_query_->is_recursive_union())
      && (OB_NOT_NULL(cycle_node) || OB_NOT_NULL(search_node))) {
    //oracle 默认非递归的CTE不可以使用search和cycle
O
oceanbase-admin 已提交
3405 3406 3407 3408 3409 3410
    ret = OB_ERR_CTE_ILLEGAL_SEARCH_CYCLE_CLAUSE;
    LOG_WARN("SEARCH and CYCLE clauses can only be specified for recursive WITH clause elements", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
3411
int ObSelectResolver::add_parent_cte_table_item(TableItem *table_item) {
O
oceanbase-admin 已提交
3412 3413 3414 3415 3416 3417 3418
  int ret = OB_SUCCESS;
  if (OB_FAIL(parent_cte_tables_.push_back(table_item))) {
    LOG_WARN("add parent cte table failed", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
3419
int ObSelectResolver::resolve_from_clause(const ParseNode *node)
O
oceanbase-admin 已提交
3420 3421 3422 3423
{
  int ret = OB_SUCCESS;
  if (OB_NOT_NULL(node)) {
    current_scope_ = T_FROM_SCOPE;
W
wangzelin.wzl 已提交
3424 3425 3426 3427 3428
    ObSelectStmt *select_stmt = NULL;
    TableItem *table_item = NULL;
    CK( OB_NOT_NULL(select_stmt = get_select_stmt()),
        node->type_ == T_FROM_LIST,
        node->num_child_ >= 1);
O
oceanbase-admin 已提交
3429
    for (int32_t i = 0; OB_SUCC(ret) && i < node->num_child_; i += 1) {
W
wangzelin.wzl 已提交
3430
      ParseNode *table_node = node->children_[i];
O
oceanbase-admin 已提交
3431
      CK(OB_NOT_NULL(table_node));
W
wangzelin.wzl 已提交
3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448
      const bool old_flag = session_info_->is_table_name_hidden();
      bool is_table_hidden = false;
      const ObSessionDDLInfo &ddl_info = session_info_->get_ddl_info();
      // add foreign key will use select xx from t1 minus select xx from t2, here t1 is source table, t2 is dest table
      if (ddl_info.is_ddl()) {
        if (in_set_query_) {
          is_table_hidden = is_left_child_ ? ddl_info.is_source_table_hidden() : ddl_info.is_dest_table_hidden();
        } else {
          is_table_hidden = ddl_info.is_source_table_hidden();
        }
      }
      // TODO@wenqu: wait flags from session info
      session_info_->set_table_name_hidden(is_table_hidden);
      OZ( resolve_table(*table_node, table_item) );
      session_info_->set_table_name_hidden(old_flag);
      OZ( column_namespace_checker_.add_reference_table(table_item), table_item );
      OZ( select_stmt->add_from_item(table_item->table_id_, table_item->is_joined_table()) );
O
oceanbase-admin 已提交
3449
      // oracle outer join will change from items
W
wangzelin.wzl 已提交
3450
      OZ( add_from_items_order(table_item), table_item );
O
obdev 已提交
3451 3452 3453
      if (OB_SUCC(ret)) {
        select_stmt->set_has_reverse_link(table_item->is_reverse_link_);
      }
O
oceanbase-admin 已提交
3454
    }
W
wangzelin.wzl 已提交
3455 3456
    OZ( gen_unpivot_target_column(node->num_child_, *select_stmt, *table_item) );
    OZ( check_recursive_cte_usage(*select_stmt) );
O
oceanbase-admin 已提交
3457 3458 3459 3460
  }
  return ret;
}

W
wangzelin.wzl 已提交
3461 3462
int ObSelectResolver::gen_unpivot_target_column(const int64_t table_count,
    ObSelectStmt &select_stmt, TableItem &table_item)
O
oceanbase-admin 已提交
3463 3464 3465 3466
{
  int ret = OB_SUCCESS;
  if (NULL != transpose_item_ && 1 == table_count) {
    select_stmt.set_from_pivot(transpose_item_->is_pivot());
W
wangzelin.wzl 已提交
3467
     //mark this stmt is transpose item
O
oceanbase-admin 已提交
3468
    if (transpose_item_->is_unpivot() && transpose_item_->need_use_unpivot_op()) {
W
wangzelin.wzl 已提交
3469 3470
      //use unpivot operation
      select_stmt.set_transpose_item(const_cast<TransposeItem *>(transpose_item_));
O
oceanbase-admin 已提交
3471 3472

      const int64_t old_column_count = transpose_item_->old_column_count_;
W
wangzelin.wzl 已提交
3473 3474
      const int64_t new_column_count = transpose_item_->unpivot_columns_.count()
                                        + transpose_item_->for_columns_.count();
O
oceanbase-admin 已提交
3475

W
wangzelin.wzl 已提交
3476
      ObSelectStmt *child_select_stmt = table_item.ref_query_;
O
oceanbase-admin 已提交
3477 3478 3479
      int64_t select_item_count = 0;
      ObCollationType coll_type = CS_TYPE_INVALID;
      LOG_DEBUG("begin gen_unpivot_target_column", K(table_item), KPC(child_select_stmt));
W
wangzelin.wzl 已提交
3480 3481 3482 3483 3484 3485 3486 3487 3488 3489
      if (OB_ISNULL(params_.expr_factory_)
          || OB_ISNULL(session_info_)
          || OB_ISNULL(child_select_stmt)
          || FALSE_IT(select_item_count = child_select_stmt->get_select_item_size())
          || OB_UNLIKELY(new_column_count < 0)
          || OB_UNLIKELY(old_column_count < 0)
          || OB_UNLIKELY(old_column_count >= select_item_count)
          || OB_UNLIKELY((select_item_count - old_column_count) % new_column_count != 0)
          || OB_UNLIKELY((select_item_count - old_column_count) / new_column_count <= 1)
          ) {
O
oceanbase-admin 已提交
3490
        ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
3491 3492 3493
        LOG_WARN("params is invalid", K(ret), K(table_item),
                 K(params_.expr_factory_), K(old_column_count), K(new_column_count),
                 K(select_item_count), KPC(child_select_stmt));
O
oceanbase-admin 已提交
3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506
      } else if (OB_FAIL(session_info_->get_collation_connection(coll_type))) {
        LOG_WARN("fail to get_collation_connection", K(ret));
      } else {
        const ObLengthSemantics default_ls = session_info_->get_actual_nls_length_semantics();
        ObSEArray<ObExprResType, 16> types;
        ObExprResType res_type;
        ObExprVersion dummy_op(*allocator_);

        for (int64_t colum_idx = 0; OB_SUCC(ret) && colum_idx < new_column_count; colum_idx++) {
          res_type.reset();
          types.reset();

          int64_t item_idx = old_column_count + colum_idx;
W
wangzelin.wzl 已提交
3507
          SelectItem &first_select_item = child_select_stmt->get_select_item(item_idx);
O
oceanbase-admin 已提交
3508 3509 3510 3511 3512 3513 3514 3515
          item_idx += new_column_count;
          if (OB_ISNULL(first_select_item.expr_)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("expr is null", K(ret), K(first_select_item.expr_));
          } else if (types.push_back(first_select_item.expr_->get_result_type())) {
            LOG_WARN("fail to push left_type", K(ret));
          }
          while (OB_SUCC(ret) && item_idx < select_item_count) {
W
wangzelin.wzl 已提交
3516 3517
            SelectItem &tmp_select_item = child_select_stmt->get_select_item(item_idx);
            if (OB_ISNULL(tmp_select_item.expr_) ) {
O
oceanbase-admin 已提交
3518 3519
              ret = OB_ERR_UNEXPECTED;
              LOG_WARN("expr is null", K(ret), K(tmp_select_item.expr_));
W
wangzelin.wzl 已提交
3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530
            } else if (first_select_item.expr_->get_result_type()
                       != tmp_select_item.expr_->get_result_type()) {
              const ObExprResType &first_type = first_select_item.expr_->get_result_type();
              const ObExprResType &tmp_type = tmp_select_item.expr_->get_result_type();
              if (!((first_type.is_null() && !tmp_type.is_lob())
                    || (tmp_type.is_null() && !first_type.is_lob())
                    || (first_type.is_character_type() && tmp_type.is_character_type())
                    || (ob_is_oracle_numeric_type(first_type.get_type())
                        && ob_is_oracle_numeric_type(tmp_type.get_type()))
                    || (ob_is_oracle_temporal_type(first_type.get_type())
                        && (ob_is_oracle_temporal_type(tmp_type.get_type()))))) {
O
oceanbase-admin 已提交
3531
                ret = OB_ERR_EXP_NEED_SAME_DATATYPE;
W
wangzelin.wzl 已提交
3532 3533 3534 3535 3536
                LOG_WARN("expression must have same datatype as corresponding expression", K(ret),
                         K(first_type), K(tmp_type));
              } else if (first_type.is_character_type()
                         && tmp_type.is_character_type()
                         && (first_type.is_varchar_or_char() != tmp_type.is_varchar_or_char())) {
O
oceanbase-admin 已提交
3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548
                ret = OB_ERR_CHARACTER_SET_MISMATCH;
                LOG_WARN("character set mismatch", K(ret), K(first_type), K(tmp_type));
              } else if (OB_FAIL(types.push_back(tmp_type))) {
                LOG_WARN("fail to push type", K(ret), K(tmp_type));
              }
            }
            item_idx += new_column_count;
          }

          if (OB_SUCC(ret)) {
            if (types.count() == 1) {
              res_type = first_select_item.expr_->get_result_type();
W
wangzelin.wzl 已提交
3549 3550 3551 3552 3553 3554 3555
            } else if (OB_FAIL(dummy_op.aggregate_result_type_for_merge(res_type,
                                                                        &types.at(0),
                                                                        types.count(),
                                                                        coll_type,
                                                                        true,
                                                                        default_ls,
                                                                        session_info_))) {
O
oceanbase-admin 已提交
3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566
              LOG_WARN("fail to aggregate_result_type_for_merge", K(ret), K(types));
            }
          }

          if (OB_SUCC(ret)) {
            if (OB_UNLIKELY(ObNullType == res_type.get_type() || ObMaxType == res_type.get_type())) {
              ret = OB_ERR_INVALID_TYPE_FOR_OP;
              LOG_WARN("column type incompatible", K(ret), K(res_type));
            } else {
              item_idx = old_column_count + colum_idx;
              while (OB_SUCC(ret) && item_idx < select_item_count) {
W
wangzelin.wzl 已提交
3567
                SelectItem &select_item = child_select_stmt->get_select_item(item_idx);
O
oceanbase-admin 已提交
3568
                if (select_item.expr_->get_result_type() != res_type) {
W
wangzelin.wzl 已提交
3569 3570 3571 3572 3573 3574
                  ObSysFunRawExpr *new_expr = NULL;
                  if (OB_FAIL(ObRawExprUtils::create_cast_expr(*params_.expr_factory_,
                                                               select_item.expr_,
                                                               res_type,
                                                               new_expr,
                                                               session_info_))) {
O
oceanbase-admin 已提交
3575
                    LOG_WARN("create cast expr for stmt failed", K(ret));
3576 3577
                  } else if (OB_FAIL(new_expr->add_flag(IS_INNER_ADDED_EXPR))) {
                    LOG_WARN("failed to add flag", K(ret));
O
oceanbase-admin 已提交
3578 3579 3580 3581 3582 3583 3584 3585 3586
                  } else {
                    select_item.expr_ = new_expr;
                    LOG_DEBUG("add cast for column", K(select_item), K(res_type));
                  }
                }
                item_idx += new_column_count;
              }
            }
          }
W
wangzelin.wzl 已提交
3587
        }//end of for
O
oceanbase-admin 已提交
3588 3589 3590
      }
      LOG_DEBUG("finish gen_unpivot_target_column", K(table_item), KPC(child_select_stmt));
    }
W
wangzelin.wzl 已提交
3591
    //reset
O
oceanbase-admin 已提交
3592 3593 3594 3595 3596
    transpose_item_ = NULL;
  }
  return ret;
}

W
wangzelin.wzl 已提交
3597
int ObSelectResolver::resolve_group_clause(const ParseNode *node)
O
oceanbase-admin 已提交
3598 3599 3600
{
  int ret = OB_SUCCESS;
  bool has_explicit_dir = false;
W
wangzelin.wzl 已提交
3601
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
3602 3603 3604
  common::ObIArray<ObRawExpr*>& groupby_exprs = select_stmt->get_group_exprs();
  common::ObIArray<ObRawExpr*>& rollup_exprs = select_stmt->get_rollup_exprs();
  common::ObSEArray<OrderItem, 4> order_items;
W
wangzelin.wzl 已提交
3605 3606 3607 3608 3609 3610
  if (OB_ISNULL(node)) {//do nothing for has no groupby clause.
  } else if (OB_FAIL(resolve_group_by_list(node,
                                           groupby_exprs,
                                           rollup_exprs,
                                           order_items,
                                           has_explicit_dir))) {
O
oceanbase-admin 已提交
3611 3612 3613 3614 3615 3616 3617
    LOG_WARN("failed to resolve group rollup list.", K(ret));
  } else if (!has_explicit_dir) {
    /* do nothing. */
  } else if (rollup_exprs.count() > 0) {
    for (int64_t i = 0; OB_SUCC(ret) && i < order_items.count(); i++) {
      if (OB_FAIL(select_stmt->add_rollup_dir(order_items.at(i).order_type_))) {
        LOG_WARN("failed to push back to order items.", K(ret));
W
wangzelin.wzl 已提交
3618
      } else {/* do nothing. */}
O
oceanbase-admin 已提交
3619 3620
    }
  } else if (OB_FAIL(append(select_stmt->get_order_items(), order_items))) {
W
wangzelin.wzl 已提交
3621 3622
      LOG_WARN("failed to append order itmes by groupby into select stmt.", K(ret));
  } else { /* do nothing. */}
O
oceanbase-admin 已提交
3623

W
wangzelin.wzl 已提交
3624
  //for mysql mode, check grouping here
O
oceanbase-admin 已提交
3625 3626
  if (OB_FAIL(ret) || is_oracle_mode()) {
    /*do nothing*/
W
wangzelin.wzl 已提交
3627
  } else if (rollup_exprs.count() <= 0 && has_grouping()) {
O
oceanbase-admin 已提交
3628 3629 3630 3631
    ret = OB_ERR_WRONG_FIELD_WITH_GROUP;
    LOG_WARN("the grouping must be with be roll up clause", K(ret));
  } else if (OB_FAIL(check_grouping_columns())) {
    LOG_WARN("failed to check grouping columns", K(ret));
W
wangzelin.wzl 已提交
3632
  } // do nothing
O
oceanbase-admin 已提交
3633 3634 3635 3636

  return ret;
}

O
obdev 已提交
3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660
int ObSelectResolver::check_rollup_clause(const ParseNode *node, bool &has_rollup)
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(node) || OB_ISNULL(node->children_) ||
      OB_UNLIKELY(T_GROUPBY_CLAUSE != node->type_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid resolver arguments", K(ret), K(node));
  } else {
    for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) {
      const ParseNode *child_node = node->children_[i];
      if (OB_ISNULL(child_node)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret), K(child_node));
      } else if (child_node->type_ == T_ROLLUP_LIST ||
                 child_node->type_ == T_CUBE_LIST ||
                 child_node->type_ == T_GROUPING_SETS_LIST ||
                 child_node->type_ == T_WITH_ROLLUP_CLAUSE) {
        has_rollup = true;
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3661 3662 3663 3664 3665
int ObSelectResolver::resolve_group_by_list(const ParseNode *node,
                                            common::ObIArray<ObRawExpr*> &groupby_exprs,
                                            common::ObIArray<ObRawExpr*> &rollup_exprs,
                                            common::ObIArray<OrderItem> &order_items,
                                            bool &has_explicit_dir)
O
oceanbase-admin 已提交
3666 3667
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3668
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
3669 3670 3671 3672 3673 3674 3675 3676
  current_scope_ = T_GROUP_SCOPE;
  if (OB_ISNULL(node) || OB_ISNULL(node->children_) || OB_ISNULL(select_stmt) ||
      OB_UNLIKELY(T_GROUPBY_CLAUSE != node->type_)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid resolver arguments", K(ret), K(node), K(select_stmt));
  } else {
    bool can_conv_multi_rollup = true;
    for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) {
W
wangzelin.wzl 已提交
3677
      const ParseNode *child_node = node->children_[i];
O
oceanbase-admin 已提交
3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691
      if (OB_ISNULL(child_node)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret), K(child_node));
      } else {
        switch (child_node->type_) {
          case T_NULL: {
            /*compatible oracle: select c1 from t1 group by c1, (); do nothing, just skip*/
            break;
          }
          case T_GROUPBY_KEY: {
            if (OB_ISNULL(child_node->children_) || OB_UNLIKELY(child_node->num_child_ != 1)) {
              ret = OB_INVALID_ARGUMENT;
              LOG_WARN("invalid resolver arguments", K(ret), K(child_node));
            } else if (OB_FAIL(resolve_groupby_node(child_node->children_[0],
W
wangzelin.wzl 已提交
3692 3693 3694 3695 3696 3697 3698
                                                    child_node,
                                                    groupby_exprs,
                                                    rollup_exprs,
                                                    order_items,
                                                    has_explicit_dir,
                                                    true,
                                                    0))) {// 0 level.
O
oceanbase-admin 已提交
3699
              LOG_WARN("failed to resolve group node.", K(ret));
W
wangzelin.wzl 已提交
3700
            } else {/*do nothing*/}
O
oceanbase-admin 已提交
3701 3702 3703 3704
            break;
          }
          case T_ROLLUP_LIST: {
            ObMultiRollupItem rollup_item;
W
wangzelin.wzl 已提交
3705 3706 3707
            if (OB_FAIL(resolve_rollup_list(child_node,
                                            rollup_item,
                                            can_conv_multi_rollup))) {
O
oceanbase-admin 已提交
3708 3709 3710 3711 3712 3713 3714 3715
              LOG_WARN("failed to resolve rollup list", K(ret));
            } else if (OB_FAIL(select_stmt->add_rollup_item(rollup_item))) {
              LOG_WARN("failed to add rollup item", K(ret));
            }
            break;
          }
          case T_CUBE_LIST: {
            ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
3716 3717
            LOG_USER_ERROR(OB_NOT_SUPPORTED, "group by cube");
            LOG_WARN("cube by not supported.", K(ret));//TODO, @jiangxiu.wt
O
oceanbase-admin 已提交
3718 3719 3720
            break;
          }
          case T_GROUPING_SETS_LIST: {
W
wangzelin.wzl 已提交
3721 3722 3723 3724 3725 3726 3727
            HEAP_VAR(ObGroupingSetsItem, grouping_sets_item) {
              if (OB_FAIL(resolve_grouping_sets_list(child_node,
                                                     grouping_sets_item))) {
                LOG_WARN("failed to resolve rollup list", K(ret));
              } else if (OB_FAIL(select_stmt->add_grouping_sets_item(grouping_sets_item))) {
                LOG_WARN("failed to add grouping sets item", K(ret));
              } else {/*do nothing*/}
O
oceanbase-admin 已提交
3728 3729 3730 3731
            }
            break;
          }
          case T_WITH_ROLLUP_CLAUSE: {
W
wangzelin.wzl 已提交
3732 3733 3734 3735 3736
            if (OB_FAIL(resolve_with_rollup_clause(child_node,
                                                   groupby_exprs,
                                                   rollup_exprs,
                                                   order_items,
                                                   has_explicit_dir))) {
O
oceanbase-admin 已提交
3737
              LOG_WARN("failed to resolve with rollup clause", K(ret));
W
wangzelin.wzl 已提交
3738
            } else {/*do nothing*/}
O
oceanbase-admin 已提交
3739 3740 3741 3742
            break;
          }
          default: {
            /* won't be here */
W
wangzelin.wzl 已提交
3743 3744
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("unexpected group by type", K(ret), K(get_type_name(child_node->type_)));
O
oceanbase-admin 已提交
3745 3746 3747 3748 3749 3750
            break;
          }
        }
      }
    }
    if (OB_SUCC(ret) && can_conv_multi_rollup && select_stmt->get_multi_rollup_items_size() == 1) {
W
wangzelin.wzl 已提交
3751 3752
      const ObIArray<ObGroupbyExpr> &rollup_list_exprs =
                                     select_stmt->get_multi_rollup_items().at(0).rollup_list_exprs_;
O
oceanbase-admin 已提交
3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768
      for (int64_t i = 0; OB_SUCC(ret) && i < rollup_list_exprs.count(); ++i) {
        if (OB_UNLIKELY(rollup_list_exprs.at(i).groupby_exprs_.count() != 1)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get unexpected error", K(ret), K(rollup_list_exprs.at(i).groupby_exprs_));
        } else if (OB_FAIL(rollup_exprs.push_back(rollup_list_exprs.at(i).groupby_exprs_.at(0)))) {
          LOG_WARN("failed to push back exprs", K(ret));
        }
      }
      if (OB_SUCC(ret)) {
        select_stmt->get_multi_rollup_items().reset();
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3769 3770 3771
int ObSelectResolver::resolve_rollup_list(const ParseNode *node,
                                          ObMultiRollupItem &rollup_item,
                                          bool &can_conv_multi_rollup)
O
oceanbase-admin 已提交
3772 3773
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3774
  if (OB_ISNULL(node) || OB_UNLIKELY(node->type_ != T_ROLLUP_LIST || !lib::is_oracle_mode())) {
O
oceanbase-admin 已提交
3775 3776 3777 3778 3779 3780 3781 3782
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("get invalid argument", K(ret), K(node));
  } else {
    ObSEArray<ObRawExpr*, 4> dummy_groupby_exprs;
    ObSEArray<OrderItem, 4> dummy_order_items;
    bool dummy_has_explicit_dir = false;
    for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) {
      ObGroupbyExpr item;
W
wangzelin.wzl 已提交
3783
      const ParseNode *group_key_node = node->children_[i];
O
oceanbase-admin 已提交
3784
      if (OB_ISNULL(group_key_node) ||
W
wangzelin.wzl 已提交
3785 3786
          OB_UNLIKELY(group_key_node->type_ != T_GROUPBY_KEY ||
                      group_key_node->num_child_ != 1)) {
O
oceanbase-admin 已提交
3787 3788 3789
        ret = OB_INVALID_ARGUMENT;
        LOG_WARN("invalid resolver arguments", K(ret), K(group_key_node));
      } else if (OB_FAIL(resolve_groupby_node(group_key_node->children_[0],
W
wangzelin.wzl 已提交
3790 3791 3792 3793 3794 3795 3796
                                              group_key_node,
                                              dummy_groupby_exprs,
                                              item.groupby_exprs_,
                                              dummy_order_items,
                                              dummy_has_explicit_dir,
                                              false,
                                              0))) {// 0 level.
O
oceanbase-admin 已提交
3797 3798 3799
        LOG_WARN("failed to resolve group node.", K(ret));
      } else if (OB_FAIL(rollup_item.rollup_list_exprs_.push_back(item))) {
        LOG_WARN("failed to push back item", K(ret));
W
wangzelin.wzl 已提交
3800
      } else if (item.groupby_exprs_.count() > 1) {//description includes vector rollup
O
oceanbase-admin 已提交
3801 3802 3803 3804 3805 3806 3807
        can_conv_multi_rollup = false;
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3808 3809
int ObSelectResolver::resolve_grouping_sets_list(const ParseNode *node,
                                                 ObGroupingSetsItem &grouping_sets_item)
O
oceanbase-admin 已提交
3810 3811
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3812
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
3813
  if (OB_ISNULL(select_stmt) || OB_ISNULL(node) ||
W
wangzelin.wzl 已提交
3814
      OB_UNLIKELY(node->type_ != T_GROUPING_SETS_LIST || !lib::is_oracle_mode())) {
O
oceanbase-admin 已提交
3815 3816 3817 3818 3819 3820 3821
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("get invalid argument", K(ret), K(select_stmt), K(node));
  } else {
    ObSEArray<ObRawExpr*, 4> dummy_rollup_exprs;
    ObSEArray<OrderItem, 4> dummy_order_items;
    bool dummy_has_explicit_dir = false;
    for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) {
W
wangzelin.wzl 已提交
3822
      const ParseNode *child_node = node->children_[i];
O
oceanbase-admin 已提交
3823 3824 3825 3826 3827 3828 3829
      if (OB_ISNULL(child_node)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret), K(child_node));
      } else {
        ObGroupbyExpr item;
        switch (child_node->type_) {
          case T_NULL: {
W
wangzelin.wzl 已提交
3830
            //for grouping sets may occur this situation:
O
oceanbase-admin 已提交
3831 3832 3833
            //  select count(c1) from t1 group by grouping sets(c1, ());
            // <==>
            //  select count(c1) from t1 group by c1 union all select count(c1) from t1;
W
wangzelin.wzl 已提交
3834
            //we should consider it to compatible oracle better.
O
oceanbase-admin 已提交
3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845
            if (OB_FAIL(grouping_sets_item.grouping_sets_exprs_.push_back(item))) {
              LOG_WARN("failed to push back into gs exprs.", K(ret));
            }
            break;
          }
          case T_GROUPBY_KEY: {
            ObGroupbyExpr item;
            if (OB_ISNULL(child_node->children_) || OB_UNLIKELY(child_node->num_child_ != 1)) {
              ret = OB_INVALID_ARGUMENT;
              LOG_WARN("invalid resolver arguments", K(ret), K(child_node));
            } else if (OB_FAIL(resolve_groupby_node(child_node->children_[0],
W
wangzelin.wzl 已提交
3846 3847 3848 3849 3850 3851 3852
                                                    child_node,
                                                    item.groupby_exprs_,
                                                    dummy_rollup_exprs,
                                                    dummy_order_items,
                                                    dummy_has_explicit_dir,
                                                    true,
                                                    0))) {// 0 level.
O
oceanbase-admin 已提交
3853 3854 3855 3856 3857 3858 3859 3860 3861
              LOG_WARN("failed to resolve group node.", K(ret));
            } else if (OB_FAIL(grouping_sets_item.grouping_sets_exprs_.push_back(item))) {
              LOG_WARN("failed to push back into gs exprs.", K(ret));
            }
            break;
          }
          case T_ROLLUP_LIST: {
            ObMultiRollupItem rollup_item;
            bool can_conv_multi_rollup = false;
W
wangzelin.wzl 已提交
3862 3863 3864
            if (OB_FAIL(resolve_rollup_list(child_node,
                                            rollup_item,
                                            can_conv_multi_rollup))) {
O
oceanbase-admin 已提交
3865 3866 3867 3868 3869 3870 3871 3872
              LOG_WARN("failed to resolve rollup list", K(ret));
            } else if (OB_FAIL(grouping_sets_item.multi_rollup_items_.push_back(rollup_item))) {
              LOG_WARN("failed to add grouping sets item", K(ret));
            }
            break;
          }
          case T_CUBE_LIST: {
            ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
3873 3874
            LOG_USER_ERROR(OB_NOT_SUPPORTED, "cube in grouping sets");
            LOG_WARN("cube/rollup in groupings sets not supported.", K(ret));//TODO, @jiangxiu.wt
O
oceanbase-admin 已提交
3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889
            break;
          }
          default: {
            /* won't be here */
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("get unexpected type", K(ret), K(get_type_name(child_node->type_)));
            break;
          }
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3890 3891 3892 3893 3894 3895

int ObSelectResolver::resolve_with_rollup_clause(const ParseNode *node,
                                                 common::ObIArray<ObRawExpr*> &groupby_exprs,
                                                 common::ObIArray<ObRawExpr*> &rollup_exprs,
                                                 common::ObIArray<OrderItem> &order_items,
                                                 bool &has_explicit_dir)
O
oceanbase-admin 已提交
3896 3897
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3898 3899
  const ParseNode *sort_list_node = NULL;
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
3900 3901
  // for: select a, sum(b) from t group by a with rollup.
  // with rollup is the children[0] and sort key list is children[1].
W
wangzelin.wzl 已提交
3902
  if (OB_ISNULL(node) || OB_ISNULL(select_stmt) || OB_UNLIKELY(!lib::is_mysql_mode()) ||
O
oceanbase-admin 已提交
3903 3904 3905 3906 3907
      OB_UNLIKELY(T_WITH_ROLLUP_CLAUSE != node->type_ || node->num_child_ != 2) ||
      OB_ISNULL(sort_list_node = node->children_[1])) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("get invalid argument", K(ret), K(node), K(sort_list_node), K(select_stmt));
  } else {
W
wangzelin.wzl 已提交
3908
    bool has_rollup = false;
O
oceanbase-admin 已提交
3909 3910 3911 3912 3913
    if (node->children_[0] != NULL) {
      if (node->children_[0]->type_ != T_ROLLUP) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get invalid type", K(get_type_name(node->children_[0]->type_)));
      } else {
W
wangzelin.wzl 已提交
3914
        has_rollup = true;
O
oceanbase-admin 已提交
3915 3916 3917
      }
    }
    for (int64_t i = 0; OB_SUCC(ret) && i < sort_list_node->num_child_; ++i) {
W
wangzelin.wzl 已提交
3918
      const ParseNode *sort_node = sort_list_node->children_[i];
O
oceanbase-admin 已提交
3919 3920 3921 3922 3923
      if (OB_ISNULL(sort_node) || OB_ISNULL(sort_node->children_) ||
          OB_UNLIKELY(T_SORT_KEY != sort_node->type_ || sort_node->num_child_ != 2)) {
        ret = OB_INVALID_ARGUMENT;
        LOG_WARN("invalid resolver arguments", K(ret));
      } else if (OB_FAIL(resolve_groupby_node(sort_node->children_[0],
W
wangzelin.wzl 已提交
3924 3925 3926 3927 3928 3929 3930
                                              sort_node,
                                              groupby_exprs,
                                              rollup_exprs,
                                              order_items,
                                              has_explicit_dir,
                                              !(select_stmt->has_rollup() || has_rollup),
                                              0))) {// 0 level.
O
oceanbase-admin 已提交
3931
        LOG_WARN("failed to resolve group node.", K(ret));
W
wangzelin.wzl 已提交
3932
      } else  {/*do nothing*/}
O
oceanbase-admin 已提交
3933 3934 3935 3936 3937
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
3938 3939 3940 3941 3942 3943 3944 3945
int ObSelectResolver::resolve_group_by_sql_expr(const ParseNode *group_node,
                                                const ParseNode *group_sort_node,
                                                common::ObIArray<ObRawExpr*> &groupby_exprs,
                                                common::ObIArray<ObRawExpr*> &rollup_exprs,
                                                common::ObIArray<OrderItem> &order_items,
                                                ObSelectStmt *select_stmt,
                                                bool &has_explicit_dir,
                                                bool is_groupby_expr)
O
oceanbase-admin 已提交
3946 3947
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
3948
  ObRawExpr *expr = NULL;
O
oceanbase-admin 已提交
3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968
  bool is_oracle_compatible = is_oracle_mode();
  if (OB_ISNULL(group_node)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid resolver arguments", K(ret));
  } else if (!is_oracle_compatible && group_node->type_ == T_INT) {
    int64_t pos = group_node->value_;
    if (pos <= 0 || pos > select_stmt->get_select_item_size()) {
      ret = OB_ERR_BAD_FIELD_ERROR;
      char buff[OB_MAX_ERROR_MSG_LEN];
      snprintf(buff, OB_MAX_ERROR_MSG_LEN, "%ld", pos);
      ObString scope_name = ObString::make_string(get_scope_name(current_scope_));
      LOG_USER_ERROR(OB_ERR_BAD_FIELD_ERROR, (int)strlen(buff), buff, scope_name.length(), scope_name.ptr());
    }
    if (OB_SUCC(ret)) {
      expr = select_stmt->get_select_item(pos - 1).expr_;
      if (!expr) {
        ret = OB_ERR_ILLEGAL_ID;
        LOG_WARN("Can not find expression", K(expr), K(ret));
      } else if (expr->has_flag(CNT_AGG) || expr->has_flag(CNT_WINDOW_FUNC)) {
        ret = OB_WRONG_GROUP_FIELD;
W
wangzelin.wzl 已提交
3969
        const ObString &alias_name = select_stmt->get_select_item(pos-1).alias_name_;
O
oceanbase-admin 已提交
3970
        LOG_USER_ERROR(OB_WRONG_GROUP_FIELD, alias_name.length(), alias_name.ptr());
W
wangzelin.wzl 已提交
3971
      } else { /*do nothing*/ }
O
oceanbase-admin 已提交
3972 3973 3974 3975 3976 3977 3978 3979
    }
  } else if (OB_FAIL(resolve_sql_expr(*group_node, expr))) {
    LOG_WARN("resolve sql expr failed", K(ret));
  }

  if (OB_SUCC(ret)) {
    OrderItem order_item;
    order_item.expr_ = expr;
W
wangzelin.wzl 已提交
3980 3981 3982
    if (!is_oracle_compatible &&
        group_sort_node->num_child_ == 2 &&
        NULL != group_sort_node->children_[1]) {
O
oceanbase-admin 已提交
3983 3984 3985
      has_explicit_dir = true;
      if (OB_FAIL(ObResolverUtils::set_direction_by_mode(*group_sort_node, order_item))) {
        LOG_WARN("failed to set direction by mode", K(ret));
W
wangzelin.wzl 已提交
3986
      } else { /*do nothing.*/ }
O
oceanbase-admin 已提交
3987 3988 3989 3990 3991 3992 3993 3994 3995 3996
    } else {
      order_item.order_type_ = default_asc_direction();
    }
    if (OB_FAIL(ret)) {
    } else if (OB_FAIL(order_items.push_back(order_item))) {
      LOG_WARN("failed to add order element to stmt", K(ret));
    }
  }

  if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
3997
    if (is_groupby_expr && OB_FAIL(groupby_exprs.push_back(expr))) {
O
oceanbase-admin 已提交
3998
      LOG_WARN("failed to add group by expression to stmt", K(ret));
W
wangzelin.wzl 已提交
3999
    } else if(!is_groupby_expr && OB_FAIL(rollup_exprs.push_back(expr))) {
O
oceanbase-admin 已提交
4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013
      LOG_WARN("failed to add rollup expression to stmt", K(ret));
    } else if (is_oracle_mode() && expr->has_flag(CNT_SYS_CONNECT_BY_PATH)) {
      // eg: select count*(*) from t1 connect by nocycle prior c1 > c2 group by SYS_CONNECT_BY_PATH('a','/');
      ret = OB_ERR_CBY_CONNECT_BY_PATH_NOT_ALLOWED;
      LOG_WARN("SYS_CONNECT_BY_PATH function is not allowed here", K(ret));
    } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
      if (OB_FAIL(standard_group_checker_.add_group_by_expr(expr))) {
        LOG_WARN("add group by expr to standard group checker failed", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4014 4015 4016 4017 4018 4019 4020 4021
int ObSelectResolver::resolve_groupby_node(const ParseNode *group_node,
                                           const ParseNode *group_sort_node,
                                           common::ObIArray<ObRawExpr*> &groupby_exprs,
                                           common::ObIArray<ObRawExpr*> &rollup_exprs,
                                           common::ObIArray<OrderItem> &order_items,
                                           bool &has_explicit_dir,
                                           bool is_groupby_expr,
                                           int group_expr_level)
O
oceanbase-admin 已提交
4022 4023 4024
{
  int ret = OB_SUCCESS;
  bool is_oracle_compatible = is_oracle_mode();
W
wangzelin.wzl 已提交
4025
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047
  bool is_stack_overflow = false;
  if (OB_ISNULL(group_node)) {
    ret = OB_INVALID_ARGUMENT; /* Won't be here */
    LOG_WARN("error group by node", K(ret));
  } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("check stack overflow failed", K(ret), K(is_stack_overflow));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("too deep recursive", K(ret), K(is_stack_overflow));
  } else if (group_node->type_ == T_EXPR_LIST) {
    /****************************************************************************
    suppport row in oracle,such as (by jiangxiu):
    select c1 from t1 group by ((c1)); ==> select c1 from t1 group by c1;
    select c1,c2 from t1 group by (c1, c2); ==> select c1,c2 from t1 group by c1, c2;
    select c1,c2 from t1 group by (c1, c2), c3; ==> select c1,c2 from t1 group by c1, c2, c3;
    select c1,c2 from t1 group by ((c1)), (c2, c3); ==> select c1,c2 from t1 group by c1, c2, c3;
    ****************************************************************************/
    if (!is_oracle_compatible) {
      ret = OB_ERR_PARSER_SYNTAX;
      LOG_WARN("row is illegal in group by", K(ret));
    } else if (++group_expr_level > 1 && group_node->num_child_ > 1) {
      ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
4048
      LOG_USER_ERROR(OB_NOT_SUPPORTED, "group by nested row");
O
oceanbase-admin 已提交
4049 4050
      LOG_WARN("not valid group by expr.", K(ret));
    } else {
W
wangzelin.wzl 已提交
4051
      ParseNode *expr_list_node = NULL;
O
oceanbase-admin 已提交
4052 4053 4054 4055 4056 4057
      for (int64_t i = 0; OB_SUCC(ret) && i < group_node->num_child_; i++) {
        expr_list_node = group_node->children_[i];
        if (OB_ISNULL(expr_list_node)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("expr list node is null", K(ret));
        } else if (OB_FAIL(SMART_CALL(resolve_groupby_node(expr_list_node,
W
wangzelin.wzl 已提交
4058 4059 4060 4061 4062 4063 4064
                                                           group_sort_node,
                                                           groupby_exprs,
                                                           rollup_exprs,
                                                           order_items,
                                                           has_explicit_dir,
                                                           is_groupby_expr,
                                                           group_expr_level)))) {
O
oceanbase-admin 已提交
4065 4066
          LOG_WARN("failed to resolve group by node.", K(ret));
        } else {
W
wangzelin.wzl 已提交
4067
        } //do nothing.
O
oceanbase-admin 已提交
4068 4069 4070
      }
    }
  } else if (OB_FAIL(resolve_group_by_sql_expr(group_node,
W
wangzelin.wzl 已提交
4071 4072 4073 4074 4075 4076 4077
                                               group_sort_node,
                                               groupby_exprs,
                                               rollup_exprs,
                                               order_items,
                                               select_stmt,
                                               has_explicit_dir,
                                               is_groupby_expr))) {
O
oceanbase-admin 已提交
4078 4079
    LOG_WARN("failed to resolve group by sql expr.", K(ret));
  } else {
W
wangzelin.wzl 已提交
4080
  } // do nothing.
O
oceanbase-admin 已提交
4081 4082 4083 4084

  return ret;
}

W
wangzelin.wzl 已提交
4085 4086 4087 4088
int ObSelectResolver::can_find_group_column(ObRawExpr *&col_expr,
                                            const ObIArray<ObGroupingSetsItem> &grouping_sets_items,
                                            bool &can_find,
                                            ObStmtCompareContext *check_context/*default = NULL*/)
O
oceanbase-admin 已提交
4089 4090 4091
{
  int ret = OB_SUCCESS;
  can_find = false;
W
wangzelin.wzl 已提交
4092 4093 4094 4095 4096 4097 4098
  for (int64_t i = 0 ; OB_SUCC(ret) && !can_find && i < grouping_sets_items.count(); ++i) {
    const ObIArray<ObGroupbyExpr> &grouping_sets_exprs =
                                                     grouping_sets_items.at(i).grouping_sets_exprs_;
    if (OB_FAIL(can_find_group_column(col_expr,
                                      grouping_sets_items.at(i).multi_rollup_items_,
                                      can_find,
                                      check_context))) {
O
oceanbase-admin 已提交
4099 4100
      LOG_WARN("failed to failed to find group column.");
    } else {
W
wangzelin.wzl 已提交
4101 4102 4103 4104 4105
      for (int64_t j = 0 ; OB_SUCC(ret) && !can_find && j < grouping_sets_exprs.count(); ++j) {
        if (OB_FAIL(can_find_group_column(col_expr,
                                          grouping_sets_exprs.at(j).groupby_exprs_,
                                          can_find,
                                          check_context))) {
O
oceanbase-admin 已提交
4106 4107 4108 4109 4110 4111 4112 4113 4114 4115
          LOG_WARN("failed to find group column.", K(ret));
        } else {
          /*do nothing*/
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4116 4117 4118 4119
int ObSelectResolver::can_find_group_column(ObRawExpr *&col_expr,
                                            const ObIArray<ObMultiRollupItem> &multi_rollup_items,
                                            bool &can_find,
                                            ObStmtCompareContext *check_context/*default = NULL*/)
O
oceanbase-admin 已提交
4120 4121 4122
{
  int ret = OB_SUCCESS;
  can_find = false;
W
wangzelin.wzl 已提交
4123 4124 4125 4126 4127 4128 4129
  for (int64_t i = 0 ; OB_SUCC(ret) && !can_find && i < multi_rollup_items.count(); ++i) {
    const ObIArray<ObGroupbyExpr> &rollup_list_exprs = multi_rollup_items.at(i).rollup_list_exprs_;
    for (int64_t j = 0 ; OB_SUCC(ret) && !can_find && j < rollup_list_exprs.count(); ++j) {
      if (OB_FAIL(can_find_group_column(col_expr,
                                        rollup_list_exprs.at(j).groupby_exprs_,
                                        can_find,
                                        check_context))) {
O
oceanbase-admin 已提交
4130 4131 4132 4133 4134 4135 4136 4137 4138
        LOG_WARN("failed to find group column.", K(ret));
      } else {
        /*do nothing*/
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4139 4140 4141 4142
int ObSelectResolver::can_find_group_column(ObRawExpr *&col_expr,
                                            const common::ObIArray<ObRawExpr*> &exprs,
                                            bool &can_find,
                                            ObStmtCompareContext *check_context/*default = NULL*/)
O
oceanbase-admin 已提交
4143 4144 4145 4146 4147 4148 4149
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(col_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(col_expr));
  } else {
    can_find = false;
W
wangzelin.wzl 已提交
4150 4151
    for (int64_t i = 0 ; OB_SUCC(ret) && !can_find && i < exprs.count(); ++i) {
      ObRawExpr *raw_expr = NULL;
O
oceanbase-admin 已提交
4152 4153 4154
      if (OB_ISNULL(raw_expr = exprs.at(i))) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("the expr in groups is null", K(exprs));
W
wangzelin.wzl 已提交
4155
      } else if (col_expr->same_as(*raw_expr, check_context)) {
O
oceanbase-admin 已提交
4156
        can_find = true;
W
wangzelin.wzl 已提交
4157
        col_expr = raw_expr;
O
oceanbase-admin 已提交
4158 4159 4160 4161 4162 4163 4164 4165 4166
      }
    }
  }
  return ret;
}

int ObSelectResolver::check_grouping_columns()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4167
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
4168 4169 4170 4171
  if (OB_ISNULL(select_stmt)) {
    ret = OB_NOT_INIT;
    LOG_WARN("select_stmt is null", K(select_stmt), K_(session_info));
  } else {
W
wangzelin.wzl 已提交
4172
    common::ObIArray<SelectItem> &select_items = select_stmt->get_select_items();
O
oceanbase-admin 已提交
4173 4174 4175 4176 4177 4178 4179 4180 4181
    for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); ++i) {
      if (OB_FAIL(recursive_check_grouping_columns(select_stmt, select_items.at(i).expr_))) {
        LOG_WARN("failed to recursive check grouping columns", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4182
int ObSelectResolver::check_grouping_columns(ObSelectStmt &stmt, ObRawExpr *&expr)
O
oceanbase-admin 已提交
4183 4184 4185
{
  int ret = OB_SUCCESS;
  bool find = false;
W
wangzelin.wzl 已提交
4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199
  /*
   * bugfix: https://work.aone.alibaba-inc.com/issue/38935701
   * for grouping/grouping_id:
   * select grouping(1+1) from t1 group by rollup(1+1). 
   */
  ObStmtCompareContext questionmark_checker;
  questionmark_checker.reset();
  questionmark_checker.override_const_compare_ = true;
  if (OB_ISNULL(params_.query_ctx_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected null pointer.", K(ret));
  } else if (FALSE_IT(questionmark_checker.init(&params_.query_ctx_->calculable_items_))) {
    // skip
  } else if (OB_ISNULL(expr)) {
O
oceanbase-admin 已提交
4200 4201
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected expr", K(ret));
W
wangzelin.wzl 已提交
4202 4203 4204 4205
  } else if (OB_FAIL(can_find_group_column(expr,
                                           stmt.get_rollup_exprs(),
                                           find,
                                           &questionmark_checker))) {
O
oceanbase-admin 已提交
4206
    LOG_WARN("failed to find group column.", K(ret));
W
wangzelin.wzl 已提交
4207 4208 4209 4210 4211
  } else if (!find && is_oracle_mode()
             && OB_FAIL(can_find_group_column(expr,
                                              stmt.get_group_exprs(),
                                              find,
                                              &questionmark_checker))) {
O
oceanbase-admin 已提交
4212
    LOG_WARN("failed to find group column.", K(ret));
W
wangzelin.wzl 已提交
4213 4214 4215 4216 4217
  } else if (!find && is_oracle_mode()
             && OB_FAIL(can_find_group_column(expr,
                                              stmt.get_grouping_sets_items(),
                                              find,
                                              &questionmark_checker))) {
O
oceanbase-admin 已提交
4218
    LOG_WARN("failed to find group column.", K(ret));
W
wangzelin.wzl 已提交
4219 4220 4221 4222 4223
  } else if (!find && is_oracle_mode()
             && OB_FAIL(can_find_group_column(expr,
                                              stmt.get_multi_rollup_items(),
                                              find,
                                              &questionmark_checker))) {
O
oceanbase-admin 已提交
4224 4225 4226
    LOG_WARN("failed to find group column.", K(ret));
  } else if (!find) {
    ret = OB_ERR_WRONG_FIELD_WITH_GROUP;
W
wangzelin.wzl 已提交
4227 4228 4229 4230 4231 4232 4233 4234 4235
    LOG_WARN("the grouping by column must be a group by column", K(ret));
  } else {
    // add constraints.
    for (int64_t i = 0; OB_SUCC(ret) && i < questionmark_checker.equal_param_info_.count(); i++) {
      if (OB_FAIL(params_.query_ctx_->all_equal_param_constraints_.push_back(
                                              questionmark_checker.equal_param_info_.at(i)))) {
        LOG_WARN("fail to push back equal constraints", K(ret));
      }
    }
O
oceanbase-admin 已提交
4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254
  }
  return ret;
}

int ObSelectResolver::check_nested_aggr_in_having(ObRawExpr* raw_expr)
{
  int ret = OB_SUCCESS;
  bool is_stack_overflow = false;
  if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
    LOG_WARN("check stack overflow failed", K(ret));
  } else if (is_stack_overflow) {
    ret = OB_SIZE_OVERFLOW;
    LOG_WARN("stack is overflow", K(ret), K(is_stack_overflow));
  } else if (OB_ISNULL(raw_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("raw expr is NULL ptr", K(ret));
  } else {
    int64_t N = raw_expr->get_param_count();
    for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) {
W
wangzelin.wzl 已提交
4255
      ObRawExpr *child_expr = raw_expr->get_param_expr(i);
O
oceanbase-admin 已提交
4256 4257 4258
      if (OB_ISNULL(child_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("expr is NULL ptr", K(ret));
W
wangzelin.wzl 已提交
4259 4260
      } else if (child_expr->is_aggr_expr() &&
        static_cast<ObAggFunRawExpr *>(child_expr)->is_nested_aggr()) {
O
oceanbase-admin 已提交
4261
        ret = OB_ERR_WRONG_FIELD_WITH_GROUP;
W
wangzelin.wzl 已提交
4262 4263 4264
        LOG_USER_ERROR(OB_ERR_WRONG_FIELD_WITH_GROUP,
            child_expr->get_expr_name().length(),
          child_expr->get_expr_name().ptr());
O
oceanbase-admin 已提交
4265 4266
      } else if (OB_FAIL(SMART_CALL(check_nested_aggr_in_having(child_expr)))) {
        LOG_WARN("replace reference column failed", K(ret));
W
wangzelin.wzl 已提交
4267 4268
      } else { /*do nothing.*/ }
    } // end for
O
oceanbase-admin 已提交
4269 4270 4271 4272
  }
  return ret;
}

W
wangzelin.wzl 已提交
4273
int ObSelectResolver::resolve_having_clause(const ParseNode *node)
O
oceanbase-admin 已提交
4274 4275
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4276
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
4277 4278
  if (node) {
    current_scope_ = T_HAVING_SCOPE;
W
wangzelin.wzl 已提交
4279 4280
    if (OB_FAIL(resolve_and_split_sql_expr_with_bool_expr(*node,
                                                  select_stmt->get_having_exprs()))) {
O
oceanbase-admin 已提交
4281
      LOG_WARN("resolve and split sql expr failed", K(ret));
W
wangzelin.wzl 已提交
4282
    } else { /*do nothing.*/ }
O
oceanbase-admin 已提交
4283 4284 4285 4286 4287 4288 4289 4290 4291
    for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_having_expr_size(); i++) {
      ObRawExpr* expr = select_stmt->get_having_exprs().at(i);
      if (OB_ISNULL(expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("expr is NULL ptr", K(ret));
      } else if (OB_FAIL(check_nested_aggr_in_having(expr))) {
        LOG_WARN("failed to check nested aggr in having.", K(ret));
      } else if (OB_FAIL(recursive_check_grouping_columns(select_stmt, expr))) {
        LOG_WARN("failed to recursive check grouping columns", K(ret));
W
wangzelin.wzl 已提交
4292 4293 4294 4295 4296 4297 4298
      } else if (expr->has_flag(CNT_ROWNUM)
          || expr->has_flag(CNT_LEVEL)
          || expr->has_flag(CNT_CONNECT_BY_ISLEAF)
          || expr->has_flag(CNT_CONNECT_BY_ISCYCLE)
          || expr->has_flag(CNT_CONNECT_BY_ROOT)){
        set_having_has_self_column();
      } else { /*do nothing.*/ }
O
oceanbase-admin 已提交
4299 4300 4301 4302 4303
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4304 4305 4306
int ObSelectResolver::get_refindex_from_named_windows(const ParseNode *ref_name_node,
                                                      const ParseNode *node,
                                                      int64_t& ref_idx)
O
oceanbase-admin 已提交
4307 4308 4309 4310 4311 4312 4313
{
  int ret = OB_SUCCESS;
  ref_idx = -1;
  if (OB_ISNULL(ref_name_node) || OB_ISNULL(node)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("ref name node or node is NULL ptr", K(ret));
  } else {
W
wangzelin.wzl 已提交
4314 4315
    ObString ref_name(static_cast<int32_t>(ref_name_node->str_len_),
                      ref_name_node->str_value_);
O
oceanbase-admin 已提交
4316
    for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++) {
W
wangzelin.wzl 已提交
4317 4318
      ParseNode *cur_named_win_node = node->children_[i];
      ParseNode *cur_name_node = NULL;
O
oceanbase-admin 已提交
4319 4320 4321 4322 4323 4324 4325
      if (OB_ISNULL(cur_named_win_node)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("cur name win node is NULL ptr", K(ret));
      } else if (OB_ISNULL(cur_name_node = cur_named_win_node->children_[0])) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("cur name node is NULL ptr", K(ret));
      } else {
W
wangzelin.wzl 已提交
4326 4327
        ObString cur_ref_name(static_cast<int32_t>(cur_name_node->str_len_),
                              cur_name_node->str_value_);
O
oceanbase-admin 已提交
4328 4329 4330 4331 4332 4333 4334 4335 4336 4337
        if (ObCharset::case_insensitive_equal(ref_name, cur_ref_name)) {
          ref_idx = i;
          break;
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4338 4339
int ObSelectResolver::check_duplicated_name_window(ObString &name,
                                                   const ObIArray<ObString> &resolved_name_list)
O
oceanbase-admin 已提交
4340 4341
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4342 4343 4344 4345 4346
  for (int64_t i = 0; OB_SUCC(ret) && i < resolved_name_list.count(); ++i) {
    const ObString &cur_name = resolved_name_list.at(i);
    if (OB_UNLIKELY(ObCharset::case_insensitive_equal(name, cur_name))) {
      ret =  OB_NOT_SUPPORTED;
      LOG_USER_ERROR(OB_NOT_SUPPORTED, "duplicate window name");
O
oceanbase-admin 已提交
4347 4348 4349 4350 4351 4352
      LOG_WARN("duplicate window name", K(name), K(cur_name), K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4353 4354
int ObSelectResolver::mock_to_named_windows(ObString &name,
                                            ParseNode *win_node)
O
oceanbase-admin 已提交
4355 4356
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4357
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
4358 4359 4360 4361
  if (OB_ISNULL(select_stmt) || OB_ISNULL(win_node)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt or win node unexpected null.", K(ret));
  } else {
W
wangzelin.wzl 已提交
4362
    const ParseNode *mock_node = NULL;
O
oceanbase-admin 已提交
4363 4364
    ObString win_str(win_node->str_len_, win_node->str_value_);
    ObSqlString sql_str;
W
wangzelin.wzl 已提交
4365 4366 4367 4368 4369 4370
    ObRawExpr *expr = NULL;
    //bug18840807, 此时frame的常量已经参数化, 重新resolve会导致参数化信息丢失, cg时期望para实际常量;
    //后续若计划重用执行阶段会取错常量值, 这里修改了parse_node的窗口指针使用已参数化的
    if (OB_FAIL(sql_str.append_fmt("COUNT(1) OVER %.*s",
                                   win_str.length(),
                                   win_str.ptr()))) {
O
oceanbase-admin 已提交
4371
      LOG_WARN("fail to concat string", K(ret));
W
wangzelin.wzl 已提交
4372 4373 4374 4375
    } else if (OB_FAIL(ObRawExprUtils::parse_expr_node_from_str(sql_str.string(),
                                                                params_.session_info_->get_local_collation_connection(),
                                                                params_.expr_factory_->get_allocator(),
                                                                mock_node))) {
O
oceanbase-admin 已提交
4376
      LOG_WARN("parse expr node from string failed", K(ret));
W
wangzelin.wzl 已提交
4377 4378
    } else if (2 != mock_node->num_child_
        || T_WIN_NEW_GENERALIZED_WINDOW != mock_node->children_[1]->type_) {
O
oceanbase-admin 已提交
4379 4380 4381 4382 4383 4384 4385
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("parse result is not expected", K(ret), K(mock_node->num_child_), K(mock_node->type_));
    } else {
      mock_node->children_[1] = win_node;
    }

    if (OB_FAIL(ret)) {
W
wangzelin.wzl 已提交
4386
      //do nothing...
O
oceanbase-admin 已提交
4387 4388
    } else if (OB_FAIL(resolve_sql_expr(*mock_node, expr))) {
      LOG_WARN("failed to resolve sql expr failed", K(ret));
W
wangzelin.wzl 已提交
4389 4390 4391 4392
      if (OB_EER_WINDOW_NO_REDEFINE_ORDER_BY == ret && OB_NOT_NULL(win_node->children_[0])) {
        LOG_USER_ERROR(OB_EER_WINDOW_NO_REDEFINE_ORDER_BY, name.length(), name.ptr(),
            (int)(win_node->children_[0]->str_len_), win_node->children_[0]->str_value_);
      }
O
oceanbase-admin 已提交
4393 4394 4395 4396 4397 4398 4399
    } else if (OB_ISNULL(expr)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected null ptr", K(expr), K(ret));
    } else if (!expr->is_win_func_expr()) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected ptr", K(expr->get_expr_type()), K(ret));
    } else {
W
wangzelin.wzl 已提交
4400
      ObWinFunRawExpr *win_expr = static_cast<ObWinFunRawExpr *>(expr);
O
oceanbase-admin 已提交
4401 4402 4403 4404 4405 4406 4407 4408
      win_expr->set_win_name(name);
      select_stmt->get_window_func_exprs().pop_back();
      ret = select_stmt->get_window_func_exprs().push_back(win_expr);
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4409
int ObSelectResolver::resolve_named_windows_clause(const ParseNode *node)
O
oceanbase-admin 已提交
4410 4411
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4412 4413
  if (OB_ISNULL(node)) {// no named windows.
  } else if (OB_UNLIKELY(node->type_ != T_WIN_NAMED_WINDOWS)) {
O
oceanbase-admin 已提交
4414 4415
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("unexpected type", K(node->type_), K(ret));
W
wangzelin.wzl 已提交
4416
  } else if (OB_UNLIKELY(node->num_child_ > OB_MAX_NAMED_WINDOW_FUNCTION_NUM)) {
O
oceanbase-admin 已提交
4417
    ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
4418
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "named windows more than 127");
O
oceanbase-admin 已提交
4419 4420 4421
    LOG_WARN("too many windows", K(ret));
  } else {
    current_scope_ = T_NAMED_WINDOWS_SCOPE;
W
wangzelin.wzl 已提交
4422 4423 4424 4425
    int64_t ref_list_cnt = 0; // 引用关系链表
    int64_t ref_list[OB_MAX_NAMED_WINDOW_FUNCTION_NUM];
    bool resolved[OB_MAX_NAMED_WINDOW_FUNCTION_NUM] = { false };
    ObSEArray<ObString, 32> resolved_name_list;
O
oceanbase-admin 已提交
4426
    for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++) {
W
wangzelin.wzl 已提交
4427
      if (resolved[i]) {
O
oceanbase-admin 已提交
4428 4429
        continue;
      }
W
wangzelin.wzl 已提交
4430 4431 4432 4433
      // 按依赖关系依次解析,优先解析被引用的window
      ParseNode *name_node = NULL;
      ParseNode *win_node = NULL;
      ParseNode *named_win_node = NULL;
O
oceanbase-admin 已提交
4434
      ref_list[ref_list_cnt++] = i;
W
wangzelin.wzl 已提交
4435 4436 4437
      // named_window             ->   named_win_node   ->   window w1 as (w2 partition by c)
      // name_ob                  ->   name_node        ->   w1
      // new_generalized_window   ->   win_node         ->   w2 partition by c
O
oceanbase-admin 已提交
4438 4439 4440 4441 4442
      while (OB_SUCC(ret) && ref_list_cnt > 0) {
        LOG_DEBUG("current window", K(ref_list[ref_list_cnt - 1]), K(ref_list_cnt));
        named_win_node = node->children_[ref_list[ref_list_cnt - 1]];
        if (OB_ISNULL(named_win_node)) {
          ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
4443
          LOG_WARN("NULL ptr",  K(ret));
O
oceanbase-admin 已提交
4444 4445 4446 4447 4448 4449 4450
        } else if (OB_ISNULL(name_node = named_win_node->children_[0])) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("NULL ptr", K(ret));
        } else if (OB_ISNULL(win_node = named_win_node->children_[1])) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("NULL ptr", K(ret));
        } else {
W
wangzelin.wzl 已提交
4451 4452 4453
          // 1. 未引用任何window
          // 2. 引用已经解析好的window
          // 这两种情况会直接解析当前window,否则转而解析被引用的window
O
oceanbase-admin 已提交
4454 4455
          bool resolve_expr = false;
          int64_t ref_idx = -1;
W
wangzelin.wzl 已提交
4456
          ParseNode *ref_name_node = win_node->children_[0];
O
oceanbase-admin 已提交
4457 4458
          if (NULL == ref_name_node) {
            resolve_expr = true;
W
wangzelin.wzl 已提交
4459 4460 4461
          } else if (OB_FAIL(get_refindex_from_named_windows(ref_name_node,
                                                             node,
                                                             ref_idx))) {
O
oceanbase-admin 已提交
4462
            LOG_WARN("failed to get ref index from named windows.", K(ret));
W
wangzelin.wzl 已提交
4463
          } else if (OB_UNLIKELY(-1 == ref_idx)) {
O
oceanbase-admin 已提交
4464
            ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
4465
            LOG_USER_ERROR(OB_NOT_SUPPORTED, "ref not existed window");
O
oceanbase-admin 已提交
4466
            LOG_WARN("ref window not exist", K(ret));
W
wangzelin.wzl 已提交
4467 4468 4469
          } else if ((ref_list + ref_list_cnt) != std::find(ref_list,
                                                            ref_list + ref_list_cnt,
                                                            ref_idx)) {
O
oceanbase-admin 已提交
4470
            ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
4471
            LOG_USER_ERROR(OB_NOT_SUPPORTED, "circle ref window");
O
oceanbase-admin 已提交
4472
            LOG_WARN("circle ref window not supported", K(ref_list), K(ref_idx), K(ret));
W
wangzelin.wzl 已提交
4473
          } else if (resolved[ref_idx]) {
O
oceanbase-admin 已提交
4474 4475 4476 4477 4478 4479
            resolve_expr = true;
          } else {
            resolve_expr = false;
            ref_list[ref_list_cnt++] = ref_idx;
          }
          if (OB_SUCC(ret) && resolve_expr) {
W
wangzelin.wzl 已提交
4480 4481 4482
            ObString name(static_cast<int32_t>(name_node->str_len_),
                          name_node->str_value_);
            if (OB_FAIL(check_duplicated_name_window(name, resolved_name_list))) {
O
oceanbase-admin 已提交
4483
              LOG_WARN("has duplicated name widow when check them.", K(ret));
W
wangzelin.wzl 已提交
4484 4485 4486 4487
            } else if (OB_FAIL(resolved_name_list.push_back(name))) {
              LOG_WARN("failed to push back win name", K(ret));
            } else if (OB_FAIL(mock_to_named_windows(name,
                                                     win_node))) {
O
oceanbase-admin 已提交
4488 4489
              LOG_WARN("failed to mock to name window", K(ret));
            } else {
W
wangzelin.wzl 已提交
4490
              resolved[ref_list[ref_list_cnt - 1]] = true;
O
oceanbase-admin 已提交
4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501
              ref_list_cnt--;
            }
          }
        }
      }
    }
    LOG_DEBUG("resolve_named_windows_clause finish", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
4502
int ObSelectResolver::resolve_into_const_node(const ParseNode *node, ObObj &obj)
O
oceanbase-admin 已提交
4503 4504 4505 4506 4507
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(node)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("node is null", K(ret));
W
wangzelin.wzl 已提交
4508 4509
  } else if (T_CHAR == node->type_ || T_VARCHAR == node->type_) {
    ObCollationType cs_type = params_.session_info_->get_local_collation_connection();
O
oceanbase-admin 已提交
4510
    ObString node_str(node->str_len_, node->str_value_);
W
wangzelin.wzl 已提交
4511 4512
    if (lib::is_oracle_mode()) {
      OZ (ObResolverUtils::escape_char_for_oracle_mode(*allocator_, node_str, cs_type));
O
oceanbase-admin 已提交
4513
    }
W
wangzelin.wzl 已提交
4514 4515 4516
    if (OB_SUCC(ret)) {
      obj.set_varchar(node_str);
      obj.set_collation_type(cs_type);
O
oceanbase-admin 已提交
4517 4518 4519 4520 4521 4522 4523 4524 4525 4526
    }
  } else if (T_QUESTIONMARK == node->type_) {
    obj.set_unknown(node->value_);
  } else {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("node type must be varchar or ?", K(ret), K(node->type_));
  }
  return ret;
}

W
wangzelin.wzl 已提交
4527 4528 4529
int ObSelectResolver::resolve_into_filed_node(
  const ParseNode *list_node,
  ObSelectIntoItem &into_item)
O
oceanbase-admin 已提交
4530 4531 4532 4533 4534 4535
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(list_node)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("str node is null", K(ret));
  } else {
W
wangzelin.wzl 已提交
4536 4537
    for (int32_t i = 0 ; i < list_node->num_child_ ; ++i) {
      ParseNode *node = list_node->children_[i];
O
oceanbase-admin 已提交
4538 4539 4540 4541 4542 4543 4544
      if (OB_ISNULL(node)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("str node or into_item is null", K(ret));
      } else if (T_FIELD_TERMINATED_STR == node->type_) {
        if (OB_FAIL(resolve_into_const_node(node->children_[0], into_item.filed_str_))) {
          LOG_WARN("resolve into outfile filed str", K(ret));
        }
W
wangzelin.wzl 已提交
4545 4546
      } else if (T_OPTIONALLY_CLOSED_STR == node->type_
                 || T_CLOSED_STR == node->type_) {
O
oceanbase-admin 已提交
4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558
        if (node->num_child_ != 1) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("child num should be one", K(ret));
        } else if (1 != node->children_[0]->str_len_ || OB_ISNULL(node->children_[0]->str_value_)) {
          ret = OB_WRONG_FIELD_TERMINATORS;
          LOG_WARN("closed str should be a character", K(ret), K(node->children_[0]->str_value_));
        } else {
          into_item.closed_cht_ = node->children_[0]->str_value_[0];
          if (T_OPTIONALLY_CLOSED_STR == node->type_) {
            into_item.is_optional_ = true;
          }
        }
W
wangzelin.wzl 已提交
4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570
      } else if (T_ESCAPED_STR == node->type_) {
        if (node->num_child_ != 1) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("child num should be one", K(ret));
        } else if (node->children_[0]->str_len_ == 0) {
          into_item.escaped_cht_ = 0;
        } else if (node->children_[0]->str_len_ == 1) {
          into_item.escaped_cht_ = node->children_[0]->str_value_[0];
        } else {
          ret = OB_WRONG_FIELD_TERMINATORS;
          LOG_WARN("escaped str should be a character", K(ret), K(node->children_[0]->str_value_));
        }
O
oceanbase-admin 已提交
4571 4572 4573 4574 4575 4576 4577 4578 4579
      } else {
        // do nothing
      }
    }
  }

  return ret;
}

W
wangzelin.wzl 已提交
4580
int ObSelectResolver::resolve_into_line_node(const ParseNode *list_node, ObSelectIntoItem &into_item)
O
oceanbase-admin 已提交
4581 4582 4583 4584 4585 4586
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(list_node)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("str node is null", K(ret));
  } else {
W
wangzelin.wzl 已提交
4587 4588
    for (int32_t i = 0 ; i < list_node->num_child_ ; ++i) {
      ParseNode *str_node = list_node->children_[i];
O
oceanbase-admin 已提交
4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602
      if (OB_ISNULL(str_node)) {
        ret = OB_ERR_UNEXPECTED;
      } else if (T_LINE_TERMINATED_STR == str_node->type_) {
        if (OB_FAIL(resolve_into_const_node(str_node->children_[0], into_item.line_str_))) {
          LOG_WARN("resolve into outfile filed str", K(ret));
        }
      } else {
        // escape
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4603
int ObSelectResolver::resolve_into_clause(const ParseNode *node)
O
oceanbase-admin 已提交
4604 4605 4606 4607
{
  int ret = OB_SUCCESS;
  if (NULL != node) {
    current_scope_ = T_INTO_SCOPE;
W
wangzelin.wzl 已提交
4608 4609
    ObSelectIntoItem *into_item = NULL;
    ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
4610 4611 4612
    if (OB_ISNULL(allocator_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("alloctor is null", K(ret));
W
wangzelin.wzl 已提交
4613 4614
    } else if (OB_ISNULL(into_item = static_cast<ObSelectIntoItem *>
                         (allocator_->alloc(sizeof(ObSelectIntoItem))))) {
O
oceanbase-admin 已提交
4615 4616 4617 4618 4619
      ret = OB_ALLOCATE_MEMORY_FAILED;
      LOG_WARN("into item is null", K(ret));
    } else if (OB_ISNULL(select_stmt)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("select stmt is NULL", K(ret));
O
obdev 已提交
4620
    } else if (OB_UNLIKELY(get_current_level() != 0)) { //in subquery
O
oceanbase-admin 已提交
4621 4622 4623 4624 4625 4626
      ret = OB_INAPPROPRIATE_INTO;
      LOG_WARN("select into can not in subquery", K(ret));
    } else if (OB_UNLIKELY(is_in_set_query())) {
      ret = OB_INAPPROPRIATE_INTO;
      LOG_WARN("select into can not in set query", K(ret));
    } else {
W
wangzelin.wzl 已提交
4627
      new(into_item) ObSelectIntoItem();
O
oceanbase-admin 已提交
4628
      into_item->into_type_ = node->type_;
W
wangzelin.wzl 已提交
4629 4630
      if (T_INTO_OUTFILE == node->type_) { // into outfile
        if (OB_FAIL(resolve_into_const_node(node->children_[0], into_item->outfile_name_))) { //name
O
oceanbase-admin 已提交
4631
          LOG_WARN("resolve into outfile name failed", K(ret));
W
wangzelin.wzl 已提交
4632 4633 4634 4635 4636 4637 4638 4639 4640
        } else if (NULL != node->children_[1]) { // charset
          ObCharsetType charset_type = CHARSET_INVALID;
          ObString charset(node->children_[1]->str_len_, node->children_[1]->str_value_);
          if (CHARSET_INVALID == (charset_type = ObCharset::charset_type(charset.trim()))) {
            ret = OB_ERR_UNKNOWN_CHARSET;
            LOG_USER_ERROR(OB_ERR_UNKNOWN_CHARSET, charset.length(), charset.ptr());
          } else {
            into_item->cs_type_ = ObCharset::get_default_collation(charset_type);
          }
O
oceanbase-admin 已提交
4641
        }
W
wangzelin.wzl 已提交
4642
        if (OB_SUCC(ret) && NULL !=  node->children_[2]) { //field
O
oceanbase-admin 已提交
4643 4644 4645 4646
          if (OB_FAIL(resolve_into_filed_node(node->children_[2], *into_item))) {
            LOG_WARN("reosolve into filed node failed", K(ret));
          }
        }
W
wangzelin.wzl 已提交
4647
        if (OB_SUCC(ret) && NULL != node->children_[3]) { // line
O
oceanbase-admin 已提交
4648 4649 4650 4651
          if (OB_FAIL(resolve_into_line_node(node->children_[3], *into_item))) {
            LOG_WARN("reosolve into line node failed", K(ret));
          }
        }
W
wangzelin.wzl 已提交
4652
      } else if (T_INTO_DUMPFILE  == node->type_) { // into dumpfile
O
oceanbase-admin 已提交
4653 4654 4655
        if (OB_FAIL(resolve_into_const_node(node->children_[0], into_item->outfile_name_))) {
          LOG_WARN("resolve into outfile name failed", K(ret));
        }
W
wangzelin.wzl 已提交
4656 4657 4658 4659 4660
      } else if (T_INTO_VARIABLES == node->type_) { // into @x,@y....
        if (OB_FAIL(resolve_into_variables(node,
                                           into_item->user_vars_,
                                           into_item->pl_vars_,
                                           select_stmt))) {
O
oceanbase-admin 已提交
4661 4662 4663
          LOG_WARN("resolve into variable failed", K(ret));
        }
      } else {
W
wangzelin.wzl 已提交
4664
        //do nothing
O
oceanbase-admin 已提交
4665 4666 4667 4668 4669 4670 4671 4672 4673
      }
      if (OB_SUCC(ret)) {
        select_stmt->set_select_into(into_item);
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4674 4675 4676 4677

int ObSelectResolver::resolve_column_ref_in_all_namespace(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
4678 4679
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4680 4681 4682 4683
  //first, find column in current namespace
  //mysql5.6中alias name不能出现在where子句中,但是可以出现在group by、having、order by子句中
  //如果普通列和alias name重复,那么在group by、having子句中优先使用基础列,并汇报WARNNING
  //order by子句中,优先使用alias name
O
oceanbase-admin 已提交
4684
  if (OB_UNLIKELY(T_ORDER_SCOPE == current_scope_)) {
W
wangzelin.wzl 已提交
4685
    if ((lib::is_mysql_mode() && params_.is_column_ref_) || lib::is_oracle_mode()) {
4686 4687 4688 4689 4690 4691
      // should raise an error
      // select id + 1 as data, data from test order by data
      // select id as data, data from test order by data
      if (OB_FAIL(resolve_column_ref_alias_first(q_name, real_ref_expr))) {
        LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column ref alias first failed", K(ret), K(q_name));
      }
W
wangzelin.wzl 已提交
4692 4693 4694 4695 4696 4697 4698 4699
    } else {
      // if the item behind order by is an expr in mysql mode, then we should resolve column
      // select id as data, data from test order by data + 1;
      // select id as data, data from test order by sum(data);
      // select id + 1 as data, data from test order by sum(data);
      if (OB_FAIL(resolve_column_ref_table_first(q_name, real_ref_expr, false))) {
        LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column ref table first failed", K(ret), K(q_name));
      }
O
oceanbase-admin 已提交
4700 4701 4702 4703 4704
    }
  } else if (OB_UNLIKELY(T_HAVING_SCOPE == current_scope_)) {
    if (OB_FAIL(resolve_column_ref_for_having(q_name, real_ref_expr))) {
      LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column ref for having failed", K(ret), K(q_name));
    }
W
wangzelin.wzl 已提交
4705
  }  else if (T_WITH_CLAUSE_SEARCH_SCOPE == current_scope_) {
O
oceanbase-admin 已提交
4706
    if (OB_FAIL(resolve_column_ref_for_search(q_name, real_ref_expr))) {
W
wangzelin.wzl 已提交
4707
      LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column ref for search failed",  K(ret), K(q_name));
O
oceanbase-admin 已提交
4708 4709
    }
  } else {
W
wangzelin.wzl 已提交
4710 4711
    //search column in table columns first
    if (OB_FAIL(resolve_column_ref_table_first(q_name, real_ref_expr))) {
O
oceanbase-admin 已提交
4712 4713 4714
      LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column ref table first failed", K(ret), K(q_name));
    }
  }
W
wangzelin.wzl 已提交
4715 4716 4717 4718 4719 4720 4721 4722 4723
  ObQueryRefRawExpr *query_ref = NULL;
  for (ObDMLResolver *cur_resolver = get_parent_namespace_resolver();
      OB_ERR_BAD_FIELD_ERROR == ret && cur_resolver != NULL;
      cur_resolver = cur_resolver->get_parent_namespace_resolver()) {
    ObRawExpr *exec_param = NULL;
    //for insert into t1 values((select c1 from dual)) ==> can't check column c1 in t1;
    if (cur_resolver->get_basic_stmt() != NULL &&
        cur_resolver->get_basic_stmt()->is_insert_stmt()) {
      //do nothing
O
oceanbase-admin 已提交
4724 4725
    } else if (OB_FAIL(cur_resolver->resolve_column_ref_for_subquery(q_name, real_ref_expr))) {
      LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column for subquery failed", K(ret), K(q_name));
W
wangzelin.wzl 已提交
4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736
    } else if (OB_ISNULL(query_ref = cur_resolver->get_subquery())) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("no subquery is found", K(ret));
    } else if (OB_FAIL(ObRawExprUtils::get_exec_param_expr(*params_.expr_factory_,
                                                           query_ref,
                                                           real_ref_expr,
                                                           exec_param))) {
      LOG_WARN("failed to get exec param expr", K(ret));
    } else {
      /// succeed to resolve the correlated column, do the replace here
      real_ref_expr = exec_param;
O
oceanbase-admin 已提交
4737 4738 4739 4740 4741
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4742 4743
int ObSelectResolver::resolve_column_ref_expr(
  const ObQualifiedName &q_name, ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
4744 4745
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4746
  //设置resolve的列是否存在本层的聚集函数中,如果存在聚集函数中,本层的列可以不需要进行only full group by约束
O
oceanbase-admin 已提交
4747 4748 4749
  if (OB_ISNULL(session_info_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("session info is null");
W
wangzelin.wzl 已提交
4750 4751
  } else  if (OB_FALSE_IT(const_cast<ObQualifiedName&>(q_name).current_resolve_level_ = current_level_)) {

O
oceanbase-admin 已提交
4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762
  } else if (q_name.parents_expr_info_.has_member(IS_AGG)) {
    const_cast<ObQualifiedName&>(q_name).parent_aggr_level_ = current_level_;
  } else {
    const_cast<ObQualifiedName&>(q_name).parent_aggr_level_ = parent_aggr_level_;
  }
  if (OB_SUCC(ret) && OB_FAIL(resolve_column_ref_in_all_namespace(q_name, real_ref_expr))) {
    LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column ref in all namespace failed", K(ret));
  }
  return ret;
}

W
wangzelin.wzl 已提交
4763 4764 4765
//resolve table column reference
//select stmt can access joined table column, generated table column or base table column
int ObSelectResolver::resolve_table_column_ref(const ObQualifiedName &q_name, ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
4766
{
W
wangzelin.wzl 已提交
4767 4768 4769 4770
  //search order
  //1. joined table column
  //2. basic table column or generated table column
  //3. object (sequence)
O
oceanbase-admin 已提交
4771 4772 4773 4774
  int ret = OB_SUCCESS;
  if (OB_FAIL(resolve_table_column_expr(q_name, real_ref_expr))) {
    LOG_WARN("resolve table column expr failed", K(ret), K(q_name), K(lbt()));
  } else if (column_need_check_group_by(q_name)) {
W
wangzelin.wzl 已提交
4775 4776
    //任何一个表达式引用到的本层的列,都必须记录到standard group checker中,并进行only full group by检查
    // In Oracle mode, it will add all referenced columns, but group by checker will check every expression recursively intead of one by one column
O
oceanbase-admin 已提交
4777 4778 4779 4780 4781 4782 4783
    if (OB_FAIL(standard_group_checker_.add_unsettled_column(real_ref_expr))) {
      LOG_WARN("add unsettled column failed", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4784 4785 4786
int ObSelectResolver::resolve_alias_column_ref(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
4787 4788
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4789 4790 4791 4792
  //resolve column in target list can't reference the alias column
  //such as select 1 as a, (select a) ->error
  //select 1 as a, a; ->error
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
4793 4794 4795 4796
  real_ref_expr = NULL;
  if (OB_ISNULL(select_stmt) || OB_ISNULL(q_name.ref_expr_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("select stmt is null", K(select_stmt), K_(q_name.ref_expr));
W
wangzelin.wzl 已提交
4797 4798 4799 4800
  } else if ((!lib::is_oracle_mode() && current_level_ < q_name.current_resolve_level_) ||current_scope_ != T_FIELD_LIST_SCOPE) {
    // mysql can use parent filed list, so test current_level_ < q_name.current_resolve_level_
    // such as create table t1(c1 int);create table t2(c1 int);select c1 as id /*(level=0)*/, (/*(level=1)*/select c1 from t1 where c1 = id) from t2;
    const SelectItem *cur_item = NULL;
O
oceanbase-admin 已提交
4801
    if (!q_name.tbl_name_.empty()) {
W
wangzelin.wzl 已提交
4802 4803 4804 4805 4806
      //select t1.c1 from t1 having t1.c1 > 0   should check if t1 is correct
      //select t1.c1 from t1 having t2.c1 > 0
      //select c1, c2 as c1 from t1 having t1.c1 > 0 //should choose c1
      //select t1.c1 as cc from t1 having t1.c1 > 0; //should found c1
      //select t1.c1 as cc from t1 having t2.c1 > 0; //should not found c1
O
oceanbase-admin 已提交
4807 4808 4809 4810
      for (int32_t i = 0; OB_SUCC(ret) && i < select_stmt->get_select_item_size(); ++i) {
        bool is_hit = false;
        cur_item = &select_stmt->get_select_item(i);
        if (cur_item->expr_ != NULL) {
W
wangzelin.wzl 已提交
4811
          ObColumnRefRawExpr *col_expr = NULL;
O
oceanbase-admin 已提交
4812
          if (cur_item->expr_->is_column_ref_expr()) {
W
wangzelin.wzl 已提交
4813
            col_expr = static_cast<ObColumnRefRawExpr *>(cur_item->expr_);
O
oceanbase-admin 已提交
4814 4815 4816 4817
          }
          if (NULL == col_expr) {
            continue;
          }
W
wangzelin.wzl 已提交
4818 4819
          if (OB_FAIL(ObResolverUtils::check_column_name(
                        session_info_, q_name, *col_expr, is_hit))) {
O
oceanbase-admin 已提交
4820 4821 4822 4823
            LOG_WARN("check column name failed", K(ret));
          } else if (is_hit) {
            if (NULL == real_ref_expr) {
              ret = column_namespace_checker_.check_column_existence_in_using_clause(
W
wangzelin.wzl 已提交
4824
                                    col_expr->get_table_id(), col_expr->get_column_name());
O
oceanbase-admin 已提交
4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853
              if (OB_SUCC(ret)) {
                real_ref_expr = col_expr;
              }
            } else if (real_ref_expr != col_expr) {
              ret = OB_NON_UNIQ_ERROR;
            }
          }
        } else {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("cur item expr is null");
        }
      }
      if (OB_SUCC(ret) && NULL == real_ref_expr) {
        ret = OB_ERR_BAD_FIELD_ERROR;
      }
    } else {
      // first loop, find the matched alias column with expr
      for (int32_t i = 0; OB_SUCC(ret) && i < select_stmt->get_select_item_size(); ++i) {
        cur_item = &select_stmt->get_select_item(i);
        if (ObCharset::case_insensitive_equal(q_name.col_name_, cur_item->alias_name_)) {
          /*
           * for oracle mode, column uniqueness is checked among all tables
           * for mysql mode, column uniqueness is only checked among select items
           * for example, create table t1(a int, b int, c int); create table t2(a int, b int, c int);
           * select t1.a, t1.b from t1 left join t2 on t1.a = t2.a order by b
           * for mysql mode, it is ok, and b refer to t1.b
           * for oracle mode, it will get error "column ambiguously defined"
           */
          if (NULL == real_ref_expr) {
W
wangzelin.wzl 已提交
4854 4855 4856
            if (lib::is_oracle_mode() && cur_item->expr_->is_column_ref_expr() &&
                !cur_item->is_real_alias_) {
              const TableItem *table_item = NULL;
O
oceanbase-admin 已提交
4857 4858 4859
              ret = column_namespace_checker_.check_table_column_namespace(q_name, table_item);
            }
            if (OB_SUCC(ret)) {
W
wangzelin.wzl 已提交
4860
             real_ref_expr = cur_item->expr_;
O
oceanbase-admin 已提交
4861 4862 4863 4864 4865 4866 4867 4868
            }
          } else if (real_ref_expr != cur_item->expr_) {
            ret = OB_NON_UNIQ_ERROR;
          }
        }
      }
      if (OB_SUCC(ret) && NULL == real_ref_expr) {
        // might not found, the caller will check the col_item is NULL or not
W
wangzelin.wzl 已提交
4869
        //select c1 as cc from t1 having c1 > 0; //should found c1
O
oceanbase-admin 已提交
4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886
        for (int32_t i = 0; i < select_stmt->get_select_item_size(); ++i) {
          cur_item = &select_stmt->get_select_item(i);
          if (cur_item->is_real_alias_ && cur_item->expr_->is_column_ref_expr()) {
            if (ObCharset::case_insensitive_equal(q_name.col_name_, cur_item->expr_name_)) {
              real_ref_expr = cur_item->expr_;
              break;
            }
          }
        }
      }
      if (OB_SUCC(ret) && NULL == real_ref_expr) {
        ret = OB_ERR_BAD_FIELD_ERROR;
      }
    }
  } else {
    ret = OB_ERR_BAD_FIELD_ERROR;
  }
W
wangzelin.wzl 已提交
4887
  //group by clause can't use aggregate function alias name
O
oceanbase-admin 已提交
4888
  if (OB_SUCC(ret) && T_GROUP_SCOPE == current_scope_) {
O
obdev 已提交
4889
    if (real_ref_expr->has_flag(CNT_AGG)) {
O
oceanbase-admin 已提交
4890
      ret = OB_ILLEGAL_REFERENCE;
W
wangzelin.wzl 已提交
4891 4892 4893 4894 4895 4896 4897
      // 为了能给group by报错
      // 兼容mysql报错,
      // select count(c1) as c from t1 group by c和select count(c1)
      // as c from t1 group by (select c)报错不同
    }
  }
  // subquery cannot ref parent aggr/window function alias
O
obdev 已提交
4898 4899 4900 4901 4902
  // SELECT SUM(c1) OVER () AS c, (SELECT SUM(c) from t2)  FROM t1;
  // SELECT SUM(c1) AS c, (SELECT SUM(c) from t2)  FROM t1;
  if(OB_SUCC(ret) && current_level_ < q_name.current_resolve_level_ && T_FIELD_LIST_SCOPE == current_scope_) {
    if (real_ref_expr->has_flag(CNT_AGG) ||
        real_ref_expr->has_flag(CNT_WINDOW_FUNC)) {
4903
      ret = OB_ILLEGAL_REFERENCE;
O
oceanbase-admin 已提交
4904 4905
    }
  }
W
wangzelin.wzl 已提交
4906

O
oceanbase-admin 已提交
4907 4908 4909 4910 4911 4912
  if (OB_SUCC(ret) && OB_FAIL(wrap_alias_column_ref(q_name, real_ref_expr))) {
    LOG_WARN("wrap alias column ref failed", K(ret), K(q_name));
  }
  return ret;
}

W
wangzelin.wzl 已提交
4913 4914 4915
int ObSelectResolver::resolve_column_ref_in_group_by(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
4916 4917
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4918
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
4919 4920 4921 4922
  if (OB_ISNULL(select_stmt)) {
    ret = OB_NOT_INIT;
    LOG_WARN("select stmt is null");
  } else if (!is_oracle_mode() && q_name.parent_aggr_level_ < current_level_) {
W
wangzelin.wzl 已提交
4923
    //the column don't located in aggregate function in having clause
Z
zz0 已提交
4924
    // resolve column refs from group by and rollup exprs
W
wangzelin.wzl 已提交
4925
    ObSEArray<ObRawExpr*, 16> group_and_rollup_exprs;
Z
zz0 已提交
4926 4927 4928 4929 4930 4931
    if (OB_FAIL(append(group_and_rollup_exprs, select_stmt->get_group_exprs()))) {
      LOG_WARN("failed to append group exprs", K(ret));
    } else if (OB_FAIL(append(group_and_rollup_exprs, select_stmt->get_rollup_exprs()))) {
      LOG_WARN("failed to append rollup exprs", K(ret));
    }
    for (int64_t i = 0; OB_SUCC(ret) && i < group_and_rollup_exprs.count(); ++i) {
O
oceanbase-admin 已提交
4932
      bool is_hit = false;
Z
zz0 已提交
4933 4934 4935
      ObRawExpr *expr = NULL;
      ObColumnRefRawExpr *col_ref = NULL;
      if (OB_ISNULL(expr = group_and_rollup_exprs.at(i))) {
O
oceanbase-admin 已提交
4936
        ret = OB_ERR_UNEXPECTED;
Z
zz0 已提交
4937 4938 4939
        LOG_WARN("expr is null", K(ret));
      } else if (!expr->is_column_ref_expr()) {
        // do nothing
W
wangzelin.wzl 已提交
4940
      } else if (OB_FALSE_IT(col_ref = static_cast<ObColumnRefRawExpr*>(expr))) {
Z
zz0 已提交
4941 4942 4943 4944 4945 4946 4947
      } else if (OB_FAIL(ObResolverUtils::check_column_name(session_info_, q_name, *col_ref, is_hit))) {
        LOG_WARN("check column name failed", K(ret), K(q_name));
      } else if (is_hit) {
        if (OB_ISNULL(real_ref_expr)) {
          real_ref_expr = col_ref;
        } else if (real_ref_expr != col_ref) {
          ret = OB_NON_UNIQ_ERROR;
O
oceanbase-admin 已提交
4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959
        }
      }
    }
  } else if (OB_FAIL(resolve_table_column_ref(q_name, real_ref_expr))) {
    LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve table column ref failed", K(ret));
  }
  if (OB_SUCC(ret) && NULL == real_ref_expr) {
    ret = OB_ERR_BAD_FIELD_ERROR;
  }
  return ret;
}

W
wangzelin.wzl 已提交
4960 4961 4962
int ObSelectResolver::resolve_column_ref_alias_first(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
4963 4964
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
4965 4966
  //search column ref in alias list first
  //if alias column exist, use alias column, otherwise, search column ref in table columns
O
oceanbase-admin 已提交
4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978
  if (OB_FAIL(resolve_alias_column_ref(q_name, real_ref_expr))) {
    if (OB_ERR_BAD_FIELD_ERROR == ret) {
      if (OB_FAIL(resolve_table_column_ref(q_name, real_ref_expr))) {
        LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve table column refs failed", K(ret), K(q_name));
      }
    } else {
      LOG_WARN("resolve alias column ref failed", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
4979 4980 4981
int ObSelectResolver::resolve_column_ref_for_search(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
4982 4983 4984
{
  int ret = OB_SUCCESS;
  UNUSED(q_name);
W
wangzelin.wzl 已提交
4985
  ColumnItem *col_item = NULL;
O
oceanbase-admin 已提交
4986 4987 4988 4989 4990 4991 4992
  if (T_WITH_CLAUSE_SEARCH_SCOPE != current_scope_) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("we only resolve the search clause at the search scope");
  } else if (OB_ISNULL(current_recursive_cte_table_item_) || OB_ISNULL(current_cte_involed_stmt_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("in order to resolve the search clause, the recursive cte table item can not be null");
  } else {
W
wangzelin.wzl 已提交
4993
    ObDMLStmt *stmt = current_cte_involed_stmt_;
O
oceanbase-admin 已提交
4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010
    TableItem& table_item = *current_recursive_cte_table_item_;
    if (OB_ISNULL(stmt) || OB_ISNULL(schema_checker_) || OB_ISNULL(params_.expr_factory_)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("schema checker is null", K(stmt), K_(schema_checker), K_(params_.expr_factory));
    } else if (OB_UNLIKELY(!table_item.is_basic_table() && !table_item.is_fake_cte_table())) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("not base table or alias from base table", K_(table_item.type));
    } else if (NULL != (col_item = stmt->get_column_item(table_item.table_id_, q_name.col_name_))) {
      real_ref_expr = col_item->expr_;
    } else {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("the col item has been resolve, but we do not find it in the search clause resolver");
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5011
int ObSelectResolver::set_having_self_column(const ObRawExpr *real_ref_expr)
O
oceanbase-admin 已提交
5012 5013 5014
{
  int ret = OB_SUCCESS;
  // set having has columns
O
obdev 已提交
5015
  if (OB_ISNULL(real_ref_expr)) {
O
oceanbase-admin 已提交
5016 5017
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null or real ref expr is null", K(ret));
O
obdev 已提交
5018
  } else if (!real_ref_expr->is_exec_param_expr()) {
O
oceanbase-admin 已提交
5019
    // set having has self column
W
wangzelin.wzl 已提交
5020
    set_having_has_self_column();
O
oceanbase-admin 已提交
5021 5022
    LOG_DEBUG("set having self column", K(*real_ref_expr));
  } else {
O
obdev 已提交
5023
    LOG_DEBUG("different level", K(*real_ref_expr));
O
oceanbase-admin 已提交
5024 5025 5026 5027 5028 5029 5030 5031 5032
  }
  return ret;
}

/**
 * The SQL standard requires that HAVING must reference only columns in the GROUP BY clause or
 * columns used in aggregate functions. However, MySQL supports an extension to this behavior,
 * and permits HAVING to refer to columns in the SELECT list and columns in outer subqueries as well
 */
W
wangzelin.wzl 已提交
5033 5034 5035
int ObSelectResolver::resolve_column_ref_for_having(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
5036 5037
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5038
  ObRawExpr *check_ref = NULL;
O
oceanbase-admin 已提交
5039 5040 5041 5042
  bool is_oracle_compatible = is_oracle_mode();
  if (OB_FAIL(resolve_column_ref_in_group_by(q_name, real_ref_expr))) {
    if (OB_ERR_BAD_FIELD_ERROR == ret) {
      if (OB_FAIL(resolve_alias_column_ref(q_name, real_ref_expr))) {
W
wangzelin.wzl 已提交
5043 5044 5045 5046 5047
        LOG_WARN_IGNORE_COL_NOTFOUND(
          ret,
          "resolve alias column reference failed",
          K(ret),
          K(q_name));
O
oceanbase-admin 已提交
5048 5049 5050 5051 5052 5053 5054 5055 5056
      }
    } else {
      LOG_WARN("resolve column ref in group by failed", K(ret), K(q_name));
    }
  } else if (is_oracle_compatible) {
    if (OB_FAIL(set_having_self_column(real_ref_expr))) {
      LOG_WARN("set having self column failed", K(ret), K(q_name));
    }
  } else if (OB_FAIL(resolve_alias_column_ref(q_name, check_ref))) {
W
wangzelin.wzl 已提交
5057
    //check column whether exists in alias select list
O
oceanbase-admin 已提交
5058 5059 5060 5061 5062 5063 5064 5065
    if (OB_ERR_BAD_FIELD_ERROR == ret) {
      ret = OB_SUCCESS;
    } else {
      LOG_WARN("resolve alias column ref failed", K(ret), K(q_name));
    }
  } else if (!ObRawExprUtils::is_same_column_ref(real_ref_expr, check_ref)) {
    // if column name exist in both group columns and alias name list,
    // use table column and produce warning msg
W
wangzelin.wzl 已提交
5066 5067
    ObString col_name = concat_qualified_name(
      q_name.database_name_, q_name.tbl_name_, q_name.col_name_);
O
oceanbase-admin 已提交
5068
    ObString scope_name = ObString::make_string(get_scope_name(current_scope_));
W
wangzelin.wzl 已提交
5069 5070 5071 5072 5073
    LOG_USER_WARN(OB_NON_UNIQ_ERROR,
                  col_name.length(),
                  col_name.ptr(),
                  scope_name.length(),
                  scope_name.ptr());
O
oceanbase-admin 已提交
5074 5075 5076 5077 5078
  }

  return ret;
}

5079
int ObSelectResolver::resolve_column_ref_table_first(
W
wangzelin.wzl 已提交
5080 5081
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr,
5082
  bool need_further_match_alias /* = true */)
O
oceanbase-admin 已提交
5083 5084
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5085 5086 5087
  //search column ref in table columns first, follow by alias name
  //if table column exist, check column name whether exist in alias name list
  ObRawExpr *tmp_ref = NULL;
O
oceanbase-admin 已提交
5088
  if (OB_FAIL(resolve_table_column_ref(q_name, real_ref_expr))) {
5089
    if (OB_ERR_BAD_FIELD_ERROR == ret) {
O
oceanbase-admin 已提交
5090 5091 5092
      if (OB_FAIL(resolve_alias_column_ref(q_name, real_ref_expr))) {
        LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve alias column ref failed", K(ret), K(q_name));
      }
W
wangzelin.wzl 已提交
5093 5094
    } else if (OB_NON_UNIQ_ERROR == ret && lib::is_mysql_mode() &&
               T_GROUP_SCOPE == current_scope_) {
Z
zs0 已提交
5095 5096 5097 5098 5099 5100
      // in mysql mode, for t1(c1, c2), t2(c1, c2), select t1.c1 from t1, t2 group by c1;
      // the c1 in group by is resolved as t1.c1 in select items.
      if (OB_FAIL(resolve_alias_column_ref(q_name, real_ref_expr))) {
        ret = OB_NON_UNIQ_ERROR;
        LOG_WARN("resolve table column ref failed", K(ret));
      }
O
oceanbase-admin 已提交
5101 5102 5103
    } else {
      LOG_WARN("resolve table column ref failed", K(ret));
    }
5104 5105 5106 5107 5108 5109 5110 5111
  } else if (need_further_match_alias) {
    if (OB_FAIL(resolve_alias_column_ref(q_name, tmp_ref))) {
      if (OB_ERR_BAD_FIELD_ERROR == ret || OB_ILLEGAL_REFERENCE == ret) {
        ret = OB_SUCCESS;
      } else {
        LOG_WARN("try to hit column on target list failed", K(ret));
      }
    } else if (!ObRawExprUtils::is_same_column_ref(real_ref_expr, tmp_ref)) {
W
wangzelin.wzl 已提交
5112
      //if column name exist in both table columns and alias name list, use table column and produce warning msg
5113 5114 5115
      ObString col_name = concat_qualified_name(q_name.database_name_, q_name.tbl_name_, q_name.col_name_);
      ObString scope_name = ObString::make_string(get_scope_name(current_scope_));
      LOG_USER_WARN(OB_NON_UNIQ_ERROR, col_name.length(), col_name.ptr(), scope_name.length(), scope_name.ptr());
O
oceanbase-admin 已提交
5116
    }
W
wangzelin.wzl 已提交
5117
  }
O
oceanbase-admin 已提交
5118 5119 5120
  return ret;
}

W
wangzelin.wzl 已提交
5121
int ObSelectResolver::create_joined_table_item(JoinedTable *&joined_table)
O
oceanbase-admin 已提交
5122 5123
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5124
  void *ptr = NULL;
O
oceanbase-admin 已提交
5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136
  if (OB_ISNULL(allocator_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("invalid argument", K(ret));
  } else if (NULL == (ptr = allocator_->alloc(sizeof(JoinedTable)))) {
    ret = OB_ALLOCATE_MEMORY_FAILED;
    SQL_RESV_LOG(ERROR, "alloc memory for JoinedTable failed", "size", sizeof(JoinedTable));
  } else {
    joined_table = new (ptr) JoinedTable();
  }
  return ret;
}

W
wangzelin.wzl 已提交
5137
int ObSelectResolver::check_special_join_table(const TableItem &join_table, bool is_left_child, ObItemType join_type)
O
oceanbase-admin 已提交
5138 5139 5140
{
  int ret = OB_SUCCESS;
  if (is_left_child) {
W
wangzelin.wzl 已提交
5141 5142
    if (join_table.is_fake_cte_table() && cte_ctx_.is_with_resolver()
        && (T_JOIN_RIGHT == join_type || T_JOIN_FULL == join_type)) {
O
oceanbase-admin 已提交
5143 5144 5145 5146
      ret = OB_ERR_ILLEGAL_JOIN_IN_RECURSIVE_CTE;
      LOG_WARN("recursive cte table placed at right join's left is not allowed, and full join is not allowed", K(ret));
    }
  } else {
W
wangzelin.wzl 已提交
5147 5148
    if (join_table.is_fake_cte_table() && cte_ctx_.is_with_resolver()
        && (T_JOIN_LEFT == join_type || T_JOIN_FULL == join_type)) {
O
oceanbase-admin 已提交
5149 5150 5151 5152 5153 5154
      ret = OB_ERR_ILLEGAL_JOIN_IN_RECURSIVE_CTE;
      LOG_WARN("recursive cte in left join' right is not allowed, and full join is not allowed", K(ret));
    }
  }
  return ret;
}
W
wangzelin.wzl 已提交
5155 5156 5157 5158 5159 5160
//find coalesce_expr in joined table
//@param jointable_idx: the index of joinedtable, use to match correct using_columns/coalesce_expr in
//               jointable_using_columns and jointable_coalesce_exprs_
int ObSelectResolver::recursive_find_coalesce_expr(const JoinedTable *&joined_table,
                                                    const ObString &cname,
                                                    ObRawExpr *&coalesce_expr)
O
oceanbase-admin 已提交
5161 5162 5163
{
  int ret = OB_SUCCESS;
  bool found = false;
W
wangzelin.wzl 已提交
5164 5165 5166 5167 5168 5169
  ResolverJoinInfo *join_info = NULL;
  if (get_joininfo_by_id(joined_table->table_id_, join_info) && join_info->coalesce_expr_.count() > 0)
  {
    for (int i = 0; !found && i < join_info->coalesce_expr_.count(); i++) {
      if (ObCharset::case_insensitive_equal(join_info->using_columns_.at(i), cname)) {
        coalesce_expr = join_info->coalesce_expr_.at(i);
O
oceanbase-admin 已提交
5170 5171 5172 5173 5174 5175 5176 5177
        found = true;
      }
    }
  }

  if (!found) {
    if (RIGHT_OUTER_JOIN == joined_table->joined_type_) {
      if (TableItem::JOINED_TABLE == joined_table->right_table_->type_) {
W
wangzelin.wzl 已提交
5178
        const JoinedTable *right_table = static_cast<const JoinedTable*>(joined_table->right_table_);
O
oceanbase-admin 已提交
5179 5180 5181
        OZ(SMART_CALL(recursive_find_coalesce_expr(right_table, cname, coalesce_expr)));
      }
    } else if (TableItem::JOINED_TABLE == joined_table->left_table_->type_) {
W
wangzelin.wzl 已提交
5182
      const JoinedTable *left_table = static_cast<const JoinedTable*>(joined_table->left_table_);
O
oceanbase-admin 已提交
5183 5184 5185 5186 5187 5188
      OZ(SMART_CALL(recursive_find_coalesce_expr(left_table, cname, coalesce_expr)));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5189
int ObSelectResolver::resolve_subquery_info(const ObIArray<ObSubQueryInfo> &subquery_info)
O
oceanbase-admin 已提交
5190 5191 5192 5193 5194 5195 5196 5197 5198 5199
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(session_info_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("session info is null");
  } else if (current_level_ + 1 >= OB_MAX_SUBQUERY_LAYER_NUM && subquery_info.count() > 0) {
    ret = OB_NOT_SUPPORTED;
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "too many levels of subqueries");
  }
  for (int64_t i = 0; OB_SUCC(ret) && i < subquery_info.count(); i++) {
W
wangzelin.wzl 已提交
5200
    const ObSubQueryInfo &info = subquery_info.at(i);
O
oceanbase-admin 已提交
5201 5202
    ObSelectResolver subquery_resolver(params_);
    subquery_resolver.set_current_level(current_level_ + 1);
W
wangzelin.wzl 已提交
5203
    subquery_resolver.set_is_sub_stmt(true);
O
oceanbase-admin 已提交
5204
    subquery_resolver.set_parent_namespace_resolver(this);
W
wangzelin.wzl 已提交
5205 5206
    subquery_resolver.set_current_view_level(current_view_level_);
    set_query_ref_expr(info.ref_expr_);
5207 5208
    resolve_alias_for_subquery_ = !(T_FIELD_LIST_SCOPE == current_scope_
                                   && info.parents_expr_info_.has_member(IS_AGG));
W
wangzelin.wzl 已提交
5209 5210 5211 5212 5213 5214 5215 5216 5217
    if (OB_FAIL(subquery_resolver.add_parent_gen_col_exprs(gen_col_exprs_))) {
      LOG_WARN("failed to add parent gen col exprs", K(ret));
    }
    OZ( subquery_resolver.set_cte_ctx(cte_ctx_, true, true) );
    OZ( add_cte_table_to_children(subquery_resolver) );
    if (info.parents_expr_info_.has_member(IS_AGG)) {
      subquery_resolver.set_parent_aggr_level(current_level_);
    } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
      subquery_resolver.set_parent_aggr_level(parent_aggr_level_);
O
oceanbase-admin 已提交
5218
    }
W
wangzelin.wzl 已提交
5219 5220
    OZ ( do_resolve_subquery_info(info, subquery_resolver) );
    set_query_ref_expr(NULL);
O
oceanbase-admin 已提交
5221 5222 5223 5224
  }
  return ret;
}

W
wangzelin.wzl 已提交
5225 5226 5227 5228
//can't find column in current namespace, continue to search column in all parent namespace
//compatible with mysql, use of the outer subqueries column follow these rules
//if subquery in having clause, 1. use column in group by, 2. use column in select list
//such as: select c2 as c1 from t1 group by c1 having c2>(select t1.c1 from t) -> use
O
oceanbase-admin 已提交
5229
// t1.c1 in group by
W
wangzelin.wzl 已提交
5230
//select c1 from t1 group by c2 having c2>(select t1.c3 from t) -> error, t1.c3 not
O
oceanbase-admin 已提交
5231
// in group by or select list
W
wangzelin.wzl 已提交
5232 5233 5234 5235
//if subquery in others clause, 1. use column in table columns, 2. use column in select list
//such as: t1(c1, c2), t2(a), select c1 as c2 from t1 group by (select c2 from t2) -> use t1.c2
//select c1 as c2 from t1 order by (select c2 from t2) -> use t1.c2
//but order by not in subquery will use alias name first, such as: select c1 as c2
O
oceanbase-admin 已提交
5236
// from t1 order by c2 -> use t1.c1
W
wangzelin.wzl 已提交
5237 5238 5239
int ObSelectResolver::resolve_column_ref_for_subquery(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254
{
  int ret = OB_SUCCESS;
  if (OB_UNLIKELY(T_HAVING_SCOPE == current_scope_)) {
    if (OB_FAIL(resolve_column_ref_in_group_by(q_name, real_ref_expr))) {
      LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve column ref in group by failed", K(ret), K(q_name));
    } else {
      if (is_oracle_mode()) {
        if (OB_FAIL(set_having_self_column(real_ref_expr))) {
          LOG_WARN("set having self column failed", K(ret), K(q_name));
        }
      }
    }
  } else if (OB_FAIL(resolve_table_column_ref(q_name, real_ref_expr))) {
    LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve table column failed", K(ret), K(q_name));
  }
5255
  if (OB_ERR_BAD_FIELD_ERROR == ret && resolve_alias_for_subquery_) {
O
oceanbase-admin 已提交
5256 5257 5258 5259 5260 5261 5262
    if (OB_FAIL(resolve_alias_column_ref(q_name, real_ref_expr))) {
      LOG_WARN_IGNORE_COL_NOTFOUND(ret, "resolve alias column ref failed", K(ret), K(q_name));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5263
inline bool ObSelectResolver::column_need_check_group_by(const ObQualifiedName &q_name) const
O
oceanbase-admin 已提交
5264 5265 5266 5267 5268 5269 5270 5271 5272
{
  bool bret = true;
  if (OB_ISNULL(session_info_)) {
    bret = false;
  } else if (!is_only_full_group_by_on(session_info_->get_sql_mode())) {
    bret = false;
  } else if (T_FIELD_LIST_SCOPE != current_scope_ && T_ORDER_SCOPE != current_scope_) {
    bret = false;
  } else if (q_name.parent_aggr_level_ >= 0 && current_level_ <= q_name.parent_aggr_level_) {
W
wangzelin.wzl 已提交
5273 5274 5275 5276 5277 5278 5279 5280 5281 5282
    //aggr_level不为-1说明该column一定存在aggr function中 current_level_ > aggr_level说明
    //引用的current level低于aggr_level
    //即使aggr没有发生上推,current level的column也不会影响aggr的聚集情况,不受聚集的约束
    //这样能够确保这样的column一定不在aggr中,或者在aggr中,但是不受aggr约束,需要检查group by的合法性
    //因此这里会存在误判的可能,因为aggr function还没有被上推,被需要检查,但是没有检查的列,
    //在上推的分析过程中会再次将其加入到standard group checker中
    //例如:select c1, (select (select count(t2.c1+t1.c1) from t3) from t2) from t1;
    //在这个例子中,count()属于第二层,这里认为t2.c1和t1.c1都不需要check group by,
    //但是在aggre上推分析过程中发现,t2.c1位于count()中,不需要检查,t1.c1需要检查,这里误判了,
    //在聚集上推分析中会加入到standard group checker中
O
oceanbase-admin 已提交
5283 5284 5285 5286 5287
    bret = false;
  }
  return bret;
}

W
wangzelin.wzl 已提交
5288 5289 5290
int ObSelectResolver::wrap_alias_column_ref(
  const ObQualifiedName &q_name,
  ObRawExpr *&real_ref_expr)
O
oceanbase-admin 已提交
5291 5292
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5293 5294 5295 5296
  //aggr in window function isn't used to wrap column ref, just only expand alias column, and do
  //wrap alias column ref is used to help analyze aggregate pullup for alias column in aggr. the
  //other situation should expand alias column directly.
  //eg: select sum(t1.c1) from t1 order by (select sum(t1.c1) from t2);
5297
  // sum(t1.c1) in subquery is from parent stmt.
W
wangzelin.wzl 已提交
5298 5299
  if (!q_name.parents_expr_info_.has_member(IS_WINDOW_FUNC) &&
      q_name.parent_aggr_level_ >= 0 &&
5300 5301
      current_level_ <= q_name.parent_aggr_level_) {
    ObAliasRefRawExpr *alias_expr = NULL;
O
oceanbase-admin 已提交
5302
    if (OB_FAIL(ObRawExprUtils::build_alias_column_expr(
W
wangzelin.wzl 已提交
5303 5304 5305 5306
                  *params_.expr_factory_,
                  real_ref_expr,
                  current_level_,
                  alias_expr))) {
O
oceanbase-admin 已提交
5307 5308 5309 5310 5311 5312 5313 5314
      LOG_WARN("build alias column expr failed", K(ret));
    } else {
      real_ref_expr = alias_expr;
    }
  }
  return ret;
}

O
obdev 已提交
5315 5316
int ObSelectResolver::mark_nested_aggr_if_required(
    const ObIArray<ObAggFunRawExpr*> &aggr_exprs)
O
oceanbase-admin 已提交
5317 5318
{
  int ret = OB_SUCCESS;
O
obdev 已提交
5319
  ObSelectStmt *stmt = static_cast<ObSelectStmt*>(get_stmt());
O
oceanbase-admin 已提交
5320
  if (OB_ISNULL(stmt)) {
O
obdev 已提交
5321 5322 5323 5324
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("stmt is null", K(ret), K(stmt));
  } else if (!has_nested_aggr_) {
    for (int64_t i = 0; OB_SUCC(ret) && i < aggr_exprs.count(); i++) {
O
oceanbase-admin 已提交
5325
      if (OB_ISNULL(aggr_exprs.at(i))) {
O
obdev 已提交
5326 5327 5328 5329
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("aggr item is null", K(ret));
      } else if (OB_FAIL(aggr_exprs.at(i)->extract_info())) {
        LOG_WARN("failed to extract info", K(ret));
O
oceanbase-admin 已提交
5330
      } else if (aggr_exprs.at(i)->contain_nested_aggr()) {
O
obdev 已提交
5331 5332 5333
        has_nested_aggr_ = true;
        break;
      }
O
oceanbase-admin 已提交
5334 5335
    }
  }
O
obdev 已提交
5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381
  if (has_nested_aggr_) {
    ObArray<ObAggFunRawExpr*> param_aggrs;
    ObArray<ObWinFunRawExpr *> param_winfuncs;
    if (OB_UNLIKELY(is_mysql_mode())) {
      ret = OB_ERR_INVALID_GROUP_FUNC_USE;
      LOG_WARN("invalid scope for agg function", K(ret));
    }
    for (int64_t i = 0; OB_SUCC(ret) && i < aggr_exprs.count(); ++i) {
      ObAggFunRawExpr *aggr = NULL;
      if (OB_ISNULL(aggr = aggr_exprs.at(i))) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("aggr item is null", K(ret));
      } else if (OB_FAIL(aggr_exprs.at(i)->extract_info())) {
        LOG_WARN("failed to extract info", K(ret));
      } else if (aggr->has_flag(CNT_AGG) ||
                 aggr->has_flag(CNT_WINDOW_FUNC)) {
        for (int64_t j = 0; OB_SUCC(ret) && j < aggr->get_param_count(); ++j) {
          if (OB_FAIL(ObTransformUtils::extract_aggr_expr(aggr->get_param_expr(j),
                                                          param_aggrs))) {
            LOG_WARN("failed to extract aggr expr", K(ret));
          } else if (OB_FAIL(ObTransformUtils::extract_winfun_expr(aggr->get_param_expr(j),
                                                                   param_winfuncs))) {
            LOG_WARN("failed to extract param win funcs", K(ret));
          }
        }
      }
    }
    for (int64_t i = 0; OB_SUCC(ret) && i < param_winfuncs.count(); ++i) {
      if (OB_ISNULL(param_winfuncs.at(i))) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("param winfunc is null", K(ret));
      } else if (param_winfuncs.at(i)->has_flag(CNT_AGG)) {
        ret = OB_ERR_INVALID_GROUP_FUNC_USE;
        LOG_WARN("aggregated nested in same level", K(ret));
      }
    }
    for (int64_t i = 0; OB_SUCC(ret) && i < param_aggrs.count(); ++i) {
      if (OB_ISNULL(param_aggrs.at(i))) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("normal aggr is null", K(ret));
      } else if (param_aggrs.at(i)->contain_nested_aggr()) {
        ret = OB_ERR_INVALID_GROUP_FUNC_USE;
        LOG_WARN("nested aggr should not contain nested aggr", K(ret));
      } else {
        param_aggrs.at(i)->set_in_nested_aggr(true);
      }
O
oceanbase-admin 已提交
5382 5383 5384 5385 5386
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5387 5388
int ObSelectResolver::resolve_aggr_exprs(ObRawExpr *&expr, ObIArray<ObAggFunRawExpr*> &aggr_exprs,
    const bool need_analyze/* = true*/)
O
oceanbase-admin 已提交
5389 5390
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5391 5392 5393
  if (OB_ISNULL(params_.expr_factory_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("expr factory is null", K(ret));
O
obdev 已提交
5394
  } else if (OB_FAIL(mark_nested_aggr_if_required(aggr_exprs))) {
O
oceanbase-admin 已提交
5395 5396 5397
    LOG_WARN("failed check nested aggr.", K(ret));
  } else if (need_analyze) {
    for (int64_t i = 0; OB_SUCC(ret) && i < aggr_exprs.count(); ++i) {
W
wangzelin.wzl 已提交
5398
      ObRawExpr *final_aggr = NULL;
O
oceanbase-admin 已提交
5399 5400 5401 5402
      ObAggrExprPushUpAnalyzer aggr_pushup_analyzer(*this);
      if (OB_ISNULL(aggr_exprs.at(i))) {
        ret = OB_INVALID_ARGUMENT;
        LOG_WARN("invalid aggr_expr", K(ret));
W
wangzelin.wzl 已提交
5403 5404 5405
      } else if (OB_FAIL(aggr_pushup_analyzer.analyze_and_push_up_aggr_expr(*params_.expr_factory_,
                                                                            aggr_exprs.at(i),
                                                                            final_aggr))) {
O
oceanbase-admin 已提交
5406 5407 5408 5409
        LOG_WARN("resolve aggr expr failed", K(ret));
      } else if (final_aggr != aggr_exprs.at(i)) {
        if (OB_FAIL(ObRawExprUtils::replace_ref_column(expr, aggr_exprs.at(i), final_aggr))) {
          LOG_WARN("replace reference column failed", K(ret));
W
wangzelin.wzl 已提交
5410
        } else { /*do nothing.*/ }
O
oceanbase-admin 已提交
5411 5412 5413 5414 5415 5416
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5417
int ObSelectResolver::resolve_win_func_exprs(ObRawExpr *&expr, common::ObIArray<ObWinFunRawExpr*> &win_exprs)
O
oceanbase-admin 已提交
5418 5419
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5420
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
5421 5422 5423 5424 5425
  if (OB_ISNULL(expr) || OB_ISNULL(select_stmt)) {
    ret = OB_INVALID_ARGUMENT;
    LOG_WARN("invalid arg", K(ret), K(expr), K(select_stmt));
  } else {
    for (int64_t i = 0; OB_SUCC(ret) && i < win_exprs.count(); ++i) {
W
wangzelin.wzl 已提交
5426 5427
      ObWinFunRawExpr *win_expr = static_cast<ObWinFunRawExpr *>(win_exprs.at(i));
      ObAggFunRawExpr *agg_expr = win_expr->get_agg_expr();
O
oceanbase-admin 已提交
5428 5429 5430 5431 5432 5433
      if (OB_ISNULL(win_expr)) {
        ret = OB_INVALID_ARGUMENT;
        LOG_WARN("invalid arg", K(ret), K(win_expr));
      } else if (OB_ISNULL(agg_expr)) {
      } else if (OB_FAIL(agg_expr->formalize(session_info_))) {
        LOG_WARN("formalize agg expr failed", K(ret));
W
wangzelin.wzl 已提交
5434 5435
      } else {/*do nothing.*/}
      ObWinFunRawExpr *final_win_expr = NULL;
O
oceanbase-admin 已提交
5436 5437 5438 5439 5440 5441 5442 5443
      const int64_t N = select_stmt->get_window_func_exprs().count();
      if (OB_SUCC(ret)) {
        if (OB_FAIL(check_ntile_compatiable_with_mysql(win_expr))) {
          LOG_WARN("failed to handle compat with mysql ntile.", K(ret));
        } else if (OB_ISNULL(final_win_expr = select_stmt->get_same_win_func_item(win_expr))) {
          ret = select_stmt->add_window_func_expr(win_expr);
        } else if (ObRawExprUtils::replace_ref_column(expr, win_exprs.at(i), final_win_expr)) {
          LOG_WARN("failed to replace ref column.", K(ret), K(*win_exprs.at(i)));
W
wangzelin.wzl 已提交
5444
        } else {/*do nothing.*/}
O
oceanbase-admin 已提交
5445 5446 5447 5448 5449 5450
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5451
int ObSelectResolver::add_aggr_expr(ObAggFunRawExpr *&final_aggr_expr)
O
oceanbase-admin 已提交
5452 5453
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5454 5455
  ObAggFunRawExpr *same_aggr_expr = NULL;
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
5456 5457 5458
  if (OB_ISNULL(select_stmt) || OB_ISNULL(final_aggr_expr) || OB_ISNULL(session_info_)) {
    ret = OB_NOT_INIT;
    LOG_WARN("select_stmt is null", K(select_stmt), K(final_aggr_expr), K_(session_info));
W
wangzelin.wzl 已提交
5459
  } else if (OB_UNLIKELY(select_stmt->is_set_stmt())) {
O
oceanbase-admin 已提交
5460 5461
    ret = OB_ERR_AGGREGATE_ORDER_FOR_UNION;
    LOG_WARN("can't use aggregate function in union stmt");
W
wangzelin.wzl 已提交
5462 5463
  } else if (OB_FAIL(select_stmt->check_and_get_same_aggr_item(final_aggr_expr,
                                                               same_aggr_expr))) {
O
oceanbase-admin 已提交
5464 5465 5466 5467 5468
    LOG_WARN("failed to check and get same aggr item.", K(ret));
  } else if (same_aggr_expr != NULL) {
    final_aggr_expr = same_aggr_expr;
  } else if (OB_FAIL(select_stmt->add_agg_item(*final_aggr_expr))) {
    LOG_WARN("add new aggregate function failed", K(ret));
O
obdev 已提交
5469
  }
O
oceanbase-admin 已提交
5470 5471 5472 5473 5474 5475
  if (OB_SUCC(ret) && is_only_full_group_by_on(session_info_->get_sql_mode())) {
    standard_group_checker_.set_has_group(true);
  }
  return ret;
}

W
wangzelin.wzl 已提交
5476
int ObSelectResolver::add_unsettled_column(ObRawExpr *column_expr)
O
oceanbase-admin 已提交
5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(session_info_)) {

    ret = OB_NOT_INIT;
    LOG_WARN("session_info is null");
  } else if (is_only_full_group_by_on(session_info_->get_sql_mode())) {
    if (OB_FAIL(standard_group_checker_.add_unsettled_column(column_expr))) {
      LOG_WARN("add unsettled column to standard group checker failed", K(ret));
    }
  }
  if (OB_SUCC(ret) && T_HAVING_SCOPE == current_scope_) {
    if (OB_FAIL(check_column_ref_in_group_by_or_field_list(column_expr))) {
      LOG_WARN_IGNORE_COL_NOTFOUND(ret, "check column ref in group by failed", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508
/**
 * create table t1(a int, b int);
 * create table t2(c int);
 * SELECT a FROM t1 GROUP BY a HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20)
 * 在上面的查询中,b位于max()中,但是此时max()还在子查询中,我们不能确定b是否是上层中合法的列
 * 对于having子句,mysql认为having子句中的列必须出现在group exprs中或者出现在aggregate function
 * 以及field list中,列出现在aggregate function中的列可以来源于当前表中的任何列,不需要出现在group by中
 * 而在解析b的时候还无法判断b是否真正位于聚集函数中,因为聚集函数可能上推,也可能无法上推
 * 在resolve column的时候我们将在聚集函数中的列都视为存在aggregate function中,不需要被group by约束
 * 在聚集上推的过程中,确定了聚集函数最终的层次后,我们再将没有出现在aggregate function中的column推回到
 * 应有的层次上进行group by exprs的检查
 */
int ObSelectResolver::check_column_ref_in_group_by_or_field_list(const ObRawExpr *column_ref) const
O
oceanbase-admin 已提交
5509 5510 5511
{
  int ret = OB_SUCCESS;
  bool found_expr = false;
W
wangzelin.wzl 已提交
5512
  const ObSelectStmt *select_stmt = static_cast<const ObSelectStmt*>(stmt_);
O
oceanbase-admin 已提交
5513 5514 5515 5516
  if (OB_ISNULL(select_stmt) || OB_ISNULL(column_ref)) {
    ret = OB_NOT_INIT;
    LOG_WARN("select_stmt is null", K(select_stmt), K(column_ref));
  } else if (column_ref->is_column_ref_expr()) {
W
wangzelin.wzl 已提交
5517 5518 5519 5520
    const ObColumnRefRawExpr *column_expr = static_cast<const ObColumnRefRawExpr*>(column_ref);
    for (int64_t i = 0;
         OB_SUCC(ret) && !found_expr && i < select_stmt->get_group_expr_size();
         ++i) {
O
oceanbase-admin 已提交
5521 5522 5523 5524
      if (select_stmt->get_group_exprs().at(i) == column_ref) {
        found_expr = true;
      }
    }
W
wangzelin.wzl 已提交
5525 5526 5527
    for (int64_t i = 0;
         OB_SUCC(ret) && !found_expr && i < select_stmt->get_select_item_size();
         ++i) {
O
oceanbase-admin 已提交
5528 5529 5530 5531 5532 5533 5534
      if (select_stmt->get_select_item(i).expr_ == column_ref) {
        found_expr = true;
      }
    }
    if (OB_SUCC(ret) && !found_expr) {
      ret = OB_ERR_BAD_FIELD_ERROR;
      ObString column_name = concat_qualified_name(
W
wangzelin.wzl 已提交
5535 5536 5537
        column_expr->get_database_name(),
        column_expr->get_table_name(),
        column_expr->get_column_name());
O
oceanbase-admin 已提交
5538 5539
      ObString scope_name = ObString::make_string(get_scope_name(current_scope_));
      LOG_USER_ERROR(
W
wangzelin.wzl 已提交
5540 5541 5542 5543 5544
        OB_ERR_BAD_FIELD_ERROR,
        column_name.length(),
        column_name.ptr(),
        scope_name.length(),
        scope_name.ptr());
O
oceanbase-admin 已提交
5545 5546 5547 5548 5549
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5550 5551
// use_sys_tenant 标记是否需要以系统租户的身份获取schema
int ObSelectResolver::check_need_use_sys_tenant(bool &use_sys_tenant) const
O
oceanbase-admin 已提交
5552 5553 5554
{
  int ret = OB_SUCCESS;
  if (params_.is_from_show_resolver_) {
W
wangzelin.wzl 已提交
5555
    // 若当前已经是系统租户, 则忽略
O
oceanbase-admin 已提交
5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569
    if (OB_ISNULL(session_info_)) {
      ret = OB_NOT_INIT;
      LOG_WARN("session info is null");
    } else if (OB_SYS_TENANT_ID == session_info_->get_effective_tenant_id()) {
      use_sys_tenant = false;
    } else {
      use_sys_tenant = true;
    }
  } else {
    use_sys_tenant = false;
  }
  return ret;
}

W
wangzelin.wzl 已提交
5570
int ObSelectResolver::check_in_sysview(bool &in_sysview) const
O
oceanbase-admin 已提交
5571 5572 5573 5574 5575 5576
{
  int ret = OB_SUCCESS;
  in_sysview = params_.is_from_show_resolver_;
  return ret;
}

W
wangzelin.wzl 已提交
5577
int ObSelectResolver::resolve_start_with_clause(const ParseNode *node)
O
oceanbase-admin 已提交
5578 5579
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5580
  if (node != NULL) {//存在start with clause
O
oceanbase-admin 已提交
5581
    current_scope_ = T_START_WITH_SCOPE;
W
wangzelin.wzl 已提交
5582
    ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
5583 5584 5585 5586 5587 5588 5589 5590 5591 5592
    if (OB_ISNULL(select_stmt)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("select stmt is NULL", K(ret));
    } else if (OB_FAIL(resolve_and_split_sql_expr(*node, select_stmt->get_start_with_exprs()))) {
      LOG_WARN("resolve and split sql expr failed", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5593
int ObSelectResolver::check_connect_by_expr_validity(const ObRawExpr *raw_expr)
O
oceanbase-admin 已提交
5594 5595
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613
  if (OB_ISNULL(raw_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("expr is null", K(ret));
  } else if (OB_UNLIKELY(raw_expr->is_pseudo_column_expr() &&
                         raw_expr->get_expr_type() != T_LEVEL)) {
    ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED;
    LOG_WARN("Only Level pseudo allow here", K(ret));
  } else if (OB_UNLIKELY(raw_expr->is_aggr_expr() ||
                          raw_expr->get_expr_class() == ObRawExpr::EXPR_PL_QUERY_REF)) {
    ret = OB_NOT_SUPPORTED;
    LOG_USER_ERROR(OB_NOT_SUPPORTED, "expr in connect by");
    LOG_WARN("expr is not supported here for connect by condition", K(ret));
  } else {
    for (int64_t i = 0; i < raw_expr->get_param_count() && OB_SUCC(ret); i++) {
      if (OB_FAIL(check_connect_by_expr_validity(raw_expr->get_param_expr(i)))) {
        LOG_WARN("check_connect_by_expr_validity failed", K(ret));
      }
    }
O
oceanbase-admin 已提交
5614
  }
W
wangzelin.wzl 已提交
5615 5616 5617 5618 5619 5620 5621
  return ret;
}

int ObSelectResolver::resolve_connect_by_clause(const ParseNode *node)
{
  int ret = OB_SUCCESS;
  if (node != NULL) {//存在connect by clause
O
oceanbase-admin 已提交
5622
    current_scope_ = T_CONNECT_BY_SCOPE;
W
wangzelin.wzl 已提交
5623 5624 5625 5626 5627 5628 5629 5630 5631 5632
    ObSelectStmt *select_stmt = get_select_stmt();
    const ParseNode *nocycle_node = NULL;
    const ParseNode *connect_by_exprs_node = NULL;
    if (OB_ISNULL(select_stmt)
        || OB_UNLIKELY(node->num_child_ != 2)
        || OB_UNLIKELY(node->type_ != T_CONNECT_BY_CLAUSE)
        || OB_ISNULL(connect_by_exprs_node = node->children_[1])) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("invalid argument", K(select_stmt), K(node->num_child_),
               K(node->type_), K(connect_by_exprs_node), K(ret));
O
oceanbase-admin 已提交
5633
    } else {
O
obdev 已提交
5634
      expr_resv_ctx_.set_new_scope();
O
oceanbase-admin 已提交
5635 5636
      nocycle_node = node->children_[0];
      select_stmt->set_nocycle(nocycle_node != NULL);
W
wangzelin.wzl 已提交
5637 5638 5639
      OZ( resolve_and_split_sql_expr(
            *connect_by_exprs_node,
            select_stmt->get_connect_by_exprs()) );
O
oceanbase-admin 已提交
5640
      for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_connect_by_exprs().count(); ++i) {
W
wangzelin.wzl 已提交
5641 5642 5643 5644 5645
        ObRawExpr *raw_expr = NULL;
        if (OB_ISNULL(raw_expr = select_stmt->get_connect_by_exprs().at(i))) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("connect by expr is null", K(ret));
        } else if (raw_expr->has_flag(CNT_CONNECT_BY_ROOT)) {
O
oceanbase-admin 已提交
5646
          ret = OB_ERR_CBY_CONNECT_BY_ROOT_ILLEGAL_USED;
W
wangzelin.wzl 已提交
5647 5648
          LOG_WARN("CONNECT BY ROOT operator is not supported in the START WITH or in the CONNECT BY condition", K(ret));
        } else if (raw_expr->has_flag(CNT_SYS_CONNECT_BY_PATH)) {
O
oceanbase-admin 已提交
5649
          ret = OB_ERR_CBY_CONNECT_BY_PATH_NOT_ALLOWED;
W
wangzelin.wzl 已提交
5650 5651 5652 5653 5654
          LOG_WARN("CONNECT BY PATH operator is not supported in the START WITH or in the CONNECT BY condition", K(ret));
        } else if (OB_FAIL(check_connect_by_expr_validity(raw_expr))) {
          LOG_WARN("check_connect_by_expr_validity failed", K(ret));
        } else if (raw_expr->has_flag(CNT_PRIOR)) {
          select_stmt->set_has_prior(true);
O
oceanbase-admin 已提交
5655 5656
        }
      }
O
obdev 已提交
5657
      expr_resv_ctx_.set_new_scope();
O
oceanbase-admin 已提交
5658 5659 5660 5661 5662
    }
    // window function in select list not supported.
    if (OB_SUCC(ret)) {
      int64_t count = select_stmt->get_select_item_size();
      for (int64_t i = 0; i < count && OB_SUCC(ret); ++i) {
W
wangzelin.wzl 已提交
5663
        SelectItem &select_item = select_stmt->get_select_item(i);
O
oceanbase-admin 已提交
5664 5665 5666 5667 5668
        if (OB_ISNULL(select_item.expr_)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("select item is null", K(ret));
        } else if (select_item.expr_->has_flag(CNT_WINDOW_FUNC)) {
          ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
5669
          LOG_USER_ERROR(OB_NOT_SUPPORTED, "window function in connect by");
O
oceanbase-admin 已提交
5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680
          LOG_WARN("window function in connect by not supported", K(ret));
        }
      }
    }
  }
  return ret;
}

int ObSelectResolver::check_pseudo_columns()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5681
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
5682 5683 5684 5685 5686 5687
  if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null", K(select_stmt), K_(session_info));
  }

  for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_pseudo_column_like_exprs().count(); ++i) {
W
wangzelin.wzl 已提交
5688
    ObRawExpr *pseudo_column = select_stmt->get_pseudo_column_like_exprs().at(i);
O
oceanbase-admin 已提交
5689 5690 5691
    if (OB_ISNULL(pseudo_column)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("invalid pseudo column", K(ret));
W
wangzelin.wzl 已提交
5692 5693
    } else if (T_CONNECT_BY_ISCYCLE == pseudo_column->get_expr_type()
               && !select_stmt->is_nocycle()) {
O
oceanbase-admin 已提交
5694 5695 5696 5697 5698 5699 5700 5701
      ret = OB_ERR_CBY_NOCYCLE_REQUIRED;
      LOG_WARN("NOCYCLE keyword is required with CONNECT_BY_ISCYCLE pseudo column", K(ret));
    }
  }

  if (OB_FAIL(ret)) {
  } else if (select_stmt->is_order_siblings()) {
    for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_order_item_size(); ++i) {
W
wangzelin.wzl 已提交
5702
      const ObRawExpr *sort_expr = select_stmt->get_order_item(i).expr_;
O
oceanbase-admin 已提交
5703 5704 5705 5706 5707 5708 5709 5710 5711
      if (OB_ISNULL(sort_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("sort expr is NULL", K(ret));
      } else if (OB_UNLIKELY(sort_expr->has_flag(CNT_SYS_CONNECT_BY_PATH))) {
        ret = OB_ERR_CBY_CONNECT_BY_PATH_NOT_ALLOWED;
        LOG_WARN("Connect by path not allowed here", K(ret));
      } else if (OB_UNLIKELY(sort_expr->has_flag(CNT_CONNECT_BY_ROOT))) {
        ret = OB_ERR_CBY_CONNECT_BY_ROOT_ILLEGAL_USED;
        LOG_WARN("Connect by root not allowed here", K(ret));
W
wangzelin.wzl 已提交
5712 5713
      } else if (OB_UNLIKELY(sort_expr->has_flag(CNT_PSEUDO_COLUMN))
                 || OB_UNLIKELY(sort_expr->has_flag(CNT_PRIOR))) {
O
oceanbase-admin 已提交
5714 5715
        ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED;
        LOG_WARN("invalid sort expr for order siblings", KPC(sort_expr), K(ret));
W
wangzelin.wzl 已提交
5716 5717
      } else if (OB_UNLIKELY(sort_expr->has_flag(CNT_SUB_QUERY))
                 || OB_UNLIKELY(sort_expr->has_flag(CNT_AGG))) {
O
oceanbase-admin 已提交
5718
        ret = OB_NOT_SUPPORTED;
W
wangzelin.wzl 已提交
5719 5720
        LOG_USER_ERROR(OB_NOT_SUPPORTED,
                       "Subquery or aggregate function in order siblings by clause is");
O
oceanbase-admin 已提交
5721 5722 5723 5724 5725 5726
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5727 5728 5729 5730 5731
//同oracle一样, ntile(arg1) (partition by arg2...) 要求arg1 = arg2或者是基于arg2的运算, 如同group by 和 select的有效性检查
int ObSelectResolver::check_win_func_arg_valid(ObSelectStmt *select_stmt,
                                               const ObItemType func_type,
                                               common::ObIArray<ObRawExpr *> &arg_exp_arr,
                                               common::ObIArray<ObRawExpr *> &partition_exp_arr)
O
oceanbase-admin 已提交
5732 5733 5734 5735 5736 5737 5738
{
  int ret = OB_SUCCESS;
  if (T_WIN_FUN_NTILE == func_type || T_FUN_GROUP_CONCAT == func_type) {
    if (OB_ISNULL(select_stmt)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected stmt", K(ret));
    } else {
O
obdev 已提交
5739 5740 5741 5742 5743 5744
      // skip add const constraint during prepare stage in PL
      const ParamStore *param_store = (NULL != params_.secondary_namespace_) ? NULL : params_.param_list_;
      if (OB_FAIL(ObGroupByChecker::check_analytic_function(param_store,
                                                            select_stmt,
                                                            arg_exp_arr,
                                                            partition_exp_arr))) {
O
oceanbase-admin 已提交
5745 5746 5747 5748 5749 5750 5751 5752 5753 5754
        LOG_WARN("check_analytic_function failed", K(ret));
      }
    }
  }
  return ret;
}

int ObSelectResolver::check_window_exprs()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5755
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
5756 5757 5758 5759 5760 5761
  if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null", K(select_stmt));
  }

  for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_window_func_exprs().count(); ++i) {
W
wangzelin.wzl 已提交
5762
    ObWinFunRawExpr *win_expr = select_stmt->get_window_func_exprs().at(i);
O
oceanbase-admin 已提交
5763 5764 5765
    if (OB_ISNULL(win_expr)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("NULL ptr", K(win_expr), K(ret));
W
wangzelin.wzl 已提交
5766 5767
    } else if (win_expr->get_agg_expr() != NULL &&
               win_expr->get_agg_expr()->has_flag(CNT_WINDOW_FUNC)) {
O
oceanbase-admin 已提交
5768 5769 5770
      ret = OB_ERR_INVALID_WINDOW_FUNC_USE;
      LOG_WARN("agg function's param cannot be window function", K(ret));
    } else {
W
wangzelin.wzl 已提交
5771 5772 5773 5774 5775 5776 5777 5778 5779
      const ObIArray<ObRawExpr *> &partition_exprs = win_expr->get_partition_exprs();
      const ObIArray<OrderItem> &order_items = win_expr->get_order_items();
      ObSEArray<ObRawExpr *, 4> exprs;
      ObSEArray<ObRawExpr *, 4> arg_exprs;
      ObRawExpr *bound_expr_arr[2] = {NULL, NULL};
      bool need_check_order_datatype = (lib::is_oracle_mode()
                                       && WINDOW_RANGE == win_expr->get_window_type()
                                       && (BOUND_INTERVAL == win_expr->get_upper().type_
                                           || BOUND_INTERVAL == win_expr->get_lower().type_));
O
oceanbase-admin 已提交
5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794
      for (int64_t j = 0; OB_SUCC(ret) && j < partition_exprs.count(); ++j) {
        ret = exprs.push_back(partition_exprs.at(j));
      }
      for (int64_t j = 0; OB_SUCC(ret) && j < order_items.count(); ++j) {
        ret = exprs.push_back(order_items.at(j).expr_);
      }
      if (OB_SUCC(ret) && win_expr->get_upper().interval_expr_ != NULL) {
        ret = exprs.push_back(win_expr->get_upper().interval_expr_);
        bound_expr_arr[0] = win_expr->get_upper().interval_expr_;
      }
      if (OB_SUCC(ret) && win_expr->get_lower().interval_expr_ != NULL) {
        ret = exprs.push_back(win_expr->get_lower().interval_expr_);
        bound_expr_arr[1] = win_expr->get_lower().interval_expr_;
      }
      for (int64_t j = 0; OB_SUCC(ret) && j < exprs.count(); ++j) {
W
wangzelin.wzl 已提交
5795 5796
        ObRawExpr *expr = exprs.at(j);
        if (OB_UNLIKELY(expr->has_flag(CNT_WINDOW_FUNC))) {
O
oceanbase-admin 已提交
5797 5798
          ret = OB_ERR_INVALID_WINDOW_FUNC_USE;
          LOG_WARN("partition or sort or interval expr within window function nest window function not supported",
W
wangzelin.wzl 已提交
5799
                   K(ret), K(*expr), K(j));
O
oceanbase-admin 已提交
5800 5801 5802
        }
      }
      if (OB_FAIL(ret)) {
W
wangzelin.wzl 已提交
5803 5804
        //do nothing...
      } else if (T_FUN_GROUP_CONCAT == win_expr->get_func_type() && NULL != win_expr->get_agg_expr() && is_oracle_mode()) {
O
oceanbase-admin 已提交
5805 5806
        if (win_expr->get_agg_expr()->get_real_param_exprs().count() > 2) {
          ret = OB_INVALID_ARGUMENT_NUM;
W
wangzelin.wzl 已提交
5807
          LOG_WARN("incorrect argument number to call listagg", K(win_expr->get_agg_expr()->get_real_param_exprs().count()));
O
oceanbase-admin 已提交
5808 5809 5810 5811 5812 5813 5814 5815 5816 5817
        } else if (win_expr->get_agg_expr()->get_real_param_exprs().count() == 2) {
          if (OB_FAIL(arg_exprs.push_back(win_expr->get_agg_expr()->get_real_param_exprs().at(1)))) {
            LOG_WARN("push seperator expr failed", K(ret));
          }
        }
      } else {
        if (OB_FAIL(arg_exprs.assign(win_expr->get_func_params()))) {
          LOG_WARN("assign func param failed", K(ret));
        }
      }
W
wangzelin.wzl 已提交
5818 5819 5820 5821 5822
      //检查分析函数参数 和 partition by是否符合要求
      if (OB_SUCC(ret) && OB_FAIL(check_win_func_arg_valid(select_stmt,
                                                           win_expr->get_func_type(),
                                                           arg_exprs,
                                                           const_cast<ObIArray<ObRawExpr *>&>(partition_exprs)))) {
O
oceanbase-admin 已提交
5823 5824
        LOG_WARN("argument should be a function of expressions in PARTITION BY", K(ret));
      }
W
wangzelin.wzl 已提交
5825
      //检查frame是range时数据类型的有效性, 规则同oracle
O
oceanbase-admin 已提交
5826 5827 5828 5829 5830 5831 5832 5833 5834
      if (OB_SUCC(ret) && need_check_order_datatype) {
        if (1 != order_items.count()) {
          ret = OB_ERR_INVALID_WINDOW_FUNC_USE;

          LOG_WARN("invalid window specification", K(ret), K(order_items.count()));
        } else if (OB_ISNULL(order_items.at(0).expr_)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("order by expr should not be null!", K(ret));
        } else {
W
wangzelin.wzl 已提交
5835 5836
          for (int64_t i = 0; OB_SUCC(ret) && i < 2; ++ i) {
            const ObObjType &order_res_type = order_items.at(0).expr_->get_data_type();
O
oceanbase-admin 已提交
5837
            if (bound_expr_arr[i] != NULL) {
W
wangzelin.wzl 已提交
5838 5839
              if (ob_is_numeric_type(bound_expr_arr[i]->get_data_type())
                  || ob_is_string_tc(bound_expr_arr[i]->get_data_type())) {
O
oceanbase-admin 已提交
5840 5841 5842 5843 5844
                if (!ob_is_numeric_type(order_res_type) && !ob_is_datetime_tc(order_res_type)) {
                  ret = OB_ERR_INVALID_WINDOW_FUNC_USE;
                  LOG_WARN("invalid datatype in order by for range clause", K(ret), K(order_res_type));
                }
              } else {
W
wangzelin.wzl 已提交
5845
                //to do: 支持interval后这里要处理interval的情况
O
oceanbase-admin 已提交
5846
                ret = OB_ERR_INVALID_WINDOW_FUNC_USE;
W
wangzelin.wzl 已提交
5847 5848
                LOG_WARN("invalid datatype in order by", K(i),
                         K(bound_expr_arr[i]->get_data_type()), K(ret), K(order_res_type));
O
oceanbase-admin 已提交
5849 5850 5851 5852 5853
              }
            }
          }
        }
      }
W
wangzelin.wzl 已提交
5854 5855
      // oracle 模式下不允许对 lob 类型进行 order by
      if (OB_SUCC(ret) && lib::is_oracle_mode()) {
O
oceanbase-admin 已提交
5856
        for (int64_t i = 0; OB_SUCC(ret) && i < order_items.count(); ++i) {
X
xj0 已提交
5857 5858
          if (ob_is_text_tc(order_items.at(i).expr_->get_data_type())
              || ob_is_lob_tc(order_items.at(i).expr_->get_data_type())
O
obdev 已提交
5859
              || ob_is_json_tc(order_items.at(i).expr_->get_data_type())
X
xianyu-w 已提交
5860 5861
              || ob_is_geometry_tc(order_items.at(i).expr_->get_data_type())
              || ob_is_extend(order_items.at(i).expr_->get_data_type())) {
O
oceanbase-admin 已提交
5862
            ret = OB_ERR_INVALID_TYPE_FOR_OP;
X
xianyu-w 已提交
5863
            LOG_WARN("lob or udt expr can't order", K(ret), K(*order_items.at(i).expr_));
O
oceanbase-admin 已提交
5864 5865 5866
          }
        }
      }
W
wangzelin.wzl 已提交
5867 5868 5869 5870 5871 5872 5873
      if (OB_SUCC(ret) && lib::is_oracle_mode()) {
        for (int64_t i = 0; OB_SUCC(ret) && i < partition_exprs.count(); i++) {
          ObRawExpr *param_expr = partition_exprs.at(i);
          if (OB_ISNULL(param_expr)) {
            ret = OB_ERR_UNEXPECTED;
            LOG_WARN("param is null", K(ret));
          } else if (ob_is_lob_locator(param_expr->get_data_type())
X
xianyu-w 已提交
5874 5875
                    || ob_is_text_tc(param_expr->get_data_type())
                    || ob_is_extend(param_expr->get_data_type())) {
W
wangzelin.wzl 已提交
5876 5877 5878 5879 5880
            ret = OB_ERR_INVALID_TYPE_FOR_OP;
            LOG_WARN("invalid partition by expr", K(ret), K(i), KPC(param_expr));
          }
        }
      }
O
oceanbase-admin 已提交
5881 5882
    }
  }
W
wangzelin.wzl 已提交
5883 5884 5885 5886 5887
  for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_having_exprs().count() +
         select_stmt->get_group_exprs().count(); ++i) {
    ObRawExpr *expr = i < select_stmt->get_having_exprs().count() ?
       select_stmt->get_having_exprs().at(i) :
       select_stmt->get_group_exprs().at(i - select_stmt->get_having_exprs().count());
O
oceanbase-admin 已提交
5888 5889 5890 5891 5892
    if (OB_ISNULL(expr)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("NULL ptr", K(i), K(expr));
    } else if (OB_UNLIKELY(expr->has_flag(CNT_WINDOW_FUNC))) {
      ret = OB_ERR_INVALID_WINDOW_FUNC_USE;
W
wangzelin.wzl 已提交
5893 5894
      LOG_WARN("window function exists in having or group scope not supported",
               K(ret), K(*expr), K(i));
O
oceanbase-admin 已提交
5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912
    }
  }

  return ret;
}

int ObSelectResolver::check_pseudo_column_name_legal(const ObString& name)
{
  int ret = OB_SUCCESS;
  for (int64_t i = 0; OB_SUCC(ret) && i < cte_ctx_.cte_col_names_.count(); ++i) {
    if (ObCharset::case_insensitive_equal(cte_ctx_.cte_col_names_.at(i), name)) {
      ret = OB_ERR_CTE_ILLEGAL_SEARCH_PSEUDO_NAME;
      LOG_WARN("the pseudo column can not be same with the defined cte column name", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5913 5914 5915 5916 5917 5918

/* sequence 有如下禁忌用法:
 *  1. 不能同时与 limit、having、order by、group by 等一起使用
 *  2. 不能出现在 subquery 中的任何地方 (insert into select 除外)
 *  3. 不能出现在 where 表达式里(resolve expr 处检查过了)
 **/
O
oceanbase-admin 已提交
5919 5920 5921
int ObSelectResolver::check_sequence_exprs()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5922
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
5923 5924 5925 5926
  if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null", K(select_stmt));
  } else if (select_stmt->has_sequence()) {
W
wangzelin.wzl 已提交
5927 5928 5929 5930 5931 5932
    if (select_stmt->has_limit() ||
        select_stmt->has_order_by() ||
        select_stmt->has_distinct() ||
        select_stmt->has_having() ||
        select_stmt->has_group_by() ||
        params_.is_from_create_view_) {
O
oceanbase-admin 已提交
5933 5934
      ret = OB_ERR_SEQ_NOT_ALLOWED_HERE;
      LOG_WARN("sequence can not be used with create-view/select-subquery/orderby/limit/groupby/distinct", K(ret));
W
wangzelin.wzl 已提交
5935

O
oceanbase-admin 已提交
5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950
    }
  }
  return ret;
}

/*
 *  The recursive component of the UNION ALL in a recursive WITH clause
 *  element used an operation that was currently not supported.  The
 *  following should not be used in the recursive branch of the
 *  UNION ALL operation: GROUP BY, DISTINCT, MODEL, grouping sets,
 *  CONNECT BY, window functions, HAVING, aggregate functions.
 **/
int ObSelectResolver::check_unsupported_operation_in_recursive_branch()
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
5951
  ObSelectStmt *select_stmt = get_select_stmt();
O
oceanbase-admin 已提交
5952 5953 5954 5955 5956
  if (!cte_ctx_.is_recursive()) {
    // Do nothing
  } else if (cte_ctx_.cte_resolve_level_ >= 2) {
    // Recursive table cann't be quoted in a subquery,
    // Q1:
W
wangzelin.wzl 已提交
5957 5958 5959 5960 5961 5962
    // with cte(c1) as (select 1 from dual union all select c1 + 1 from (select * from cte where c1 < 3) where c1 < 5) select * from cte;
    // You will got a error, 32042. 00000 -  "recursive WITH clause must reference itself directly in one of the UNION ALL branches"
    // Q2:
    // with cte(c,d) AS (SELECT c1,c2 from t1 where c1 < 3 union all select c+1, d+1 from cte, t2 where t2.c1 = c and t2.c2 > some (select c1 from t44  t99 group by c1)) select * from cte;
    // No need to check subquery at the rigth union, because recursive table cann't be here.
    // So.do nothing
O
oceanbase-admin 已提交
5963 5964 5965 5966
  } else if (OB_ISNULL(select_stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("select stmt is null", K(select_stmt));
  } else {
W
wangzelin.wzl 已提交
5967 5968 5969 5970 5971 5972 5973
    if (select_stmt->has_order_by() ||
        select_stmt->has_distinct() ||
        select_stmt->has_having() ||
        select_stmt->has_group_by() ||
        !select_stmt->get_window_func_exprs().empty() ||
        !select_stmt->get_connect_by_exprs().empty() ||
        !select_stmt->get_aggr_items().empty()) {
O
oceanbase-admin 已提交
5974 5975 5976 5977 5978 5979 5980
      ret = OB_ERR_CTE_ILLEGAL_RECURSIVE_BRANCH;
      LOG_WARN("unsupported operation in recursive branch of recursive WITH clause", K(ret));
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
5981
int ObSelectResolver::resolve_all_fake_cte_table_columns(const TableItem &table_item, common::ObIArray<ColumnItem> *column_items)
O
oceanbase-admin 已提交
5982 5983 5984 5985
{
  return ObDMLResolver::resolve_all_basic_table_columns(table_item, false, column_items);
}

W
wangzelin.wzl 已提交
5986
int ObSelectResolver::check_recursive_cte_usage(const ObSelectStmt &select_stmt)
O
oceanbase-admin 已提交
5987 5988 5989 5990
{
  int ret = OB_SUCCESS;
  int64_t fake_cte_table_count = 0;
  for (int64_t i = 0; i < select_stmt.get_table_items().count(); ++i) {
W
wangzelin.wzl 已提交
5991
    const TableItem *table_item = select_stmt.get_table_items().at(i);
O
oceanbase-admin 已提交
5992 5993 5994 5995 5996 5997 5998 5999 6000
    if (table_item->is_fake_cte_table()) {
      fake_cte_table_count++;
    }
  }
  if (cte_ctx_.invalid_recursive_union() && fake_cte_table_count >= 1) {
    ret = OB_ERR_NEED_UNION_ALL_IN_RECURSIVE_CTE;
    LOG_WARN("recursive WITH clause must use a UNION ALL operation", K(ret));
  } else if (fake_cte_table_count > 1) {
    ret = OB_ERR_CTE_RECURSIVE_QUERY_NAME_REFERENCED_MORE_THAN_ONCE;
W
wangzelin.wzl 已提交
6001
    LOG_WARN("Recursive query name referenced more than once in recursive branch of recursive WITH clause element", K(ret), K(fake_cte_table_count));
O
oceanbase-admin 已提交
6002 6003 6004 6005
  }
  return ret;
}

W
wangzelin.wzl 已提交
6006
int ObSelectResolver::check_correlated_column_ref(const ObSelectStmt &select_stmt, ObRawExpr *expr, bool &correalted_query)
O
oceanbase-admin 已提交
6007 6008 6009
{
  int ret = OB_SUCCESS;
  if (expr->is_column_ref_expr()) {
W
wangzelin.wzl 已提交
6010
    ObColumnRefRawExpr *col_expr = static_cast<ObColumnRefRawExpr*>(expr);
O
oceanbase-admin 已提交
6011
    uint64_t table_id = col_expr->get_table_id();
W
wangzelin.wzl 已提交
6012
    const TableItem *table_item = nullptr;
O
oceanbase-admin 已提交
6013 6014 6015 6016 6017 6018 6019 6020 6021 6022
    if (nullptr == (table_item = select_stmt.get_table_item_by_id(table_id))) {
      correalted_query = true;
      LOG_WARN("Column expr not in this stmt", K(ret));
    } else {
      LOG_DEBUG("Find table item", K(*select_stmt.get_table_item_by_id(table_id)));
    }
  }
  if (!correalted_query) {
    int64_t param_expr_count = expr->get_param_count();
    for (int64_t i = 0; i < param_expr_count && !correalted_query; ++i) {
W
wangzelin.wzl 已提交
6023
      ObRawExpr *param_expr = expr->get_param_expr(i);
O
oceanbase-admin 已提交
6024 6025 6026
      if (OB_ISNULL(param_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("Param expr is null", K(ret));
W
wangzelin.wzl 已提交
6027 6028
      } else if (OB_FAIL(SMART_CALL(check_correlated_column_ref(select_stmt, param_expr,
                                                                correalted_query)))) {
O
oceanbase-admin 已提交
6029 6030 6031 6032 6033 6034 6035
        LOG_WARN("Failed to check correlated column", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6036
int ObSelectResolver::check_ntile_compatiable_with_mysql(ObWinFunRawExpr *win_expr)
O
oceanbase-admin 已提交
6037 6038
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
6039 6040 6041 6042 6043 6044 6045
  if (OB_ISNULL(win_expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("win expr is null.", K(ret));
  } else if (T_WIN_FUN_NTILE == win_expr->get_func_type() && lib::is_mysql_mode()) {
    if (1 != win_expr->get_func_params().count()) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("ntile param count should be 1", K(ret));
O
oceanbase-admin 已提交
6046
    } else {
W
wangzelin.wzl 已提交
6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057
      ObRawExpr *func_param = win_expr->get_func_params().at(0);
      bool is_valid = true;
      if (OB_ISNULL(func_param)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("param is null", K(ret));
      } else if (OB_FAIL(check_ntile_validity(func_param, is_valid))) {
        LOG_WARN("failed to check ntile validity", K(ret));
      } else if (!is_valid) {
        ret = OB_ERR_NOT_CONST_EXPR;
        LOG_WARN("The argument of the window function should be a constant for a partition", K(ret), K(*func_param));
      }
O
oceanbase-admin 已提交
6058 6059 6060 6061 6062
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6063 6064
int ObSelectResolver::check_ntile_validity(const ObRawExpr *expr,
                                           bool &is_valid)
6065 6066
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
6067
  if (OB_ISNULL(expr)) {
6068
    ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090
    LOG_WARN("expr is null", K(ret));
  } else if (expr->is_column_ref_expr() ||
             expr->is_aggr_expr() ||
             expr->is_win_func_expr() ||
             expr->get_expr_type() == T_FUN_SYS_RAND) {
    is_valid = false;
  } else if (expr->is_exec_param_expr()) {
    if (OB_FAIL(SMART_CALL(check_ntile_validity(static_cast<const ObExecParamRawExpr *>(expr)->get_ref_expr(),
                                                is_valid)))) {
      LOG_WARN("failed to check ntile validity", K(ret));
    }
  }
  for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < expr->get_param_count(); ++i) {
    if (OB_FAIL(SMART_CALL(check_ntile_validity(expr->get_param_expr(i),
                                                is_valid)))) {
      LOG_WARN("failed to check ntile validity", K(ret));
    }
  }
  if (OB_SUCC(ret) && expr->is_query_ref_expr()) {
    if (OB_FAIL(SMART_CALL(check_ntile_validity(static_cast<const ObQueryRefRawExpr *>(expr)->get_ref_stmt(),
                                                is_valid)))) {
      LOG_WARN("failed to check ntile validity", K(ret));
6091 6092 6093 6094 6095
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6096 6097
int ObSelectResolver::check_ntile_validity(const ObSelectStmt *stmt,
                                           bool &is_valid) {
O
oceanbase-admin 已提交
6098
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
6099 6100 6101
  ObArray<ObSelectStmt*> child_stmts;
  ObArray<ObRawExpr *> relation_exprs;
  if (OB_ISNULL(stmt)) {
O
oceanbase-admin 已提交
6102
    ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120
    LOG_WARN("stmt is null", K(ret));
  } else if (stmt->get_column_size() > 0 ||
             stmt->get_window_func_count() > 0 ||
             stmt->get_aggr_item_size() > 0) {
    is_valid = false;
  } else if (OB_FAIL(stmt->get_child_stmts(child_stmts))) {
    LOG_WARN("failed to get child stmts", K(ret));
  } else if (OB_FAIL(stmt->get_relation_exprs(relation_exprs))) {
    LOG_WARN("failed to get relation exprs", K(ret));
  }
  for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < relation_exprs.count(); ++i) {
    if (OB_FAIL(check_ntile_validity(relation_exprs.at(i), is_valid))) {
      LOG_WARN("failed to check ntile validity", K(ret));
    }
  }
  for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < child_stmts.count(); ++i) {
    if (OB_FAIL(check_ntile_validity(child_stmts.at(i), is_valid))) {
      LOG_WARN("failed to check ntile validity", K(ret));
O
oceanbase-admin 已提交
6121 6122 6123 6124 6125
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6126 6127 6128 6129 6130 6131
/**
 * oracle在select item中如果有子查询,当且仅当
 * 子查询为exists、not exists的参数时,
 * 允许子查询返回多列,
 */
int ObSelectResolver::check_subquery_return_one_column(const ObRawExpr &expr, bool is_exists_param)
O
oceanbase-admin 已提交
6132 6133 6134 6135 6136 6137
{
  int ret = OB_SUCCESS;
  if (T_FUN_UDF == expr.get_expr_type()) {
    // select ff(cursor(select * from tbl)) from dual;
    // do nothing
  } else if (expr.has_flag(IS_SUB_QUERY)) {
W
wangzelin.wzl 已提交
6138
    const ObQueryRefRawExpr &query_expr = static_cast<const ObQueryRefRawExpr&>(expr);
O
oceanbase-admin 已提交
6139 6140 6141 6142 6143 6144 6145
    if (1 != query_expr.get_output_column() && !is_exists_param) {
      ret = OB_ERR_TOO_MANY_VALUES;
      LOG_WARN("subquery return too many columns", K(query_expr.get_output_column()));
    }
  } else {
    bool is_exists_param = T_OP_EXISTS == expr.get_expr_type() || T_OP_NOT_EXISTS == expr.get_expr_type();
    for (int64_t i = 0; OB_SUCC(ret) && i < expr.get_param_count(); ++i) {
W
wangzelin.wzl 已提交
6146
      const ObRawExpr *cur_expr = expr.get_param_expr(i);
O
oceanbase-admin 已提交
6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159
      if (OB_ISNULL(cur_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get null expr", K(ret));
      } else if (!cur_expr->has_flag(CNT_SUB_QUERY)) {
        // do nothing
      } else if (OB_FAIL(check_subquery_return_one_column(*cur_expr, is_exists_param))) {
        LOG_WARN("failed to check subquery return one column", K(ret));
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6160

O
oceanbase-admin 已提交
6161
/*fetch clause:
W
wangzelin.wzl 已提交
6162
*[OFFSET offset {ROW | ROWS}] FETCH {NEXT | FIRST} {rowcount| percent PERCENT} {ROW | ROWS} {ONLY | WITH TIES}
O
oceanbase-admin 已提交
6163
 */
W
wangzelin.wzl 已提交
6164
int ObSelectResolver::resolve_fetch_clause(const ParseNode *node)
O
oceanbase-admin 已提交
6165 6166 6167 6168 6169
{
  int ret = OB_SUCCESS;
  if (OB_ISNULL(params_.expr_factory_) || OB_ISNULL(session_info_)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(params_.expr_factory_));
W
wangzelin.wzl 已提交
6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214
  } else if (lib::is_oracle_mode() && NULL != node) {
    current_scope_ = T_LIMIT_SCOPE;
    ObSelectStmt *select_stmt = get_select_stmt();
    select_stmt->set_has_fetch(true);
    ParseNode *limit_node = NULL;
    ParseNode *offset_node = NULL;
    ParseNode *percent_node = NULL;
    if (node->type_ == T_FETCH_CLAUSE) {
      offset_node = node->children_[0];
      limit_node = node->children_[1];
      percent_node = node->children_[2];
    } else if (node->type_ == T_FETCH_TIES_CLAUSE) {
      offset_node = node->children_[0];
      limit_node = node->children_[1];
      percent_node = node->children_[2];
      if (select_stmt->has_order_by()) {
        select_stmt->set_fetch_with_ties(true);
      }
    }
    ObRawExpr* limit_offset = NULL;
    ObRawExpr* case_limit_offset = NULL;
    ObRawExpr* limit_count = NULL;
    ObRawExpr* case_limit_count = NULL;
    ObRawExpr* limit_percent = NULL;
    //1.处理offset node,由于oracle支持为常量的double类型,但是对于行数来说,本质上为整型,同时兼容oracle行为,
    //  向下取整,由于老引擎cast函数转换时无法保证向下取整,所以需要显示分配一个floor函数
    if (offset_node != NULL) {
      ObSysFunRawExpr *floor_offset_expr = NULL;
      if (OB_FAIL(resolve_sql_expr(*offset_node, limit_offset))) {
        LOG_WARN("failed to resolve sql expr", K(ret));
      } else if (OB_ISNULL(limit_offset)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret), K(limit_offset));
      } else if (!limit_offset->is_const_expr()) {
        ret = OB_ERR_INVALID_SQL_ROW_LIMITING;
        LOG_WARN("Invalid SQL ROW LIMITING expression was specified", K(ret));
      } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_FUN_SYS_FLOOR,
                                                                floor_offset_expr))) {
        LOG_WARN("failed to create fun sys floor", K(ret));
      } else if (OB_ISNULL(floor_offset_expr)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("floor expr is null", K(ret));
      } else if (OB_FAIL(floor_offset_expr->set_param_expr(limit_offset))) {
        LOG_WARN("failed to set param expr", K(ret));
      //保证offset为非负数,避免在计划生成时转换limit + offset出现负数,需要进行二次处理
O
obdev 已提交
6215
      } else if (OB_ISNULL(limit_offset = floor_offset_expr)) {
W
wangzelin.wzl 已提交
6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null", K(ret), K(limit_offset));
      } else {
        floor_offset_expr->set_func_name(ObString::make_string("FLOOR"));
        ObExprResType dst_type;
        dst_type.set_int();
        ObSysFunRawExpr *cast_expr = NULL;
        OZ(ObRawExprUtils::create_cast_expr(
                *params_.expr_factory_, limit_offset, dst_type, cast_expr, session_info_));
        CK(NULL != cast_expr);
        OX(limit_offset = cast_expr);
        OZ(limit_offset->add_flag(IS_INNER_ADDED_EXPR));
      }
    }
    //2.1 处理fetch node ==> limit count同上,可以在resolve阶段提前计算出结果
    if (OB_SUCC(ret)) {
      if (limit_node != NULL) {
        ObSysFunRawExpr *floor_count_expr = NULL;
        if (OB_FAIL(resolve_sql_expr(*limit_node, limit_count))) {
O
oceanbase-admin 已提交
6235
          LOG_WARN("failed to resolve sql expr", K(ret));
W
wangzelin.wzl 已提交
6236
        } else if (OB_ISNULL(limit_count)) {
O
oceanbase-admin 已提交
6237
          ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
6238 6239
          LOG_WARN("get unexpected null", K(ret), K(limit_count));
        } else if (!limit_count->is_const_expr()) {
O
oceanbase-admin 已提交
6240 6241
          ret = OB_ERR_INVALID_SQL_ROW_LIMITING;
          LOG_WARN("Invalid SQL ROW LIMITING expression was specified", K(ret));
W
wangzelin.wzl 已提交
6242 6243
        } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_FUN_SYS_FLOOR,
                                                                  floor_count_expr))) {
O
oceanbase-admin 已提交
6244
          LOG_WARN("failed to create fun sys floor", K(ret));
W
wangzelin.wzl 已提交
6245
        } else if (OB_ISNULL(floor_count_expr)) {
O
oceanbase-admin 已提交
6246 6247
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("floor expr is null", K(ret));
W
wangzelin.wzl 已提交
6248
        } else if (OB_FAIL(floor_count_expr->set_param_expr(limit_count))) {
O
oceanbase-admin 已提交
6249
          LOG_WARN("failed to set param expr", K(ret));
O
obdev 已提交
6250 6251
        //保证limit为非负数,避免在计划生成时转换limit + offset出现负数,在preprocess进行二次处理
        } else if (OB_ISNULL(limit_count = floor_count_expr)) {
O
oceanbase-admin 已提交
6252
          ret = OB_ERR_UNEXPECTED;
W
wangzelin.wzl 已提交
6253
          LOG_WARN("get unexpected null", K(ret), K(limit_count));
O
oceanbase-admin 已提交
6254
        } else {
W
wangzelin.wzl 已提交
6255
          floor_count_expr->set_func_name(ObString::make_string("FLOOR"));
O
oceanbase-admin 已提交
6256 6257
          ObExprResType dst_type;
          dst_type.set_int();
W
wangzelin.wzl 已提交
6258
          ObSysFunRawExpr *cast_expr = NULL;
O
oceanbase-admin 已提交
6259
          OZ(ObRawExprUtils::create_cast_expr(
W
wangzelin.wzl 已提交
6260
                  *params_.expr_factory_, limit_count, dst_type, cast_expr, session_info_));
O
oceanbase-admin 已提交
6261
          CK(NULL != cast_expr);
W
wangzelin.wzl 已提交
6262 6263
          OX(limit_count = cast_expr);
          OZ(limit_count->add_flag(IS_INNER_ADDED_EXPR));
O
oceanbase-admin 已提交
6264 6265
        }
      }
W
wangzelin.wzl 已提交
6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287
    }
    //2.2 处理fetch node ==> limit percent,由于这里计算的为总行数的百分比,因此不能直接转为int,同时考虑计算的总
    //                                     行时存在小数,因此这里统一设置百分比为double类型
    if (OB_SUCC(ret)) {
      if (percent_node != NULL) {
        if (OB_FAIL(resolve_sql_expr(*percent_node, limit_percent))) {
          LOG_WARN("failed to resolve sql expr", K(ret));
        } else if (OB_ISNULL(limit_percent)) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("get unexpected null", K(ret), K(limit_percent));
        } else if (!limit_percent->is_const_expr()) {
          ret = OB_ERR_INVALID_SQL_ROW_LIMITING;
          LOG_WARN("Invalid SQL ROW LIMITING expression was specified", K(ret));
        } else {
          ObExprResType dst_type;
          dst_type.set_double();
          ObSysFunRawExpr *cast_expr = NULL;
          OZ(ObRawExprUtils::create_cast_expr(
                  *params_.expr_factory_, limit_percent, dst_type, cast_expr, session_info_));
          CK(NULL != cast_expr);
          OX(limit_percent = cast_expr);
          OZ(limit_percent->add_flag(IS_INNER_ADDED_EXPR));
O
oceanbase-admin 已提交
6288 6289
        }
      }
W
wangzelin.wzl 已提交
6290 6291 6292
    }
    if (OB_SUCC(ret)) {
      select_stmt->set_fetch_info(limit_offset, limit_count, limit_percent);
O
oceanbase-admin 已提交
6293 6294 6295 6296 6297
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318
int ObSelectResolver::resolve_check_option_clause(const ParseNode *node)
{
  int ret = OB_SUCCESS;
  if (NULL != node) {
    const int64_t node_value = node->value_;
    ObSelectStmt *select_stmt = get_select_stmt();
    if (OB_UNLIKELY(node_value < 0 || node_value >= static_cast<int64_t>(VIEW_CHECK_OPTION_MAX))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unexpected check option node value", K(ret), K(node_value));
    } else if (OB_ISNULL(select_stmt)) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("select stmt is null", K(ret));
    } else {
      select_stmt->set_check_option(static_cast<ViewCheckOption>(node_value));
    }
  }
  return ret;
}

int ObSelectResolver::check_multi_rollup_items_valid(
                                              const ObIArray<ObMultiRollupItem> &multi_rollup_items)
O
oceanbase-admin 已提交
6319 6320 6321
{
  int ret = OB_SUCCESS;
  for (int64_t i = 0; OB_SUCC(ret) && i < multi_rollup_items.count(); i++) {
W
wangzelin.wzl 已提交
6322
    const ObIArray<ObGroupbyExpr> &rollup_list_exprs = multi_rollup_items.at(i).rollup_list_exprs_;
O
oceanbase-admin 已提交
6323
    for (int64_t j = 0; OB_SUCC(ret) && j < rollup_list_exprs.count(); ++j) {
W
wangzelin.wzl 已提交
6324
      const ObIArray<ObRawExpr*> &groupby_exprs = rollup_list_exprs.at(j).groupby_exprs_;
O
oceanbase-admin 已提交
6325
      for (int64_t k = 0; OB_SUCC(ret) && k < groupby_exprs.count(); ++k) {
W
wangzelin.wzl 已提交
6326
        ObRawExpr *groupby_expr = NULL;
O
oceanbase-admin 已提交
6327 6328 6329
        if (OB_ISNULL(groupby_expr = groupby_exprs.at(k))) {
          ret = OB_ERR_UNEXPECTED;
          LOG_WARN("rollup expr is null", K(ret));
W
wangzelin.wzl 已提交
6330 6331
        } else if (ObLongTextType == groupby_expr->get_data_type()
                  || ObLobType == groupby_expr->get_data_type()
O
obdev 已提交
6332
                  || ObJsonType == groupby_expr->get_data_type()
X
xianyu-w 已提交
6333 6334
                  || ObGeometryType == groupby_expr->get_data_type()
                  || ObExtendType == groupby_expr->get_data_type()) {
O
oceanbase-admin 已提交
6335
          ret = OB_ERR_INVALID_TYPE_FOR_OP;
X
xianyu-w 已提交
6336
          LOG_WARN("group by lob or udt expr is not allowed", K(ret));
O
oceanbase-admin 已提交
6337 6338 6339 6340 6341 6342 6343
        }
      }
    }
  }
  return ret;
}

W
wangzelin.wzl 已提交
6344
int ObSelectResolver::recursive_check_grouping_columns(ObSelectStmt *stmt, ObRawExpr *expr)
O
oceanbase-admin 已提交
6345 6346
{
  int ret = OB_SUCCESS;
W
wangzelin.wzl 已提交
6347
  ObAggFunRawExpr *c_expr = NULL;
O
oceanbase-admin 已提交
6348 6349 6350 6351 6352 6353
  if (OB_ISNULL(stmt) || OB_ISNULL(expr)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null", K(ret), K(stmt), K(expr));
  } else if (!expr->has_flag(CNT_AGG)) {
    /*do nothing*/
  } else if (T_FUN_GROUPING == expr->get_expr_type()) {
W
wangzelin.wzl 已提交
6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365
    if (OB_ISNULL(c_expr = static_cast<ObAggFunRawExpr*>(expr))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unable to convert expr to ObAggFunRawExpr", K(ret));
    } else if (c_expr->is_nested_aggr()) {
      ret = OB_ERR_GROUP_FUNC_NOT_ALLOWED;
      LOG_WARN("grouping shouldn't be nested", K(ret));
    } else if (1 != c_expr->get_real_param_exprs().count() ||
               OB_ISNULL(c_expr->get_real_param_exprs().at(0))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("check grouping has unexpected err", K(ret));      
    } else if (OB_FAIL(check_grouping_columns(*stmt,
                                  c_expr->get_real_param_exprs_for_update().at(0)))) {
O
oceanbase-admin 已提交
6366 6367
      LOG_WARN("failed to check grouping columns", K(ret));
    } else {
W
wangzelin.wzl 已提交
6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394
      assign_grouping();
    }
  } else if (T_FUN_GROUPING_ID == expr->get_expr_type()) {
    if (OB_ISNULL(c_expr = static_cast<ObAggFunRawExpr*>(expr))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unable to convert expr to ObAggFunRawExpr", K(ret));
    } else if (c_expr->is_nested_aggr()) {
      ret = OB_ERR_GROUP_FUNC_NOT_ALLOWED;
      LOG_WARN("grouping shouldn't be nested", K(ret));
    } else if (c_expr->get_real_param_count() < 1) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("check grouping_id has unexpected err", K(ret));
    } else {
      for (int64_t i = 0; OB_SUCC(ret) && i < c_expr->get_real_param_count(); i++) {
        if (OB_FAIL(check_grouping_columns(*stmt,
                                  c_expr->get_real_param_exprs_for_update().at(i)))) {
          LOG_WARN("fail to check grouping columns", K(ret));
        }
      }
    }
  } else if (T_FUN_GROUP_ID == expr->get_expr_type()) {
    if (OB_ISNULL(c_expr = static_cast<ObAggFunRawExpr*>(expr))) {
      ret = OB_ERR_UNEXPECTED;
      LOG_WARN("unable to convert expr to ObAggFunRawExpr", K(ret));
    } else if (c_expr->is_nested_aggr()) {
      ret = OB_ERR_GROUP_FUNC_NOT_ALLOWED;
      LOG_WARN("group_id shouldn't be nested", K(ret));
O
oceanbase-admin 已提交
6395 6396 6397 6398 6399
    }
  } else {
    for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) {
      if (OB_FAIL(SMART_CALL(recursive_check_grouping_columns(stmt, expr->get_param_expr(i))))) {
        LOG_WARN("failed to recursive check grouping columns", K(ret));
W
wangzelin.wzl 已提交
6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426
      } else {/*do nothing*/}
    }
  }
  return ret;
}


int ObSelectResolver::add_name_for_anonymous_view()
{
  int ret = OB_SUCCESS;
  ObSelectStmt *stmt = get_select_stmt();
  if (OB_ISNULL(stmt)) {
    ret = OB_ERR_UNEXPECTED;
    LOG_WARN("get unexpected null pointer", K(ret));
  } else {
    for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_table_size(); i++) {
      TableItem *tmp_table = stmt->get_table_item(i);
      if (OB_ISNULL(tmp_table)) {
        ret = OB_ERR_UNEXPECTED;
        LOG_WARN("get unexpected null pointer", K(ret));
      } else if (tmp_table->is_generated_table()
                && tmp_table->alias_name_.empty()
                && tmp_table->table_name_.empty()) {
        // found anonymous view, generate new name.
        if (OB_FAIL(stmt->generate_anonymous_view_name(*params_.allocator_, tmp_table->table_name_))) {
          LOG_WARN("fail to generate view name", K(ret));
        }
O
oceanbase-admin 已提交
6427 6428 6429
      }
    }
  }
W
wangzelin.wzl 已提交
6430

O
oceanbase-admin 已提交
6431 6432 6433 6434 6435
  return ret;
}

}  // namespace sql
}  // namespace oceanbase