]>
Commit | Line | Data |
---|---|---|
1d09f67e TL |
1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file | |
3 | // distributed with this work for additional information | |
4 | // regarding copyright ownership. The ASF licenses this file | |
5 | // to you under the Apache License, Version 2.0 (the | |
6 | // "License"); you may not use this file except in compliance | |
7 | // with the License. You may obtain a copy of the License at | |
8 | // | |
9 | // http://www.apache.org/licenses/LICENSE-2.0 | |
10 | // | |
11 | // Unless required by applicable law or agreed to in writing, | |
12 | // software distributed under the License is distributed on an | |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | // KIND, either express or implied. See the License for the | |
15 | // specific language governing permissions and limitations | |
16 | // under the License. | |
17 | ||
18 | #include "arrow/dbi/hiveserver2/thrift_internal.h" | |
19 | ||
20 | #include <map> | |
21 | #include <sstream> | |
22 | ||
23 | #include "arrow/dbi/hiveserver2/TCLIService_constants.h" | |
24 | #include "arrow/dbi/hiveserver2/service.h" | |
25 | ||
26 | #include "arrow/status.h" | |
27 | #include "arrow/util/logging.h" | |
28 | ||
29 | namespace hs2 = apache::hive::service::cli::thrift; | |
30 | ||
31 | namespace arrow { | |
32 | namespace hiveserver2 { | |
33 | ||
34 | namespace { | |
35 | ||
36 | // Convert an "enum class" value to an integer equivalent, for outputting. | |
37 | template <typename ENUM> | |
38 | typename std::underlying_type<ENUM>::type EnumToInt(const ENUM& value) { | |
39 | return static_cast<typename std::underlying_type<ENUM>::type>(value); | |
40 | } | |
41 | ||
42 | } // namespace | |
43 | ||
44 | const std::string OperationStateToString(const Operation::State& state) { | |
45 | switch (state) { | |
46 | case Operation::State::INITIALIZED: | |
47 | return "INITIALIZED"; | |
48 | case Operation::State::RUNNING: | |
49 | return "RUNNING"; | |
50 | case Operation::State::FINISHED: | |
51 | return "FINISHED"; | |
52 | case Operation::State::CANCELED: | |
53 | return "CANCELED"; | |
54 | case Operation::State::CLOSED: | |
55 | return "CLOSED"; | |
56 | case Operation::State::ERROR: | |
57 | return "ERROR"; | |
58 | case Operation::State::UNKNOWN: | |
59 | return "UNKNOWN"; | |
60 | case Operation::State::PENDING: | |
61 | return "PENDING"; | |
62 | default: | |
63 | std::stringstream ss; | |
64 | ss << "Unknown Operation::State " << EnumToInt(state); | |
65 | return ss.str(); | |
66 | } | |
67 | } | |
68 | ||
69 | const std::string TypeIdToString(const ColumnType::TypeId& type_id) { | |
70 | switch (type_id) { | |
71 | case ColumnType::TypeId::BOOLEAN: | |
72 | return "BOOLEAN"; | |
73 | case ColumnType::TypeId::TINYINT: | |
74 | return "TINYINT"; | |
75 | case ColumnType::TypeId::SMALLINT: | |
76 | return "SMALLINT"; | |
77 | case ColumnType::TypeId::INT: | |
78 | return "INT"; | |
79 | case ColumnType::TypeId::BIGINT: | |
80 | return "BIGINT"; | |
81 | case ColumnType::TypeId::FLOAT: | |
82 | return "FLOAT"; | |
83 | case ColumnType::TypeId::DOUBLE: | |
84 | return "DOUBLE"; | |
85 | case ColumnType::TypeId::STRING: | |
86 | return "STRING"; | |
87 | case ColumnType::TypeId::TIMESTAMP: | |
88 | return "TIMESTAMP"; | |
89 | case ColumnType::TypeId::BINARY: | |
90 | return "BINARY"; | |
91 | case ColumnType::TypeId::ARRAY: | |
92 | return "ARRAY"; | |
93 | case ColumnType::TypeId::MAP: | |
94 | return "MAP"; | |
95 | case ColumnType::TypeId::STRUCT: | |
96 | return "STRUCT"; | |
97 | case ColumnType::TypeId::UNION: | |
98 | return "UNION"; | |
99 | case ColumnType::TypeId::USER_DEFINED: | |
100 | return "USER_DEFINED"; | |
101 | case ColumnType::TypeId::DECIMAL: | |
102 | return "DECIMAL"; | |
103 | case ColumnType::TypeId::NULL_TYPE: | |
104 | return "NULL_TYPE"; | |
105 | case ColumnType::TypeId::DATE: | |
106 | return "DATE"; | |
107 | case ColumnType::TypeId::VARCHAR: | |
108 | return "VARCHAR"; | |
109 | case ColumnType::TypeId::CHAR: | |
110 | return "CHAR"; | |
111 | case ColumnType::TypeId::INVALID: | |
112 | return "INVALID"; | |
113 | default: { | |
114 | std::stringstream ss; | |
115 | ss << "Unknown ColumnType::TypeId " << EnumToInt(type_id); | |
116 | return ss.str(); | |
117 | } | |
118 | } | |
119 | } | |
120 | ||
121 | hs2::TFetchOrientation::type FetchOrientationToTFetchOrientation( | |
122 | FetchOrientation orientation) { | |
123 | switch (orientation) { | |
124 | case FetchOrientation::NEXT: | |
125 | return hs2::TFetchOrientation::FETCH_NEXT; | |
126 | case FetchOrientation::PRIOR: | |
127 | return hs2::TFetchOrientation::FETCH_PRIOR; | |
128 | case FetchOrientation::RELATIVE: | |
129 | return hs2::TFetchOrientation::FETCH_RELATIVE; | |
130 | case FetchOrientation::ABSOLUTE: | |
131 | return hs2::TFetchOrientation::FETCH_ABSOLUTE; | |
132 | case FetchOrientation::FIRST: | |
133 | return hs2::TFetchOrientation::FETCH_FIRST; | |
134 | case FetchOrientation::LAST: | |
135 | return hs2::TFetchOrientation::FETCH_LAST; | |
136 | default: | |
137 | DCHECK(false) << "Unknown FetchOrientation " << EnumToInt(orientation); | |
138 | return hs2::TFetchOrientation::FETCH_NEXT; | |
139 | } | |
140 | } | |
141 | ||
142 | hs2::TProtocolVersion::type ProtocolVersionToTProtocolVersion(ProtocolVersion protocol) { | |
143 | switch (protocol) { | |
144 | case ProtocolVersion::PROTOCOL_V1: | |
145 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V1; | |
146 | case ProtocolVersion::PROTOCOL_V2: | |
147 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V2; | |
148 | case ProtocolVersion::PROTOCOL_V3: | |
149 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V3; | |
150 | case ProtocolVersion::PROTOCOL_V4: | |
151 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V4; | |
152 | case ProtocolVersion::PROTOCOL_V5: | |
153 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V5; | |
154 | case ProtocolVersion::PROTOCOL_V6: | |
155 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V6; | |
156 | case ProtocolVersion::PROTOCOL_V7: | |
157 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V7; | |
158 | default: | |
159 | DCHECK(false) << "Unknown ProtocolVersion " << EnumToInt(protocol); | |
160 | return hs2::TProtocolVersion::HIVE_CLI_SERVICE_PROTOCOL_V7; | |
161 | } | |
162 | } | |
163 | ||
164 | Operation::State TOperationStateToOperationState( | |
165 | const hs2::TOperationState::type& tstate) { | |
166 | switch (tstate) { | |
167 | case hs2::TOperationState::INITIALIZED_STATE: | |
168 | return Operation::State::INITIALIZED; | |
169 | case hs2::TOperationState::RUNNING_STATE: | |
170 | return Operation::State::RUNNING; | |
171 | case hs2::TOperationState::FINISHED_STATE: | |
172 | return Operation::State::FINISHED; | |
173 | case hs2::TOperationState::CANCELED_STATE: | |
174 | return Operation::State::CANCELED; | |
175 | case hs2::TOperationState::CLOSED_STATE: | |
176 | return Operation::State::CLOSED; | |
177 | case hs2::TOperationState::ERROR_STATE: | |
178 | return Operation::State::ERROR; | |
179 | case hs2::TOperationState::UKNOWN_STATE: | |
180 | return Operation::State::UNKNOWN; | |
181 | case hs2::TOperationState::PENDING_STATE: | |
182 | return Operation::State::PENDING; | |
183 | default: | |
184 | ARROW_LOG(WARNING) << "Unknown TOperationState " << tstate; | |
185 | return Operation::State::UNKNOWN; | |
186 | } | |
187 | } | |
188 | ||
189 | Status TStatusToStatus(const hs2::TStatus& tstatus) { | |
190 | switch (tstatus.statusCode) { | |
191 | case hs2::TStatusCode::SUCCESS_STATUS: | |
192 | return Status::OK(); | |
193 | case hs2::TStatusCode::SUCCESS_WITH_INFO_STATUS: { | |
194 | std::stringstream ss; | |
195 | for (size_t i = 0; i < tstatus.infoMessages.size(); i++) { | |
196 | if (i != 0) ss << ","; | |
197 | ss << tstatus.infoMessages[i]; | |
198 | } | |
199 | return Status::OK(ss.str()); | |
200 | } | |
201 | case hs2::TStatusCode::STILL_EXECUTING_STATUS: | |
202 | return Status::ExecutionError("Still executing"); | |
203 | case hs2::TStatusCode::ERROR_STATUS: | |
204 | return Status::IOError(tstatus.errorMessage); | |
205 | case hs2::TStatusCode::INVALID_HANDLE_STATUS: | |
206 | return Status::Invalid("Invalid handle"); | |
207 | default: { | |
208 | return Status::UnknownError("Unknown TStatusCode ", tstatus.statusCode); | |
209 | } | |
210 | } | |
211 | } | |
212 | ||
213 | std::unique_ptr<ColumnType> TTypeDescToColumnType(const hs2::TTypeDesc& ttype_desc) { | |
214 | if (ttype_desc.types.size() != 1 || !ttype_desc.types[0].__isset.primitiveEntry) { | |
215 | ARROW_LOG(WARNING) << "TTypeDescToColumnType only supports primitive types."; | |
216 | return std::unique_ptr<ColumnType>(new PrimitiveType(ColumnType::TypeId::INVALID)); | |
217 | } | |
218 | ||
219 | ColumnType::TypeId type_id = TTypeIdToTypeId(ttype_desc.types[0].primitiveEntry.type); | |
220 | if (type_id == ColumnType::TypeId::CHAR || type_id == ColumnType::TypeId::VARCHAR) { | |
221 | const std::map<std::string, hs2::TTypeQualifierValue>& qualifiers = | |
222 | ttype_desc.types[0].primitiveEntry.typeQualifiers.qualifiers; | |
223 | DCHECK_EQ(qualifiers.count(hs2::g_TCLIService_constants.CHARACTER_MAXIMUM_LENGTH), 1); | |
224 | ||
225 | try { | |
226 | return std::unique_ptr<ColumnType>(new CharacterType( | |
227 | type_id, | |
228 | qualifiers.at(hs2::g_TCLIService_constants.CHARACTER_MAXIMUM_LENGTH).i32Value)); | |
229 | } catch (std::out_of_range e) { | |
230 | ARROW_LOG(ERROR) << "Character type qualifiers invalid: " << e.what(); | |
231 | return std::unique_ptr<ColumnType>(new PrimitiveType(ColumnType::TypeId::INVALID)); | |
232 | } | |
233 | } else if (type_id == ColumnType::TypeId::DECIMAL) { | |
234 | const std::map<std::string, hs2::TTypeQualifierValue>& qualifiers = | |
235 | ttype_desc.types[0].primitiveEntry.typeQualifiers.qualifiers; | |
236 | DCHECK_EQ(qualifiers.count(hs2::g_TCLIService_constants.PRECISION), 1); | |
237 | DCHECK_EQ(qualifiers.count(hs2::g_TCLIService_constants.SCALE), 1); | |
238 | ||
239 | try { | |
240 | return std::unique_ptr<ColumnType>(new DecimalType( | |
241 | type_id, qualifiers.at(hs2::g_TCLIService_constants.PRECISION).i32Value, | |
242 | qualifiers.at(hs2::g_TCLIService_constants.SCALE).i32Value)); | |
243 | } catch (std::out_of_range e) { | |
244 | ARROW_LOG(ERROR) << "Decimal type qualifiers invalid: " << e.what(); | |
245 | return std::unique_ptr<ColumnType>(new PrimitiveType(ColumnType::TypeId::INVALID)); | |
246 | } | |
247 | } else { | |
248 | return std::unique_ptr<ColumnType>(new PrimitiveType(type_id)); | |
249 | } | |
250 | } | |
251 | ||
252 | ColumnType::TypeId TTypeIdToTypeId(const hs2::TTypeId::type& type_id) { | |
253 | switch (type_id) { | |
254 | case hs2::TTypeId::BOOLEAN_TYPE: | |
255 | return ColumnType::TypeId::BOOLEAN; | |
256 | case hs2::TTypeId::TINYINT_TYPE: | |
257 | return ColumnType::TypeId::TINYINT; | |
258 | case hs2::TTypeId::SMALLINT_TYPE: | |
259 | return ColumnType::TypeId::SMALLINT; | |
260 | case hs2::TTypeId::INT_TYPE: | |
261 | return ColumnType::TypeId::INT; | |
262 | case hs2::TTypeId::BIGINT_TYPE: | |
263 | return ColumnType::TypeId::BIGINT; | |
264 | case hs2::TTypeId::FLOAT_TYPE: | |
265 | return ColumnType::TypeId::FLOAT; | |
266 | case hs2::TTypeId::DOUBLE_TYPE: | |
267 | return ColumnType::TypeId::DOUBLE; | |
268 | case hs2::TTypeId::STRING_TYPE: | |
269 | return ColumnType::TypeId::STRING; | |
270 | case hs2::TTypeId::TIMESTAMP_TYPE: | |
271 | return ColumnType::TypeId::TIMESTAMP; | |
272 | case hs2::TTypeId::BINARY_TYPE: | |
273 | return ColumnType::TypeId::BINARY; | |
274 | case hs2::TTypeId::ARRAY_TYPE: | |
275 | return ColumnType::TypeId::ARRAY; | |
276 | case hs2::TTypeId::MAP_TYPE: | |
277 | return ColumnType::TypeId::MAP; | |
278 | case hs2::TTypeId::STRUCT_TYPE: | |
279 | return ColumnType::TypeId::STRUCT; | |
280 | case hs2::TTypeId::UNION_TYPE: | |
281 | return ColumnType::TypeId::UNION; | |
282 | case hs2::TTypeId::USER_DEFINED_TYPE: | |
283 | return ColumnType::TypeId::USER_DEFINED; | |
284 | case hs2::TTypeId::DECIMAL_TYPE: | |
285 | return ColumnType::TypeId::DECIMAL; | |
286 | case hs2::TTypeId::NULL_TYPE: | |
287 | return ColumnType::TypeId::NULL_TYPE; | |
288 | case hs2::TTypeId::DATE_TYPE: | |
289 | return ColumnType::TypeId::DATE; | |
290 | case hs2::TTypeId::VARCHAR_TYPE: | |
291 | return ColumnType::TypeId::VARCHAR; | |
292 | case hs2::TTypeId::CHAR_TYPE: | |
293 | return ColumnType::TypeId::CHAR; | |
294 | default: | |
295 | ARROW_LOG(WARNING) << "Unknown TTypeId " << type_id; | |
296 | return ColumnType::TypeId::INVALID; | |
297 | } | |
298 | } | |
299 | ||
300 | } // namespace hiveserver2 | |
301 | } // namespace arrow |