text: //===----------------------------------------------------------------------===//
  //                         DuckDB
  //
  // duckdb/main/prepared_statement.hpp
  //
  //
  //===----------------------------------------------------------------------===//
  
  #pragma once
  
  #include "duckdb/common/winapi.hpp"
  #include "duckdb/main/materialized_query_result.hpp"
  
  namespace duckdb {
  class ClientContext;
  class PreparedStatementData;
  
  //! A prepared statement
  class PreparedStatement {
  public:
  	//! Create a successfully prepared prepared statement object with the given name
  	DUCKDB_API PreparedStatement(shared_ptr<ClientContext> context, shared_ptr<PreparedStatementData> data,
  	                             string query, idx_t n_param);
  	//! Create a prepared statement that was not successfully prepared
  	DUCKDB_API explicit PreparedStatement(string error);
  
  	DUCKDB_API ~PreparedStatement();
  
  public:
  	//! The client context this prepared statement belongs to
  	shared_ptr<ClientContext> context;
  	//! The prepared statement data
  	shared_ptr<PreparedStatementData> data;
  	//! The query that is being prepared
  	string query;
  	//! Whether or not the statement was successfully prepared
  	bool success;
  	//! The error message (if success = false)
  	string error;
  	//! The amount of bound parameters
  	idx_t n_param;
  
  public:
  	//! Returns the number of columns in the result
  	idx_t ColumnCount();
  	//! Returns the statement type of the underlying prepared statement object
  	StatementType GetStatementType();
  	//! Returns the result SQL types of the prepared statement
  	const vector<LogicalType> &GetTypes();
  	//! Returns the result names of the prepared statement
  	const vector<string> &GetNames();
  
  	//! Execute the prepared statement with the given set of arguments
  	template <typename... Args>
  	unique_ptr<QueryResult> Execute(Args... args) {
  		vector<Value> values;
  		return ExecuteRecursive(values, args...);
  	}
  
  	//! Execute the prepared statement with the given set of values
  	DUCKDB_API unique_ptr<QueryResult> Execute(vector<Value> &values, bool allow_stream_result = true);
  
  private:
  	unique_ptr<QueryResult> ExecuteRecursive(vector<Value> &values) {
  		return Execute(values);
  	}
  
  	template <typename T, typename... Args>
  	unique_ptr<QueryResult> ExecuteRecursive(vector<Value> &values, T value, Args... args) {
  		values.push_back(Value::CreateValue<T>(value));
  		return ExecuteRecursive(values, args...);
  	}
  };
  
  } // namespace duckdb