1#include "duckdb/main/query_result.hpp"
2#include "duckdb/common/printer.hpp"
3#include "duckdb/common/vector.hpp"
4#include "duckdb/main/client_context.hpp"
5#include "duckdb/common/box_renderer.hpp"
6namespace duckdb {
7
8BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties_p,
9 vector<LogicalType> types_p, vector<string> names_p)
10 : type(type), statement_type(statement_type), properties(std::move(properties_p)), types(std::move(types_p)),
11 names(std::move(names_p)), success(true) {
12 D_ASSERT(types.size() == names.size());
13}
14
15BaseQueryResult::BaseQueryResult(QueryResultType type, PreservedError error)
16 : type(type), success(false), error(std::move(error)) {
17}
18
19BaseQueryResult::~BaseQueryResult() {
20}
21
22void BaseQueryResult::ThrowError(const string &prepended_message) const {
23 D_ASSERT(HasError());
24 error.Throw(prepended_message);
25}
26
27void BaseQueryResult::SetError(PreservedError error) {
28 success = !error;
29 this->error = std::move(error);
30}
31
32bool BaseQueryResult::HasError() const {
33 D_ASSERT((bool)error == !success);
34 return !success;
35}
36
37const ExceptionType &BaseQueryResult::GetErrorType() const {
38 return error.Type();
39}
40
41const std::string &BaseQueryResult::GetError() {
42 D_ASSERT(HasError());
43 return error.Message();
44}
45
46PreservedError &BaseQueryResult::GetErrorObject() {
47 return error;
48}
49
50idx_t BaseQueryResult::ColumnCount() {
51 return types.size();
52}
53
54QueryResult::QueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties,
55 vector<LogicalType> types_p, vector<string> names_p, ClientProperties client_properties_p)
56 : BaseQueryResult(type, statement_type, std::move(properties), std::move(types_p), std::move(names_p)),
57 client_properties(std::move(client_properties_p)) {
58}
59
60bool CurrentChunk::Valid() {
61 if (data_chunk) {
62 if (position < data_chunk->size()) {
63 return true;
64 }
65 }
66 return false;
67}
68
69idx_t CurrentChunk::RemainingSize() {
70 return data_chunk->size() - position;
71}
72
73QueryResult::QueryResult(QueryResultType type, PreservedError error)
74 : BaseQueryResult(type, std::move(error)), client_properties("UTC", ArrowOffsetSize::REGULAR) {
75}
76
77QueryResult::~QueryResult() {
78}
79
80const string &QueryResult::ColumnName(idx_t index) const {
81 D_ASSERT(index < names.size());
82 return names[index];
83}
84
85string QueryResult::ToBox(ClientContext &context, const BoxRendererConfig &config) {
86 return ToString();
87}
88
89unique_ptr<DataChunk> QueryResult::Fetch() {
90 auto chunk = FetchRaw();
91 if (!chunk) {
92 return nullptr;
93 }
94 chunk->Flatten();
95 return chunk;
96}
97
98bool QueryResult::Equals(QueryResult &other) { // LCOV_EXCL_START
99 // first compare the success state of the results
100 if (success != other.success) {
101 return false;
102 }
103 if (!success) {
104 return error == other.error;
105 }
106 // compare names
107 if (names != other.names) {
108 return false;
109 }
110 // compare types
111 if (types != other.types) {
112 return false;
113 }
114 // now compare the actual values
115 // fetch chunks
116 while (true) {
117 auto lchunk = Fetch();
118 auto rchunk = other.Fetch();
119 if (!lchunk && !rchunk) {
120 return true;
121 }
122 if (!lchunk || !rchunk) {
123 return false;
124 }
125 if (lchunk->size() == 0 && rchunk->size() == 0) {
126 return true;
127 }
128 if (lchunk->size() != rchunk->size()) {
129 return false;
130 }
131 D_ASSERT(lchunk->ColumnCount() == rchunk->ColumnCount());
132 for (idx_t col = 0; col < rchunk->ColumnCount(); col++) {
133 for (idx_t row = 0; row < rchunk->size(); row++) {
134 auto lvalue = lchunk->GetValue(col_idx: col, index: row);
135 auto rvalue = rchunk->GetValue(col_idx: col, index: row);
136 if (lvalue.IsNull() && rvalue.IsNull()) {
137 continue;
138 }
139 if (lvalue.IsNull() != rvalue.IsNull()) {
140 return false;
141 }
142 if (lvalue != rvalue) {
143 return false;
144 }
145 }
146 }
147 }
148} // LCOV_EXCL_STOP
149
150void QueryResult::Print() {
151 Printer::Print(str: ToString());
152}
153
154string QueryResult::HeaderToString() {
155 string result;
156 for (auto &name : names) {
157 result += name + "\t";
158 }
159 result += "\n";
160 for (auto &type : types) {
161 result += type.ToString() + "\t";
162 }
163 result += "\n";
164 return result;
165}
166
167ArrowOptions QueryResult::GetArrowOptions(QueryResult &query_result) {
168 return {query_result.client_properties.arrow_offset_size, query_result.client_properties.time_zone};
169}
170
171string QueryResult::GetConfigTimezone(QueryResult &query_result) {
172 return query_result.client_properties.time_zone;
173}
174
175} // namespace duckdb
176