1#include "duckdb/main/pending_query_result.hpp"
2#include "duckdb/main/client_context.hpp"
3#include "duckdb/main/prepared_statement_data.hpp"
4
5namespace duckdb {
6
7PendingQueryResult::PendingQueryResult(shared_ptr<ClientContext> context_p, PreparedStatementData &statement,
8 vector<LogicalType> types_p, bool allow_stream_result)
9 : BaseQueryResult(QueryResultType::PENDING_RESULT, statement.statement_type, statement.properties,
10 std::move(types_p), statement.names),
11 context(std::move(context_p)), allow_stream_result(allow_stream_result) {
12}
13
14PendingQueryResult::PendingQueryResult(PreservedError error)
15 : BaseQueryResult(QueryResultType::PENDING_RESULT, std::move(error)) {
16}
17
18PendingQueryResult::~PendingQueryResult() {
19}
20
21unique_ptr<ClientContextLock> PendingQueryResult::LockContext() {
22 if (!context) {
23 if (HasError()) {
24 throw InvalidInputException(
25 "Attempting to execute an unsuccessful or closed pending query result\nError: %s", GetError());
26 }
27 throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result");
28 }
29 return context->LockContext();
30}
31
32void PendingQueryResult::CheckExecutableInternal(ClientContextLock &lock) {
33 bool invalidated = HasError() || !context;
34 if (!invalidated) {
35 invalidated = !context->IsActiveResult(lock, result: this);
36 }
37 if (invalidated) {
38 if (HasError()) {
39 throw InvalidInputException(
40 "Attempting to execute an unsuccessful or closed pending query result\nError: %s", GetError());
41 }
42 throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result");
43 }
44}
45
46PendingExecutionResult PendingQueryResult::ExecuteTask() {
47 auto lock = LockContext();
48 return ExecuteTaskInternal(lock&: *lock);
49}
50
51PendingExecutionResult PendingQueryResult::ExecuteTaskInternal(ClientContextLock &lock) {
52 CheckExecutableInternal(lock);
53 return context->ExecuteTaskInternal(lock, result&: *this);
54}
55
56unique_ptr<QueryResult> PendingQueryResult::ExecuteInternal(ClientContextLock &lock) {
57 CheckExecutableInternal(lock);
58 while (ExecuteTaskInternal(lock) == PendingExecutionResult::RESULT_NOT_READY) {
59 }
60 if (HasError()) {
61 return make_uniq<MaterializedQueryResult>(args&: error);
62 }
63 auto result = context->FetchResultInternal(lock, pending&: *this);
64 Close();
65 return result;
66}
67
68unique_ptr<QueryResult> PendingQueryResult::Execute() {
69 auto lock = LockContext();
70 return ExecuteInternal(lock&: *lock);
71}
72
73void PendingQueryResult::Close() {
74 context.reset();
75}
76
77} // namespace duckdb
78