/**
 * Copyright (c) 2021 OceanBase
 * OceanBase CE is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#ifndef OCEANBASE_SQL_OB_UPDATE_STMT_H
#define OCEANBASE_SQL_OB_UPDATE_STMT_H
#include "lib/utility/ob_print_utils.h"
#include "sql/resolver/dml/ob_del_upd_stmt.h"
#include "sql/resolver/dml/ob_dml_stmt.h"
#include "sql/ob_sql_context.h"
namespace oceanbase {
namespace sql {
/**
 * UPDATE syntac from MySQL 5.7
 *
 * Single-table syntax:
 UPDATE [LOW_PRIORITY] [IGNORE] table_reference
 *   SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
 *   [WHERE where_condition]
 *   [ORDER BY ...]
 *   [LIMIT row_count]
 *
 * Multiple-table syntax:
 *   UPDATE [LOW_PRIORITY] [IGNORE] table_references
 *   SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
 *   [WHERE where_condition]
 */
class ObUpdateStmt : public ObDelUpdStmt {
public:
  ObUpdateStmt();
  virtual ~ObUpdateStmt();
  int deep_copy_stmt_struct(
      ObStmtFactory& stmt_factory, ObRawExprFactory& expr_factory, const ObDMLStmt& other) override;
  int assign(const ObUpdateStmt& other);
  const ObTablesAssignments& get_tables_assignments() const
  {
    return tables_assignments_;
  }
  ObTablesAssignments& get_tables_assignments()
  {
    return tables_assignments_;
  }
  int get_tables_assignments_exprs(ObIArray<ObRawExpr*>& exprs);
  // functions for convenience
  int64_t get_table_count() const
  {
    return tables_assignments_.count();
  }
  void set_update_set(bool update_set)
  {
    update_set_ = update_set;
  }
  bool is_update_set() const
  {
    return update_set_;
  }

  int get_assign_values(ObIArray<ObRawExpr*>& exprs) const;
  int get_vector_assign_values(ObQueryRefRawExpr* query_ref, ObIArray<ObRawExpr*>& assign_values) const;
  int check_assign();

  int update_base_tid_cid() override;

  // Used to replace all references to from expr in stmt, from from to to expr
  // The search space is only in the expr directly referenced by stmt, and will not recurse into expr
  virtual int replace_expr_in_stmt(ObRawExpr* from, ObRawExpr* to) override;
  virtual int has_special_expr(const ObExprInfoFlag, bool& has) const override;
  virtual int replace_inner_stmt_expr(
      const common::ObIArray<ObRawExpr*>& other_exprs, const common::ObIArray<ObRawExpr*>& new_exprs) override;
  int refill_global_index_dml_info(ObRawExprFactory& expr_factory, bool use_static_typing_engine);
  const ObTablesAssignments* get_slice_from_all_table_assignments(
      common::ObIAllocator& allocator, int64_t table_idx, int64_t index_idx) const;

  TO_STRING_KV(N_STMT_TYPE, stmt_type_, N_TABLE, table_items_, N_IS_IGNORE, ignore_, N_PARTITION_EXPR, part_expr_items_,
      N_COLUMN, column_items_, "input_columns", all_table_columns_, N_ASSIGN, tables_assignments_, N_WHERE,
      condition_exprs_, N_ORDER_BY, order_items_, N_LIMIT, limit_count_expr_, N_OFFSET, limit_offset_expr_,
      N_QUERY_HINT, stmt_hint_, N_QUERY_CTX, query_ctx_);

protected:
  // Get the root expr of all query-related expressions in stmt
  //(expression generated by the attributes specified in the query statement)
  virtual int inner_get_relation_exprs(RelExprCheckerBase& expr_checker) override;
  // Get the root expr that needs to be processed by enum_set_wrapper in stmt
  virtual int inner_get_relation_exprs_for_wrapper(RelExprChecker& expr_checker) override
  {
    return inner_get_relation_exprs(expr_checker);
  }

private:
  ObTablesAssignments tables_assignments_;
  /**
   * @note These fields are added for the compatiblity of MySQL syntax and are not
   * supported at the moment.
   */
  bool low_priority_;
  bool update_set_;
  bool use_static_typing_engine_;
};
}  // namespace sql
}  // namespace oceanbase

#endif  // OCEANBASE_SQL_OB_UPDATE_STMT_H
