/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015 Pivotal Software, Inc.
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *     University of Wisconsin—Madison.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 **/

#ifndef QUICKSTEP_PARSER_PARSE_STATEMENT_HPP_
#define QUICKSTEP_PARSER_PARSE_STATEMENT_HPP_

#include <memory>
#include <string>
#include <vector>

#include "parser/ParseAssignment.hpp"
#include "parser/ParseAttributeDefinition.hpp"
#include "parser/ParseBasicExpressions.hpp"
#include "parser/ParseBlockProperties.hpp"
#include "parser/ParseIndexProperties.hpp"
#include "parser/ParseKeyValue.hpp"
#include "parser/ParsePartitionClause.hpp"
#include "parser/ParsePredicate.hpp"
#include "parser/ParseSelect.hpp"
#include "parser/ParseString.hpp"
#include "parser/ParseSubqueryTableReference.hpp"
#include "parser/ParseTreeNode.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrList.hpp"
#include "utility/PtrVector.hpp"

#include "glog/logging.h"

namespace quickstep {

/** \addtogroup Parser
 *  @{
 */

/**
 * @brief Abstract base class for all complete SQL commands.
 **/
class ParseStatement : public ParseTreeNode {
 public:
  /**
   * @brief The possible types of SQL statements.
   **/
  enum StatementType {
    kCreateTable,
    kCreateIndex,
    kDropTable,
    kSelect,
    kInsert,
    kCopyFrom,
    kUpdate,
    kDelete,
    kQuit,
    kCommand
  };

  /**
   * @brief Virtual destructor.
   **/
  ~ParseStatement() override {
  }

  /**
   * @brief Identify the type of this SQL statement.
   *
   * @return The type of this statement.
   **/
  virtual StatementType getStatementType() const = 0;

 protected:
  ParseStatement(const int line_number, const int column_number)
      : ParseTreeNode(line_number, column_number) {
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ParseStatement);
};

/**
 * @brief The parsed representation of a CREATE TABLE statement.
 **/
class ParseStatementCreateTable : public ParseStatement {
 public:
  /**
   * @brief Constructor.
   *
   * @param relation_name The name of the relation to create.
   * @param attribute_definition_list The list of definitions for the
   *        attributes in the new relation, which becomes owned by this
   *        ParseStatementCreateTable.
   * @param opt_block_properties Optional physical properties of the block.
   **/
  ParseStatementCreateTable(const int line_number,
                            const int column_number,
                            ParseString *relation_name,
                            PtrList<ParseAttributeDefinition> *attribute_definition_list,
                            ParseBlockProperties *opt_block_properties,
                            ParsePartitionClause *opt_partition_clause)
      : ParseStatement(line_number, column_number),
        relation_name_(relation_name),
        attribute_definition_list_(attribute_definition_list),
        opt_block_properties_(opt_block_properties),
        opt_partition_clause_(opt_partition_clause) {
  }

  ~ParseStatementCreateTable() override {
  }

  StatementType getStatementType() const override {
    return kCreateTable;
  }

  std::string getName() const override { return "CreateTableStatement"; }

  /**
   * @brief Get the name of the relation to create.
   *
   * @return The new relation's name.
   **/
  const ParseString* relation_name() const {
    return relation_name_.get();
  }

  /**
   * @brief Get the list of attribute definitions.
   *
   * @return The list of attribute definitions for the new relation.
   **/
  const PtrList<ParseAttributeDefinition>& attribute_definition_list() const {
    return *attribute_definition_list_;
  }

  /**
   * @brief Get a pointer to the BlockProperties.
   *
   * @return The BlockProperties or nullptr if not specified.
   **/
  const ParseBlockProperties* opt_block_properties() const {
    return opt_block_properties_.get();
  }

  /**
   * @brief Get a pointer to the PartitionClause.
   *
   * @return The PartitionClause or nullptr if not specified.
   **/
  const ParsePartitionClause* opt_partition_clause() const {
    return opt_partition_clause_.get();
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("relation_name");
    inline_field_values->push_back(relation_name_->value());

    container_child_field_names->push_back("attribute_list");
    container_child_fields->emplace_back();
    for (const ParseAttributeDefinition& attribute_definition : *attribute_definition_list_) {
      container_child_fields->back().push_back(&attribute_definition);
    }

    if (opt_block_properties_) {
      container_child_field_names->push_back("block_properties");
      container_child_fields->emplace_back();
      container_child_fields->back().push_back(opt_block_properties_.get());
    }

    if (opt_partition_clause_) {
      container_child_field_names->push_back("partition_clause");
      container_child_fields->emplace_back();
      container_child_fields->back().push_back(opt_partition_clause_.get());
    }
  }

 private:
  std::unique_ptr<ParseString> relation_name_;
  std::unique_ptr<PtrList<ParseAttributeDefinition> > attribute_definition_list_;
  std::unique_ptr<ParseBlockProperties> opt_block_properties_;
  std::unique_ptr<ParsePartitionClause> opt_partition_clause_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementCreateTable);
};

  /**
   * @brief The parsed representation of a CREATE INDEX statement.
   **/
class ParseStatementCreateIndex : public ParseStatement {
 public:
    /**
     * @brief Constructor.
     *
     * @param index_name The name of the index to create.
     * @param relation_name The name of the relation to create index upon.
     * @param attribute_name_list A list of attributes of the relation
     *        on which the index has to be created. If specified as null,
     *        then index is created on all the attributes.
     * @param index_type The type of index to create.
     **/
    ParseStatementCreateIndex(const int line_number,
                              const int column_number,
                              ParseString *index_name,
                              ParseString *relation_name,
                              PtrList<ParseAttribute> *attribute_list,
                              ParseString *index_type)
        : ParseStatement(line_number, column_number),
          index_name_(index_name),
          relation_name_(relation_name),
          attribute_list_(attribute_list),
          index_type_(index_type) {
      initializeIndexType();
    }

    /**
     * @brief Constructor.
     *
     * @param index_name The name of the index to create.
     * @param relation_name The name of the relation to create index upon.
     * @param attribute_name_list A list of attributes of the relation
     *        on which the index has to be created. If specified as null,
     *        then index is created on all the attributes.
     * @param index_type The type of index to create.
     * @param index_properties_line_number
     * @param index_properties_column_number
     * @param opt_index_properties Optional index properties that were specified.
     **/
    ParseStatementCreateIndex(const int line_number,
                              const int column_number,
                              ParseString *index_name,
                              ParseString *relation_name,
                              PtrList<ParseAttribute> *attribute_list,
                              ParseString *index_type,
                              const int index_properties_line_number,
                              const int index_properties_column_number,
                              PtrList<ParseKeyValue> *opt_index_properties)
        : ParseStatement(line_number, column_number),
          index_name_(index_name),
          relation_name_(relation_name),
          attribute_list_(attribute_list),
          index_type_(index_type) {
      initializeIndexType();
      custom_properties_node_.reset(new ParseIndexProperties(index_properties_line_number,
                                                                   index_properties_column_number,
                                                                   opt_index_properties));
      index_properties_->addCustomProperties(custom_properties_node_->getKeyValueList());
    }

    ~ParseStatementCreateIndex() override {
    }

    StatementType getStatementType() const override {
      return kCreateIndex;
    }

    std::string getName() const override { return "CreateIndexStatement"; }

    /**
     * @brief Get the name of the index to create.
     *
     * @return The index's name.
     **/
    const ParseString* index_name() const {
      return index_name_.get();
    }

    /**
     * @brief Get the name of the relation to create index upon.
     *
     * @return The relation's name.
     **/
    const ParseString* relation_name() const {
      return relation_name_.get();
    }

    /**
     * @brief Get the list of attributes on which index is supposed to be defined.
     *
     * @return The list of attributes on which index is to be built.
     **/
    const PtrList<ParseAttribute>* attribute_list() const {
      return attribute_list_.get();
    }

    /**
     * @brief Get the type of the index to be created.
     *
     * @return The index's type.
     **/
    const ParseString* index_type() const {
      return index_type_.get();
    }

    /**
     * @brief Get the index properties associated with this index type.
     *
     * @return The index properties for this type.
     **/
    const IndexProperties* getIndexProperties() const {
      return index_properties_.get();
    }

    const ParseIndexProperties* getCustomPropertiesNode() const {
      return custom_properties_node_.get();
    }

    bool hasCustomProperties() const {
      return custom_properties_node_ != nullptr;
    }

 protected:
    void getFieldStringItems(
       std::vector<std::string> *inline_field_names,
       std::vector<std::string> *inline_field_values,
       std::vector<std::string> *non_container_child_field_names,
       std::vector<const ParseTreeNode*> *non_container_child_fields,
       std::vector<std::string> *container_child_field_names,
       std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
      inline_field_names->push_back("index_name");
      inline_field_values->push_back(index_name_->value());

      inline_field_names->push_back("relation_name");
      inline_field_values->push_back(relation_name_->value());

      inline_field_names->push_back("index_type");
      const int index_type_enum_val = std::stoi(index_type_->value());
      switch (index_type_enum_val) {
        case IndexSubBlockType::kBitWeavingV:  // Fall through.
        case IndexSubBlockType::kBitWeavingH:
          inline_field_values->push_back("bitweaving");
          break;
        case IndexSubBlockType::kCSBTree:
          inline_field_values->push_back("cs_b_tree");
          break;
        case IndexSubBlockType::kBloomFilter:
          inline_field_values->push_back("bloom_filter");
          break;
        case IndexSubBlockType::kSMA:
          inline_field_values->push_back("sma");
          break;
        default:
          inline_field_values->push_back("unknown");
      }

      if (attribute_list_ != nullptr) {
        container_child_field_names->push_back("attribute_list");
        container_child_fields->emplace_back();
        for (const ParseAttribute &attribute : *attribute_list_) {
          container_child_fields->back().push_back(&attribute);
        }
      }

      if (custom_properties_node_ != nullptr) {
        container_child_field_names->push_back("index_property_list");
        container_child_fields->emplace_back();
        container_child_fields->back().push_back(custom_properties_node_.get());
      }
    }

 private:
    std::unique_ptr<ParseString> index_name_;
    std::unique_ptr<ParseString> relation_name_;
    std::unique_ptr<PtrList<ParseAttribute>> attribute_list_;
    std::unique_ptr<ParseString> index_type_;
    std::unique_ptr<IndexProperties> index_properties_;
    // Optional custom properties for the index can be specified during creation.
    std::unique_ptr<const ParseIndexProperties> custom_properties_node_;

    void initializeIndexType() {
      const int index_type_enum_val = std::stoi(index_type_->value());
      switch (index_type_enum_val) {
        case IndexSubBlockType::kBitWeavingV:  // Fall through.
        case IndexSubBlockType::kBitWeavingH:
          index_properties_.reset(new BitWeavingIndexProperties());
          break;
        case IndexSubBlockType::kBloomFilter:
          index_properties_.reset(new BloomFilterIndexProperties());
          break;
        case IndexSubBlockType::kCSBTree:
          index_properties_.reset(new CSBTreeIndexProperties());
          break;
        case IndexSubBlockType::kSMA:
          index_properties_.reset(new SMAIndexProperties());
          break;
        default:
          LOG(FATAL) << "Unknown index subblock type.";
          break;
      }
    }

    DISALLOW_COPY_AND_ASSIGN(ParseStatementCreateIndex);
};

/**
 * @brief The parsed representation of a DROP TABLE statement.
 **/
class ParseStatementDropTable : public ParseStatement {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param relation_name The name of the relation to drop.
   **/
  ParseStatementDropTable(const int line_number, const int column_number, ParseString *relation_name)
      : ParseStatement(line_number, column_number),
        relation_name_(relation_name) {
  }

  /**
   * @brief Destructor.
   */
  ~ParseStatementDropTable() override {
  }

  StatementType getStatementType() const override {
    return kDropTable;
  }

  std::string getName() const override { return "DropTableStatement"; }

  /**
   * @brief Get the name of the relation to drop.
   *
   * @return The name of the relation to drop.
   **/
  const ParseString* relation_name() const {
    return relation_name_.get();
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("relation_name");
    inline_field_values->push_back(relation_name_->value());
  }

 private:
  std::unique_ptr<ParseString> relation_name_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementDropTable);
};

/**
 * @brief The parsed representation of a SELECT statement.
 **/
class ParseStatementSelect : public ParseStatement {
 public:
  /**
   * @brief Constructor.
   * @note Takes ownership of all pointers.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param select_query The top-level SELECT query.
   * @param with_clause The WITH clause of common table query expressions.
   **/
  ParseStatementSelect(const int line_number,
                       const int column_number,
                       ParseSelect *select_query,
                       PtrVector<ParseSubqueryTableReference> *with_clause)
      : ParseStatement(line_number, column_number),
        select_query_(select_query),
        with_clause_(with_clause) {
  }

  /**
   * @brief Destructor.
   */
  ~ParseStatementSelect() override {
  }

  StatementType getStatementType() const override {
    return kSelect;
  }

  std::string getName() const override { return "SelectStatement"; }

  /**
   * @return Gets the top-level SELECT query.
   */
  const ParseSelect* select_query() const {
    return select_query_.get();
  }

  /**
   * @brief Gets the WITH table queries.
   *
   * @return The parsed WITH table list.
   */
  const PtrVector<ParseSubqueryTableReference>* with_clause() const {
    return with_clause_.get();
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    non_container_child_field_names->push_back("select_query");
    non_container_child_fields->push_back(select_query_.get());

    if (with_clause_ != nullptr && !with_clause_->empty()) {
      container_child_field_names->push_back("with_clause");
      container_child_fields->emplace_back();
      for (const ParseSubqueryTableReference &common_subquery : *with_clause_) {
        container_child_fields->back().push_back(&common_subquery);
      }
    }
  }

 private:
  std::unique_ptr<ParseSelect> select_query_;
  std::unique_ptr<PtrVector<ParseSubqueryTableReference>> with_clause_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementSelect);
};

/**
 * @brief The parsed representation of an INSERT statement.
 *
 * This is an abstract class where each of its subclass represents a concrete
 * type of insert operation.
 **/
class ParseStatementInsert : public ParseStatement {
 public:
  enum class InsertType {
    kTuple = 0,
    kSelection
  };

  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param relation_name The name of the relation to insert into.
   **/
  ParseStatementInsert(const int line_number,
                       const int column_number,
                       const ParseString *relation_name)
      : ParseStatement(line_number, column_number),
        relation_name_(relation_name) {
  }

  /**
   * @brief Get the insert type of this insert statement.
   *
   * @return The insert type of this insert statement.
   */
  virtual InsertType getInsertType() const = 0;

  std::string getName() const override { return "InsertStatement"; }

  StatementType getStatementType() const override {
    return kInsert;
  }

  /**
   * @brief Get the name of the relation to insert into.
   *
   * @return The name of the relation to insert into.
   **/
  const ParseString* relation_name() const {
    return relation_name_.get();
  }

 private:
  std::unique_ptr<const ParseString> relation_name_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementInsert);
};


/**
 * @brief The parsed representation of an INSERT ... VALUES ... statement.
 **/
class ParseStatementInsertTuple : public ParseStatementInsert {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param relation_name The name of the relation to insert into.
   * @param literal_values A list of literal values (in attribute-definition
   *        order) to insert into the specified relation as a new tuple.
   *        Becomes owned by this ParseStatementInsert.
   **/
  ParseStatementInsertTuple(const int line_number,
                            const int column_number,
                            const ParseString *relation_name,
                            PtrList<ParseScalarLiteral> *literal_values)
      : ParseStatementInsert(line_number, column_number, relation_name),
        literal_values_(literal_values) {
  }

  ~ParseStatementInsertTuple() override {
  }

  InsertType getInsertType() const override {
    return InsertType::kTuple;
  }

  /**
   * @brief Get the parsed literal attribute values to insert.
   *
   * @return The list of literal values to insert.
   **/
  const PtrList<ParseScalarLiteral>& getLiteralValues() const {
    return *literal_values_;
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("relation_name");
    inline_field_values->push_back(relation_name()->value());

    container_child_field_names->push_back("tuple");
    container_child_fields->emplace_back();
    for (const ParseScalarLiteral& literal_value : *literal_values_) {
      container_child_fields->back().push_back(&literal_value);
    }
  }

 private:
  std::unique_ptr<PtrList<ParseScalarLiteral> > literal_values_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementInsertTuple);
};

/**
 * @brief The parsed representation of an INSERT ... SELECT ... statement.
 **/
class ParseStatementInsertSelection : public ParseStatementInsert {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param relation_name The name of the relation to insert into.
   * @param select_query The SELECT query for generating insertion tuples.
   * @param with_clause The WITH clause of common table query expressions.
   **/
  ParseStatementInsertSelection(const int line_number,
                                const int column_number,
                                const ParseString *relation_name,
                                ParseSelect *select_query,
                                PtrVector<ParseSubqueryTableReference> *with_clause)
      : ParseStatementInsert(line_number, column_number, relation_name),
        select_query_(select_query),
        with_clause_(with_clause) {
  }

  ~ParseStatementInsertSelection() override {
  }

  InsertType getInsertType() const override {
    return InsertType::kSelection;
  }

  /**
   * @return Gets the SELECT query.
   */
  const ParseSelect* select_query() const {
    return select_query_.get();
  }

  /**
   * @brief Gets the WITH table queries.
   *
   * @return The parsed WITH table list.
   */
  const PtrVector<ParseSubqueryTableReference>* with_clause() const {
    return with_clause_.get();
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("relation_name");
    inline_field_values->push_back(relation_name()->value());

    non_container_child_field_names->push_back("select_query");
    non_container_child_fields->push_back(select_query_.get());

    if (with_clause_ != nullptr && !with_clause_->empty()) {
      container_child_field_names->push_back("with_clause");
      container_child_fields->emplace_back();
      for (const ParseSubqueryTableReference &common_subquery : *with_clause_) {
        container_child_fields->back().push_back(&common_subquery);
      }
    }
  }

 private:
  std::unique_ptr<ParseSelect> select_query_;
  std::unique_ptr<PtrVector<ParseSubqueryTableReference>> with_clause_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementInsertSelection);
};

/**
 * @brief Optional parameters for a COPY FROM statement.
 **/
struct ParseCopyFromParams : public ParseTreeNode {
  /**
   * @brief Constructor, sets default values.
   **/
  ParseCopyFromParams(const int line_number, const int column_number)
      : ParseTreeNode(line_number, column_number),
        escape_strings(true) {
  }

  std::string getName() const override { return "CopyFromParams"; }

  /**
   * @brief Sets the column delimiter.
   *
   * @param delimiter_in The column delimiter string.
   */
  void set_delimiter(ParseString* delimiter_in) {
    delimiter.reset(delimiter_in);
  }

  /**
   * @brief The string which terminates individual attribute values in the
   *        input file. Can be NULL.
   **/
  std::unique_ptr<ParseString> delimiter;

  /**
   * @brief If true, replace C-style escape sequences in strings from the input
   *        text file.
   **/
  bool escape_strings;

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    if (delimiter != nullptr) {
      inline_field_names->push_back("delimiter");
      inline_field_values->push_back(delimiter->value());
    }

    inline_field_names->push_back("escape_string");
    inline_field_values->push_back(escape_strings ? "true" : "false");
  }
};

/**
 * @brief The parsed representation of a COPY FROM statement.
 **/
class ParseStatementCopyFrom : public ParseStatement {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param relation_name The name of the relation to insert into.
   * @param source_filename The name of the text file to bulk insert from.
   * @param params The optional parameters of the COPY FROM statement (should
   *        be supplied with defaults if not otherwise set).
   **/
  ParseStatementCopyFrom(const int line_number,
                         const int column_number,
                         ParseString *relation_name,
                         ParseString *source_filename,
                         ParseCopyFromParams *params)
      : ParseStatement(line_number, column_number),
        relation_name_(relation_name),
        source_filename_(source_filename),
        params_(params) {
  }

  /**
   * @brief Destructor.
   */
  ~ParseStatementCopyFrom() override {
  }

  StatementType getStatementType() const override {
    return kCopyFrom;
  }

  std::string getName() const override { return "CopyFromStatement"; }

  /**
   * @brief Get the name of the relation to insert into.
   *
   * @return The name of the relation to insert into.
   **/
  const ParseString* relation_name() const {
    return relation_name_.get();
  }

  /**
   * @brief Get the name of the text file to copy from.
   *
   * @return The name of the text file to copy from.
   **/
  const ParseString* source_filename() const {
    return source_filename_.get();
  }

  /**
   * @brief Get the additional COPY FROM parameters.
   *
   * @return The string which terminates individual attribute values in the
   *         input file.
   **/
  const ParseCopyFromParams* params() const {
    return params_.get();
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("relation_name");
    inline_field_values->push_back(relation_name_->value());

    inline_field_names->push_back("source_file");
    inline_field_values->push_back(source_filename_->value());

    if (params_ != nullptr) {
      non_container_child_field_names->push_back("params");
      non_container_child_fields->push_back(params_.get());
    }
  }

 private:
  std::unique_ptr<ParseString> relation_name_;
  std::unique_ptr<ParseString> source_filename_;
  std::unique_ptr<ParseCopyFromParams> params_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementCopyFrom);
};


/**
 * @brief The parsed representation of an UPDATE statement.
 **/
class ParseStatementUpdate : public ParseStatement {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param relation_name The name of the relation to update.
   * @param assignments A list of assignment for the attributes in the
   *        relation, which becomes owned by this ParseStatementUpdate.
   * @param where_predicate An optional predicate from a WHERE clause in the
   *        UPDATE statement (may be NULL if no predicate). Becomes owned by
   *        this ParseStatementUpdate if non-NULL.
   **/
  ParseStatementUpdate(const int line_number,
                       const int column_number,
                       ParseString *relation_name,
                       PtrList<ParseAssignment> *assignments,
                       ParsePredicate *where_predicate)
      : ParseStatement(line_number, column_number),
        relation_name_(relation_name),
        assignments_(assignments),
        where_predicate_(where_predicate) {
  }

  /**
   * @brief Destructor.
   */
  ~ParseStatementUpdate() override {
  }

  StatementType getStatementType() const override {
    return kUpdate;
  }

  std::string getName() const override { return "UpdateStatement"; }

  /**
   * @brief Get the name of the relation to update.
   *
   * @return The name of the relation to update.
   **/
  const ParseString* relation_name() const {
    return relation_name_.get();
  }

  /**
   * @brief Get the assignments to perform in the update.
   *
   * @return A list of assignments to perform in the update.
   **/
  const PtrList<ParseAssignment>& assignments() const {
    return *assignments_;
  }

  /**
   * @brief Determine whether this update statement has a WHERE predicate.
   *
   * @return Whether there is a WHERE predicate in this statement.
   **/
  bool hasWherePredicate() const {
    return where_predicate_.get() != nullptr;
  }

  /**
   * @brief Get the where predicate.
   * @warning Always call hasWherePredicate() first.
   *
   * @return The where predicate for this update.
   **/
  const ParsePredicate& where_predicate() const {
    DCHECK(hasWherePredicate());
    return *where_predicate_;
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("relation_name");
    inline_field_values->push_back(relation_name_->value());

    container_child_field_names->push_back("assignment");
    container_child_fields->emplace_back();
    for (const ParseAssignment& assignment_item : *assignments_) {
      container_child_fields->back().push_back(&assignment_item);
    }

    if (where_predicate_ != nullptr) {
      non_container_child_field_names->push_back("where_predicate");
      non_container_child_fields->push_back(where_predicate_.get());
    }
  }

 private:
  std::unique_ptr<ParseString> relation_name_;
  std::unique_ptr<PtrList<ParseAssignment> > assignments_;
  std::unique_ptr<ParsePredicate> where_predicate_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementUpdate);
};

/**
 * @brief The parsed representation of a DELETE statement.
 **/
class ParseStatementDelete : public ParseStatement {
 public:
  /**
   * @brief Constructor
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param relation_name The name of the relation to delete from.
   * @param where_predicate An optional predicate from a WHERE clause in the
   *        DELETE statement (may be NULL if no predicate). Becomes owned by
   *        this ParseStatementDelete if non-NULL.
   **/
  ParseStatementDelete(const int line_number,
                       const int column_number,
                       ParseString *relation_name,
                       ParsePredicate *where_predicate)
      : ParseStatement(line_number, column_number), relation_name_(relation_name), where_predicate_(where_predicate) {
  }

  /**
   * @brief Destructor.
   */
  ~ParseStatementDelete() override {
  }

  StatementType getStatementType() const override {
    return kDelete;
  }

  std::string getName() const override { return "DeleteStatement"; }

  /**
   * @brief Get the name of the relation to delete from.
   *
   * @return The name of the relation to delete from.
   **/
  const ParseString* relation_name() const {
    return relation_name_.get();
  }

  /**
   * @brief Get the where predicate.
   *
   * @return The where predicate for this delete statement.
   **/
  const ParsePredicate* where_predicate() const {
    return where_predicate_.get();
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("relation_name");
    inline_field_values->push_back(relation_name_->value());

    if (where_predicate_ != nullptr) {
      non_container_child_field_names->push_back("where_predicate");
      non_container_child_fields->push_back(where_predicate_.get());
    }
  }

 private:
  std::unique_ptr<ParseString> relation_name_;
  std::unique_ptr<ParsePredicate> where_predicate_;

  DISALLOW_COPY_AND_ASSIGN(ParseStatementDelete);
};

/**
 * @brief The parsed representation of a QUIT statement, which terminates a
 *        quickstep session.
 **/
class ParseStatementQuit : public ParseStatement {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   */
  ParseStatementQuit(const int line_number, const int column_number)
      : ParseStatement(line_number, column_number) {
  }

  StatementType getStatementType() const override {
    return kQuit;
  }

  std::string getName() const override { return "QuitStatement"; }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ParseStatementQuit);
};

/**
 * @brief Class to hold the parsed command name and an optional argument string.
 * @details Commands are non-sql statements which can be issued to quickstep.
 *          They are entered into the CLI as '.command-name command-string\n'.
 *          The command string is split up into words using whitespace as
 *          a delimiter.
 */
class ParseCommand : public ParseStatement {
 public:
  ParseCommand(const int line_number,
               const int column_number,
               ParseString *command,
               PtrVector<ParseString> *arguments)
      : ParseStatement(line_number, column_number),
        command_(command),
        arguments_(arguments) {  }

  /**
   * @return The name of this class.
   */
  std::string getName() const override {
    return "ParseCommand";
  }

  /**
   * @brief All ParseCommands are ParseStatements of the type command.
   */
  StatementType getStatementType() const override {
    return kCommand;
  }

  /**
   * @return The name of the command.
   */
  const ParseString* command() const {
    return command_.get();
  }

  /**
   * @return The optional argument strings to the command. Possibly empty.
   */
  const PtrVector<ParseString>* arguments() const {
    return arguments_.get();
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override {
    inline_field_names->push_back("command");
    inline_field_values->push_back(command_->value());

    for (const ParseString &argument : *arguments_) {
      non_container_child_field_names->push_back("argument");
      non_container_child_fields->push_back(&argument);
    }
  }

 private:
  std::unique_ptr<ParseString> command_;
  std::unique_ptr<PtrVector<ParseString>> arguments_;

  DISALLOW_COPY_AND_ASSIGN(ParseCommand);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_PARSER_PARSE_STATEMENT_HPP_
