// 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 IMPALA_SERVICE_CHILD_QUERY_H
#define IMPALA_SERVICE_CHILD_QUERY_H

#include <string>
#include <boost/thread/mutex.hpp>

#include "common/status.h"
#include "impala-server.h"
#include "gen-cpp/TCLIService_types.h"

namespace impala {

class ImpalaServer;

/// Child queries are used for implementing statements that consist of one or several
/// query statements (e.g., compute stats) that require independent query handles for
/// fetching results. Such queries are 'children' of a parent exec state in the sense
/// that they are executed in the same session and that child queries are cancelled if
/// the parent is cancelled (but not necessarily vice versa).
/// For simplicity and consistency, child queries are always executed via HiveServer2,
/// regardless of whether the parent session is Beeswax or HiveServer2.
//
/// Parent queries are expected to call ExecAndWait() of a child query in a
/// separate thread, and then join that thread to wait for child-query completion.
/// The parent ClientRequestState is independent of the child query's ClientRequestState,
/// with the exception that the child query selectively checks the parent's status
/// for failure/cancellation detection. Child queries should never call into their
/// parent's ClientRequestState to avoid deadlock.
//
/// TODO: Compute stats is the only stmt that requires child queries. Once the
/// CatalogService performs background stats gathering the concept of child queries
/// will likely become obsolete. Remove this class and all child-query related code.
class ChildQuery {
 public:
  ChildQuery(const std::string& query, ClientRequestState* parent_request_state,
      ImpalaServer* parent_server, RuntimeProfile* profile, ObjectPool* profile_pool)
    : query_(query),
      parent_request_state_(parent_request_state),
      parent_server_(parent_server),
      profile_(profile),
      profile_pool_(profile_pool),
      is_running_(false),
      is_cancelled_(false) {
    DCHECK(!query_.empty());
    DCHECK(parent_request_state_ != NULL);
    DCHECK(parent_server_ != NULL);
  }

  /// Allow child queries to be added to std collections.
  /// (boost::mutex's operator= and copy c'tor are private)
  ChildQuery(const ChildQuery& other)
    : query_(other.query_),
      parent_request_state_(other.parent_request_state_),
      parent_server_(other.parent_server_),
      profile_(other.profile_),
      profile_pool_(other.profile_pool_),
      is_running_(other.is_running_),
      is_cancelled_(other.is_cancelled_) {}

  /// Allow child queries to be added to std collections.
  /// (boost::mutex's operator= and copy c'tor are private)
  ChildQuery& operator=(const ChildQuery& other) {
    query_ = other.query_;
    parent_request_state_ = other.parent_request_state_;
    parent_server_ = other.parent_server_;
    is_running_ = other.is_running_;
    is_cancelled_ = other.is_cancelled_;
    return *this;
  }

  /// Executes this child query through HiveServer2 and fetches all its results.
  Status ExecAndFetch();

  /// Cancels and closes the given child query if it is running. Sets is_cancelled_.
  /// Child queries can be cancelled by the parent query through ClientRequestState::Cancel().
  /// Child queries should never cancel their parent to avoid deadlock (but the parent
  /// query may decide to cancel itself based on a non-OK status from a child query).
  /// Note that child queries have a different ClientRequestState than their parent query,
  /// so cancellation of a child query does not call into the parent's ClientRequestState.
  void Cancel();

  const apache::hive::service::cli::thrift::TTableSchema& result_schema() {
    return meta_resp_.schema;
  }

  const apache::hive::service::cli::thrift::TRowSet& result_data() {
    return fetch_resp_.results;
  }

  /// The key in the HS2 conf overlay which indicates to the executing ImpalaServer that
  /// this query is a child query.
  static const string PARENT_QUERY_OPT;

 private:
  /// Sets the query options from the parent query in child's HS2 request.
  /// TODO: Consider moving this function into a more appropriate place.
  void SetQueryOptions(const TQueryOptions& parent_options,
      apache::hive::service::cli::thrift::TExecuteStatementReq* exec_stmt_req);

  /// Returns Status::Cancelled if this child query has been cancelled, otherwise OK.
  /// Acquires lock_.
  Status IsCancelled();

  /// SQL string to be executed.
  std::string query_;

  /// Execution state of parent query. Used to synchronize and propagate parent
  /// cancellations/failures to this child query. Not owned.
  ClientRequestState* parent_request_state_;

  /// Parent Impala server used for executing this child query. Not owned.
  ImpalaServer* parent_server_;

  /// The profile for the query is retrieved after Close() and added as a child.
  RuntimeProfile* profile_;
  ObjectPool* profile_pool_;

  /// Result metadata and result rows of query.
  apache::hive::service::cli::thrift::TGetResultSetMetadataResp meta_resp_;
  apache::hive::service::cli::thrift::TFetchResultsResp fetch_resp_;

  /// HS2 query handle. Set in ExecChildQuery().
  apache::hive::service::cli::thrift::TOperationHandle hs2_handle_;

  /// Protects is_running_ and is_cancelled_ to ensure idempotent cancellations.
  boost::mutex lock_;

  /// Indicates whether this query is running. False if the query has not started yet
  /// or if the query has finished either successfully or because of an error.
  bool is_running_;

  /// Indicates whether this child query has been cancelled. Set in Cancel().
  bool is_cancelled_;
};

/// Asynchronously executes a set of child queries in a separate thread.
///
/// ExecAsync() is called at most once per executor to execute a set of child queries
/// asynchronously. After ExecAsync() is called, either WaitForAll() or Cancel() must be
/// called to ensure that the child queries are no longer executing before destroying the
/// object.
class ChildQueryExecutor {
 public:
  ChildQueryExecutor();
  ~ChildQueryExecutor();

  /// Asynchronously executes 'child_queries' one by one in a new thread. 'child_queries'
  /// must be non-empty. May clear or modify the 'child_queries' arg. Can only be called
  /// once. Does nothing if Cancel() was already called.
  Status ExecAsync(std::vector<ChildQuery>&& child_queries) WARN_UNUSED_RESULT;

  /// Waits for all child queries to complete successfully or with an error. Returns a
  /// non-OK status if a child query fails. Returns OK if ExecAsync() was not called,
  /// Cancel() was called before an error occurred, or if all child queries finished
  /// successfully. If returning OK, populates 'completed_queries' with the completed
  /// queries. Any returned ChildQueries remain owned by the executor. Should not be
  /// called concurrently with ExecAsync(). After WaitForAll() returns, the object can
  /// safely be destroyed.
  Status WaitForAll(std::vector<ChildQuery*>* completed_queries);

  /// Cancels all child queries and prevents any more from starting. Returns once all
  /// child queries are cancelled, after which the object can safely be destroyed. Can
  /// be safely called concurrently with ExecAsync() or WaitForAll().
  void Cancel();

 private:
  /// Serially executes the queries in child_queries_ by calling the child query's
  /// ExecAndWait(). This function blocks until all queries complete and is run
  /// in 'child_queries_thread_'.
  /// Sets 'child_queries_status_'.
  void ExecChildQueries();

  /// Protects all fields below.
  /// Should not be held at the same time as 'ChildQuery::lock_'.
  SpinLock lock_;

  /// True if cancellation of child queries has been initiated and no more child queries
  /// should be started.
  bool is_cancelled_;

  /// True if 'child_queries_thread_' is in the process of executing child queries.
  /// Set to false by 'child_queries_thread_' just before it exits. 'is_running_' must
  /// be false when ChildQueryExecutor is destroyed: once execution is started,
  /// WaitForAll() or Cancel() must be called to ensure the thread exits.
  bool is_running_;

  /// List of child queries to be executed. Not modified after it is initially populated,
  /// so safe to read without holding 'lock_' if 'is_running_' or 'is_cancelled_' is
  /// true, or 'child_queries_thread_' is non-NULL.
  std::vector<ChildQuery> child_queries_;

  /// Thread to execute 'child_queries_' in. Immutable after the first time it is set or
  /// after 'is_cancelled_' is true.
  std::unique_ptr<Thread> child_queries_thread_;

  /// The status of the child queries. The status is OK iff all child queries complete
  /// successfully. Otherwise, status contains the error of the first child query that
  /// failed (child queries are executed serially and abort on the first error).
  /// Immutable after 'child_queries_thread_' exits
  Status child_queries_status_;
};
}

#endif
