/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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_QUERY_OPTIMIZER_RESOLVER_RESOLVER_HPP_
#define QUICKSTEP_QUERY_OPTIMIZER_RESOLVER_RESOLVER_HPP_

#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "query_optimizer/expressions/Alias.hpp"
#include "query_optimizer/expressions/ExprId.hpp"
#include "query_optimizer/expressions/NamedExpression.hpp"
#include "query_optimizer/expressions/Predicate.hpp"
#include "query_optimizer/expressions/SubqueryExpression.hpp"
#include "query_optimizer/expressions/Scalar.hpp"
#include "query_optimizer/expressions/WindowAggregateFunction.hpp"
#include "query_optimizer/logical/Logical.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrVector.hpp"

namespace quickstep {

class CatalogDatabase;
class CatalogRelation;
class Comparison;
class ParseExpression;
class ParseFunctionCall;
class ParseGeneratorTableReference;
class ParseJoinedTableReference;
class ParseOrderBy;
class ParsePredicate;
class ParseSearchedCaseExpression;
class ParseSelect;
class ParseSelectionClause;
class ParseSetOperation;
class ParseSimpleCaseExpression;
class ParseSimpleTableReference;
class ParseSubqueryTableReference;
class ParseStatement;
class ParseStatementCopy;
class ParseStatementCreateTable;
class ParseStatementCreateIndex;
class ParseStatementDelete;
class ParseStatementDropTable;
class ParseStatementInsertSelection;
class ParseStatementInsertTuple;
class ParseStatementSetOperation;
class ParseStatementUpdate;
class ParseString;
class ParseSubqueryExpression;
class ParseTableReference;
class ParseTableReferenceSignature;
class ParseTreeNode;
class ParseWindow;
template <class T>
class PtrList;
class StorageBlockLayoutDescription;
class Type;

namespace serialization { class PartitionSchemeHeader; }

namespace optimizer {

class OptimizerContext;

namespace resolver {

class NameResolver;

/** \addtogroup QueryResolver
 *  @{
 */

/**
 * @brief Performs semantic analysis and validation on a parse tree for a SELECT
 *        statement and outputs an initial logical plan.
 */
class Resolver {
 public:
  /**
   * @brief Constructor. Does not take ownership of \p context.
   *
   * @param catalog_database The database that the query is executed on.
   * @param context The context of this query.
   */
  Resolver(const CatalogDatabase &catalog_database, OptimizerContext *context)
      : catalog_database_(catalog_database),
        context_(context) {}

  /**
   * @brief Validates the query is semantically correct and converts the parse
   *        tree to an initial logical plan.
   *
   * @param parse_query
   * @return The converted logical node.
   */
  logical::LogicalPtr resolve(const ParseStatement &parse_query);

  /**
   * @brief Get the referenced base relations in the query.
   */
  std::vector<const CatalogRelation*> getReferencedBaseRelations();

 private:
  /**
   * @brief Expression-scoped info that contains both constant and non-constant
   *        info (e.g. the name resolver, whether an aggregate is allowed)
   *        during resolving an expression.
   */
  struct ExpressionResolutionInfo;

  /**
   * @brief Query-scoped info that contains the aggregate expressions in a query
   *        block.
   */
  struct QueryAggregationInfo;

  /**
   * @brief Query-scoped info that contains window aggregate expressions and a
   *        window map.
   **/
  struct WindowAggregationInfo;

  /**
   * @brief A wrapper for resolved window and the corresponding sorted plan.
   **/
  struct WindowPlan;

  /**
   * @brief Query-scoped info that contains select-list expressions
   *        and whether an expression is referenced by an
   *        ordinal or alias reference.
   */
  struct SelectListInfo;

  /**
   * @brief Contains resolution info for subqueries in the WITH clause.
   */
  struct WithQueriesInfo {
    /**
     * @brief The plans for WITH queries.
     */
    std::vector<logical::LogicalPtr> with_query_plans;

    /**
     * @brief The query name (the name of the table derived by the query) to
     *        the position of the plan in <with_query_plans>.
     */
    std::unordered_map<std::string, int> with_query_name_to_vector_position;

    /**
     * @brief Indexes of WITH queries that are not used.
     */
    std::unordered_set<int> unreferenced_query_indexes;
  };

  /**
   * @brief Resolves a SELECT (sub)query and returns a logical plan.
   *
   * @param select_statement The SELECT parse tree.
   * @param select_name The name for the SELECT query.
   * @param type_hints Type hints for the expressions in the SELECT clause. Can
   *                   be NULL if there is no expectation.
   * @param parent_resolver The name resolver of the outer query if exists.
   * @return A logical plan for the SELECT query.
   */
  logical::LogicalPtr resolveSelect(
      const ParseSelect &select_statement,
      const std::string &select_name,
      const std::vector<const Type*> *type_hints,
      const NameResolver *parent_resolver);

  /**
   * @brief Resolves multiple set operations at the same level.
   */
  logical::LogicalPtr resolveSetOperations(
      const ParseSetOperation &parse_set_operations,
      const std::string &set_operation_name,
      const std::vector<const Type*> *type_hints,
      const NameResolver *parent_resolver);

  /**
   * @brief Resolves a set operation and returns a logical plan.
   */
  logical::LogicalPtr resolveSetOperation(
      const ParseSetOperation &set_operation_query,
      const std::string &set_operation_name,
      const std::vector<const Type*> *type_hints,
      const NameResolver *parent_resolver);

  /**
   * @brief Resolves a CREATE TABLE query and returns a logical plan.
   *
   * @param create_table_statement The CREATE TABLE parse tree.
   * @return A logical plan for the CREATE TABLE query.
   */
  logical::LogicalPtr resolveCreateTable(
      const ParseStatementCreateTable &create_table_statement);

  /**
   * @brief Resolves a CREATE INDEX query and returns a logical plan.
   *
   * @param create_index_statement THE CREATE INDEX parse tree.
   * @return A logical plan for the CREATE INDEX query.
   */
  logical::LogicalPtr resolveCreateIndex(
      const ParseStatementCreateIndex &create_index_statement);

  /**
   * @brief Resolves the BLOCK PROPERTIES of a CREATE TABLE statement to a
   *        proto message describing the user input.
   *
   * @param create_table_statement The create table statement.
   * @return A pointer to a user-owned Proto message describing the block. Note
   *         that this message may be invalid.
   */
  StorageBlockLayoutDescription* resolveBlockProperties(
      const ParseStatementCreateTable &create_table_statement);

  /**
   * @brief Resolves the PARTITION clause of a CREATE TABLE statement to a
   *        the serialized PartitionSchemeHeader describing the user input.
   *
   * @param create_table_statement The create table statement.
   * @return A pointer to a user-owned serialized PartitionSchemeHeader.
   */
  const serialization::PartitionSchemeHeader* resolvePartitionClause(
      const ParseStatementCreateTable &create_table_statement);

  /**
   * @brief Resolves a DELETE query and returns a logical plan.
   *
   * @param delete_statement The DELETE parse tree.
   * @return A logical plan for the DELETE query.
   */
  logical::LogicalPtr resolveDelete(
      const ParseStatementDelete &delete_statement);

  /**
   * @brief Resolves a DROP TABLE query and returns a logical plan.
   *
   * @param drop_table_statement The DROP TABLE parse tree.
   * @return A logical plan for the DROP TABLE query.
   */
  logical::LogicalPtr resolveDropTable(
      const ParseStatementDropTable &drop_table_statement);

  /**
   * @brief Resolves an INSERT VALUES query and returns a logical plan.
   *
   * @param insert_statement The INSERT parse tree.
   * @return A logical plan for the INSERT query.
   */
  logical::LogicalPtr resolveInsertTuple(
      const ParseStatementInsertTuple &insert_statement);

  /**
   * @brief Resolves an INSERT SELECT query and returns a logical plan.
   *
   * @param insert_statement The INSERT parse tree.
   * @return A logical plan for the INSERT query.
   */
  logical::LogicalPtr resolveInsertSelection(
      const ParseStatementInsertSelection &insert_statement);

  /**
   * @brief Resolves a COPY FROM query and returns a logical plan.
   *
   * @param copy_from_statement The COPY FROM parse tree.
   * @return A logical plan for the COPY FROM query.
   */
  logical::LogicalPtr resolveCopyFrom(
      const ParseStatementCopy &copy_from_statement);

  /**
   * @brief Resolves a COPY TO query and returns a logical plan.
   *
   * @param copy_to_statement The COPY TO parse tree.
   * @return A logical plan for the COPY TO query.
   */
  logical::LogicalPtr resolveCopyTo(
      const ParseStatementCopy &copy_to_statement);

  /**
   * @brief Resolves a UPDATE query and returns a logical plan.
   *
   * @param update_statement The UPDATE parse tree.
   * @return A logical plan for the UPDATE query.
   */
  logical::LogicalPtr resolveUpdate(
      const ParseStatementUpdate &update_statement);

  /**
   * @brief Resolves WITH clause and stores the resolved information into
   * the member object with_query_info_ of this class.
   *
   * @param with_list The list of subqueries in WITH clause.
   */
  void resolveWithClause(
      const PtrVector<ParseSubqueryTableReference> &with_list);

  /**
   * @brief Resolves SELECT-list expressions and returns the resolved
   *        expressions in \p project_expressions.
   * @warning \p project_expressions will be cleared first.
   *
   * @param parse_selection The SELECT parse tree.
   * @param select_name The name of the SELECT query. It is used to populate the
   *                    relation name in the expressions.
   * @param type_hints Type hints for the expressions in the SELECT clause. Can
   *                   be NULL if there is no expectation.
   * @param name_resolver NameResolver to resolve the relation/attribute names.
   * @param query_aggregation_info Passed down to each expression to collects
   *                               aggregate expressions.
   * @param window_aggregate_expressions Passed down to each expressions to
   *                                     collects window aggregate expressions.
   * @param project_expressions Converted SELECT-list expressions.
   * @param has_aggregate_per_expression For each SELECT-list expression,
   *                                     indicates whether it contains
   *                                     an aggregate.
   */
  void resolveSelectClause(
      const ParseSelectionClause &parse_selection,
      const std::string &select_name,
      const std::vector<const Type*> *type_hints,
      const NameResolver &name_resolver,
      QueryAggregationInfo *query_aggregation_info,
      WindowAggregationInfo *window_aggregation_info,
      std::vector<expressions::NamedExpressionPtr> *project_expressions,
      std::vector<bool> *has_aggregate_per_expression);

  /**
   * @brief Resolves FROM clause and converts it to a logical plan. If the FROM
   *        clause has multiple items, the returned plan is a MultiwayCartisianJoin
   *        on all logical subplans for FROM-list items.
   *
   * @param from_list The FROM-list items.
   * @param name_resolver The resolver to resolve names.
   * @return A logical plan for the FROM clause.
   */
  logical::LogicalPtr resolveFromClause(
      const PtrList<ParseTableReference> &from_list,
      NameResolver *name_resolver);

  /**
   * @brief Resolves a table reference item, which can be a base table,
   *        a generator table, a subquery table, or a joined table defined by
   *        a join chain.
   *
   * @param table_reference The parse table reference to be resolved.
   * @param name_resolver The name resolver to be updated with new tables
   *                      visible from this table reference item.
   * @return The logical plan to derive the table.
   */
  logical::LogicalPtr resolveTableReference(const ParseTableReference &table_reference,
                                            NameResolver *name_resolver);

  /**
   * @brief Resolves a table reference by name, and converts it to a logical
   *        plan. The table is not added into the NameResolver.
   *
   * @param table_name The parse node for the table name string.
   * @param reference_alias The alias of the table reference.
   * @return A logical plan for the table reference.
   */
  logical::LogicalPtr resolveSimpleTableReference(
      const ParseString &table_name, const ParseString *reference_alias);

  /**
   * @brief Resolves a generator table reference and links the corresponding
   *        generator function. The table is not added into the NameResolver.
   *
   * @param table_reference The parse table reference to be resolved.
   * @return The logical plan for the generator table reference.
   */
  logical::LogicalPtr resolveGeneratorTableReference(
      const ParseGeneratorTableReference &table_reference,
      const ParseString *reference_alias);

  /**
   * @brief Resolves a joined table resulting from a join between two table
   *        references.
   *
   * @param joined_table_reference The parse joined table reference to be resolved.
   * @param name_resolver The name resolver to be updated with the left and the
   *        right tables.
   * @return A logical plan for the joined table reference.
   */
  logical::LogicalPtr resolveJoinedTableReference(
      const ParseJoinedTableReference &joined_table_reference,
      NameResolver *name_resolver);

  /**
   * @brief Renames the output columns from \p logical_plan based on the table signature
   *        by wrapping it with a Project.
   *
   * @param logical The logical node whose output columns are
   * @param table_signature A table reference signature that specifies column names.
   * @return A logical plan with a wrapper Project.
   */
  logical::LogicalPtr RenameOutputColumns(
      const logical::LogicalPtr &logical_plan,
      const ParseTableReferenceSignature &table_signature);

  /**
   * @brief Sort the input table in (p_key, o_key) order specified by the window.
   *
   * @param logical_plan The input logical node.
   * @param window_info The window that the input table has to be sorted accordingly.
   * @return A logical plan that sorts the table according to window_info.
   **/
  logical::LogicalPtr resolveSortInWindow(
      const logical::LogicalPtr &logical_plan,
      const expressions::WindowInfo &window_info);

  /**
   * @brief Resolves a parse expression and converts it to a scalar expression
   *        in the query optimizer. A non-scalar parse expression is resolved
   *        to an AttributeReference to another optimizer expression.
   *
   * @param parse_expression The parse expression to be resolved.
   * @param type_hint A hint about what Type the expression is expected to be
   *        (e.g. an attribute's type in an INSERT or UPDATE query). May be
   *        NULL if there is no expectation, or the expectation is ambiguous.
   *        This is passed through to ParseLiteralValue::concretize().
   * @param expression_resolution_info Resolution info that contains the name
   *                                   resolver and info to be updated after
   *                                   resolution.
   * @return An expression in the query optimizer.
   */
  expressions::ScalarPtr resolveExpression(
      const ParseExpression &parse_expression,
      const Type *type_hint,
      ExpressionResolutionInfo *expression_resolution_info);

  /**
   * @brief Resolves a searched CASE expression.
   *
   * @param type_hint The expected result type of this expression.
   * @param parse_searched_case_expression The parsed searched CASE expression
   *        to be resolved.
   * @param expresssion_resolution_info Resolution info that contains the name
   *        resolver and info to be updated after resolution.
   * @return An optimizer expression for the CASE expression.
   */
  expressions::ScalarPtr resolveSearchedCaseExpression(
      const ParseSearchedCaseExpression &parse_searched_case_expression,
      const Type *type_hint,
      ExpressionResolutionInfo *expression_resolution_info);

  /**
   * @brief Resolves a simple CASE expression.
   *
   * @param type_hint The expected result type of this expression.
   * @param parse_simple_case_expression The parsed simple CASE expression
   *        to be resolved.
   * @param expresssion_resolution_info Resolution info that contains the name
   *        resolver and info to be updated after resolution.
   * @return An optimizer expression for the CASE expression.
   */
  expressions::ScalarPtr resolveSimpleCaseExpression(
      const ParseSimpleCaseExpression &parse_simple_case_expression,
      const Type *type_hint,
      ExpressionResolutionInfo *expression_resolution_info);

  /**
   * @brief Resolves a function call. For a non-scalar function, the returned
   *        expression is an AttributeReference to the actual resolved expression.
   *
   * @note This currently only handles resolving aggregate functions and window
   *       aggregate functions.
   *
   * @param parse_function_call The function call to be resolved.
   * @param expression_resolution_info Resolution info that contains the name
   *                                   resolver and info to be updated after
   *                                   resolution.
   * @return An expression in the query optimizer.
   */
  expressions::ScalarPtr resolveFunctionCall(
      const ParseFunctionCall &parse_function_call,
      ExpressionResolutionInfo *expression_resolution_info);

  /**
   * @brief Resolves a window aggregate function.
   *
   * @param parse_function_call The function call to be resolved.
   * @param expression_resolution_info Resolution info that contains the name
   *                                   resolver and info to be updated after
   *                                   resolution.
   * @param aggregate The window aggregate function.
   * @param resolved_arguments The resolved arguments.
   * @return An expression in the query optimizer.
   */
  expressions::ScalarPtr resolveWindowAggregateFunction(
      const ParseFunctionCall &parse_function_call,
      ExpressionResolutionInfo *expression_resolution_info,
      const ::quickstep::WindowAggregateFunction *aggregate,
      const std::vector<expressions::ScalarPtr> &resolved_arguments);

  /**
   * @brief Resolves a parse Predicate and converts it to a predicate in the
   *        query optimizer.
   *
   * @param parse_predicate The parse predicate to be resolved.
   * @param expression_resolution_info Resolution info that contains the name
   *                                   resolver and info to be updated after
   *                                   resolution.
   * @return A predicate in the query optimizer
   */
  expressions::PredicatePtr resolvePredicate(
      const ParsePredicate &parse_predicate,
      ExpressionResolutionInfo *expression_resolution_info);

  /**
   * @brief Convenient method to resolve a list of predicates that uses
   *        resolvePredicate as a subroutine.
   *
   * @param parse_predicates Parse predicates to be resolved.
   * @param expression_resolution_info Resolution info that contains the name
   *                                   resolver and info to be updated after
   *                                   resolution.
   * @return Resolved predicates in the query optimizer
   */
  std::vector<expressions::PredicatePtr> resolvePredicates(
      const PtrList<ParsePredicate> &parse_predicates,
      ExpressionResolutionInfo *expression_resolution_info);

  /**
   * @brief Resolves a table/scalar subquery expression.
   *
   * @param parse_subquery_expression The parsed subquery expression.
   * @param type_hints The type hints for output columns by the subquery.
   * @param expression_resolution_info Resolution info that contains the name
   *        resolver and info to be updated after resolution.
   * @param has_single_column True if the subquery is expected to return only
   *        one column in the result.
   */
  expressions::SubqueryExpressionPtr resolveSubqueryExpression(
      const ParseSubqueryExpression &parse_subquery_expression,
      const std::vector<const Type*> *type_hints,
      ExpressionResolutionInfo *expression_resolution_info,
      const bool has_single_column);

  /**
   * @brief Resolves a window definition.
   *
   * @param parse_window The parsed window definition.
   * @param name_resolver The resolver to resolve names.
   **/
  expressions::WindowInfo resolveWindow(const ParseWindow &parse_window,
                                        const NameResolver &name_resolver);

  /**
   * @brief Resolves a relation name to a pointer to the corresponding
   *        CatalogRelation with the name.
   *
   * @param relation_name The parser node of the relation name.
   * @return The CatalogRelation.
   */
  const CatalogRelation *resolveRelationName(const ParseString *relation_name);

  /**
   * @brief Determines whether \p op can apply to \p left_operand and \p
   *        right_operand.
   *
   * @param location The location for the error message.
   * @param op The comparison operator.
   * @param left_operand The left operand.
   * @param right_operand The right operand.
   */
  void checkComparisonCanApplyTo(const ParseTreeNode *location,
                                 const Comparison &op,
                                 const expressions::ScalarPtr &left_operand,
                                 const expressions::ScalarPtr &right_operand) const;

  /**
   * @brief Collapse tree of homogenous set operations into a flat vector.
   */
  static void CollapseSetOperation(const ParseSetOperation &toplevel,
                                   const ParseSetOperation &current,
                                   std::vector<const ParseSetOperation*> *output);

  /**
   * @brief Generates an internal alias for an aggregate attribute.
   *
   * @param index The index of the aggregate attribute used for generating the
   *              name.
   * @return A string for the name.
   */
  static std::string GenerateAggregateAttributeAlias(int index);

  /**
   * @brief Generates an internal alias for a window aggregate attribute.
   *
   * @param index The index of the window aggregate attribute used for
   *              generating the name.
   * @return A string for the name.
   */
  static std::string GenerateWindowAggregateAttributeAlias(int index);

  /**
   * @brief Generates an internal alias for a grouping attribute.
   *
   * @param index The index of the grouping attribute used for generating the
   *              name.
   * @return A string for the name.
   */
  static std::string GenerateGroupingAttributeAlias(int index);

  /**
   * @brief Generates an internal alias for an ordering attribute.
   *
   * @param index The index of an ordering attribute used for generating
   *              the name.
   * @return A string for the name.
   */
  static std::string GenerateOrderingAttributeAlias(int index);

  /**
   * @brief Reports an error if there is a WITH query that is not actually used.
   *
   * @param with_list The list of subqueries in WITH clause.
   */
  void reportIfWithClauseUnused(
      const PtrVector<ParseSubqueryTableReference> &with_list) const;

  /**
   * @brief Validates each SELECT-list expression to ensure that it does not
   *        reference a named expression with an ID not in \p valid_expr_id_set.
   *
   * @param parse_select The parse tree for SELECT.
   * @param select_list_expressions The resolved SELECT-list expressions.
   * @param visible_expr_id_set A set of IDs of expressions visible to the
   *                            SELECT list.
   */
  void validateSelectExpressionsForAggregation(
      const ParseSelectionClause &parse_selection,
      const std::vector<expressions::NamedExpressionPtr> &
          select_list_expressions,
      const std::unordered_set<expressions::ExprId> &visible_expr_id_set) const;

  /**
   * @brief Validates each ordering expression to ensure that it does not
   *        reference a named expression with an ID not in \p valid_expr_id_set.
   *
   * @param parse_order_by The parse tree for ORDER BY.
   * @param order_by_expressions The resolved order by expressions.
   * @param visible_expr_id_set A set of IDs of expressions visible to ORDER BY.
   */
  void validateOrderingExpressionsForAggregation(
      const ParseOrderBy &parse_order_by,
      const std::vector<expressions::ScalarPtr> &order_by_expressions,
      const std::unordered_set<expressions::ExprId> &visible_expr_id_set) const;

  /**
   * @brief Validates \p expression does not reference a name expression with an
   *        ID not in \p valid_expr_id_set.
   *
   * @param location The location where to report an error at.
   * @param expression The expression to be checked.
   * @param visible_expr_id_set A set of IDs of expressions visible to the
   *                            expression.
   */
  void validateExpressionForAggregation(
      const ParseTreeNode *location,
      const expressions::ExpressionPtr &expression,
      const std::unordered_set<expressions::ExprId> &visible_expr_id_set) const;

  /**
   * @brief Rewrites \p expression if it is an integer literal that can be used
   *        as an ordinal reference to a SELECT-list expression.
   *
   * @param location The location where to report an error at.
   * @param expr_resolution_info Used to know aggregate functions are allowed.
   * @param select_list_info The SELECT-list expressions info.
   * @param expression The expression to be checked and rewritten.
   */
  void rewriteIfOrdinalReference(
      const ParseTreeNode *location,
      const ExpressionResolutionInfo &expr_resolution_info,
      SelectListInfo *select_list_info, expressions::ScalarPtr *expression);

  /**
   * @brief Wraps \p project_plan with a Project if \p select_list_info
   *        indicates that there are SELECT-list expressions
   *        that do not contain aggregates and need to be precomputed (those
   *        that are referenced by aliases), updates those precomputed
   *        expressions in \p select_list_expressions with the references.
   *
   * @param select_list_info Select list info to determine precomputed
   *                         expressions.
   * @param select_list_expressions Select list expressions.
   * @param logical_plan The logical plan to be updated.
   */
  void appendProjectIfNeedPrecomputationBeforeAggregation(
      const SelectListInfo &select_list_info,
      std::vector<expressions::NamedExpressionPtr> *select_list_expressions,
      logical::LogicalPtr *logical_plan);

  /**
   * @brief Wraps \p project_plan with a Project if \p select_list_info
   *        indicates that there are SELECT-list expressions
   *        that contain aggregates and need to be precomputed (those that are
   *        referenced by aliases), updates those precomputed expressions in
   *        \p select_list_expressions with the references.
   *
   * @param select_list_info Select list info to determine precomputed
   *                         expressions.
   * @param select_list_expressions Select list expressions.
   * @param logical_plan The logical plan to be updated.
   */
  void appendProjectIfNeedPrecomputationAfterAggregation(
      const SelectListInfo &select_list_info,
      std::vector<expressions::NamedExpressionPtr> *select_list_expressions,
      logical::LogicalPtr *logical_plan);

  const CatalogDatabase &catalog_database_;

  OptimizerContext *context_;
  WithQueriesInfo with_queries_info_;

  logical::LogicalPtr logical_plan_;

  DISALLOW_COPY_AND_ASSIGN(Resolver);
};

/** @} */

}  // namespace resolver
}  // namespace optimizer
}  // namespace quickstep

#endif /* QUICKSTEP_QUERY_OPTIMIZER_RESOLVER_RESOLVER_HPP_ */
