ADBC
Arrow Database Connectivity
Loading...
Searching...
No Matches
base_driver.h
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#pragma once
19
20#include <charconv>
21#include <cstring>
22#include <memory>
23#include <optional>
24#include <string>
25#include <string_view>
26#include <type_traits>
27#include <utility>
28#include <variant>
29#include <vector>
30
31#include <arrow-adbc/adbc.h>
32
33#include "fmt/core.h"
34
36
49namespace adbc::driver {
50
52enum class LifecycleState {
54 kUninitialized,
56 kInitialized,
57};
58
60class Option {
61 public:
63 struct Unset {};
65 using Value = std::variant<Unset, std::string, std::vector<uint8_t>, int64_t, double>;
66
67 Option() : value_(Unset{}) {}
70 explicit Option(const char* value)
71 : value_(value ? Value(std::string(value)) : Value{Unset{}}) {}
72 explicit Option(std::string value) : value_(std::move(value)) {}
73 explicit Option(std::vector<uint8_t> value) : value_(std::move(value)) {}
74 explicit Option(double value) : value_(value) {}
75 explicit Option(int64_t value) : value_(value) {}
76
77 const Value& value() const& { return value_; }
78 Value& value() && { return value_; }
79
81 bool has_value() const { return !std::holds_alternative<Unset>(value_); }
82
85 return std::visit(
86 [&](auto&& value) -> Result<bool> {
87 using T = std::decay_t<decltype(value)>;
88 if constexpr (std::is_same_v<T, std::string>) {
89 if (value == ADBC_OPTION_VALUE_ENABLED) {
90 return true;
91 } else if (value == ADBC_OPTION_VALUE_DISABLED) {
92 return false;
93 }
94 }
95 return status::InvalidArgument("Invalid boolean value ", this->Format());
96 },
97 value_);
98 }
99
102 return std::visit(
103 [&](auto&& value) -> Result<int64_t> {
104 using T = std::decay_t<decltype(value)>;
105 if constexpr (std::is_same_v<T, int64_t>) {
106 return value;
107 } else if constexpr (std::is_same_v<T, std::string>) {
108 int64_t parsed = 0;
109 auto begin = value.data();
110 auto end = value.data() + value.size();
111 auto result = std::from_chars(begin, end, parsed);
112 if (result.ec != std::errc()) {
113 return status::InvalidArgument("Invalid integer value '", value,
114 "': not an integer", value);
115 } else if (result.ptr != end) {
116 return status::InvalidArgument("Invalid integer value '", value,
117 "': trailing data", value);
118 }
119 return parsed;
120 } else {
121 return status::InvalidArgument("Invalid integer value ", this->Format());
122 }
123 },
124 value_);
125 }
126
129 return std::visit(
130 [&](auto&& value) -> Result<std::string_view> {
131 using T = std::decay_t<decltype(value)>;
132 if constexpr (std::is_same_v<T, std::string>) {
133 return value;
134 } else {
135 return status::InvalidArgument("Invalid string value ", this->Format());
136 }
137 },
138 value_);
139 }
140
142 std::string Format() const {
143 return std::visit(
144 [&](auto&& value) -> std::string {
145 using T = std::decay_t<decltype(value)>;
146 if constexpr (std::is_same_v<T, adbc::driver::Option::Unset>) {
147 return "(NULL)";
148 } else if constexpr (std::is_same_v<T, std::string>) {
149 return std::string("'") + value + "'";
150 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
151 return std::string("(") + std::to_string(value.size()) + " bytes)";
152 } else {
153 return std::to_string(value);
154 }
155 },
156 value_);
157 }
158
159 private:
160 Value value_;
161
162 // Methods used by trampolines to export option values in C below
163 friend class ObjectBase;
164 AdbcStatusCode CGet(char* out, size_t* length, AdbcError* error) const {
165 {
166 if (!length || (!out && *length > 0)) {
167 return status::InvalidArgument("Must provide both out and length to GetOption")
168 .ToAdbc(error);
169 }
170 return std::visit(
171 [&](auto&& value) -> AdbcStatusCode {
172 using T = std::decay_t<decltype(value)>;
173 if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, int64_t> ||
174 std::is_same_v<T, double>) {
175 std::string_view string_value;
176 std::string allocated_value;
177 if constexpr (std::is_same_v<T, int64_t>) {
178 allocated_value = fmt::format("{}", value);
179 string_value = allocated_value;
180 } else if constexpr (std::is_same_v<T, double>) {
181 allocated_value = fmt::format("{}", value);
182 string_value = allocated_value;
183 } else {
184 string_value = value;
185 }
186 size_t value_size_with_terminator = string_value.size() + 1;
187 if (*length >= value_size_with_terminator) {
188 std::memcpy(out, string_value.data(), string_value.size());
189 out[string_value.size()] = 0;
190 }
191 *length = value_size_with_terminator;
192 return ADBC_STATUS_OK;
193 } else if constexpr (std::is_same_v<T, Unset>) {
194 return status::NotFound("Unknown option").ToAdbc(error);
195 } else {
196 return status::NotFound("Option value is not a string").ToAdbc(error);
197 }
198 },
199 value_);
200 }
201 }
202 AdbcStatusCode CGet(uint8_t* out, size_t* length, AdbcError* error) const {
203 if (!length || (!out && *length > 0)) {
204 return status::InvalidArgument("Must provide both out and length to GetOption")
205 .ToAdbc(error);
206 }
207 return std::visit(
208 [&](auto&& value) -> AdbcStatusCode {
209 using T = std::decay_t<decltype(value)>;
210 if constexpr (std::is_same_v<T, std::string> ||
211 std::is_same_v<T, std::vector<uint8_t>>) {
212 if (*length >= value.size()) {
213 std::memcpy(out, value.data(), value.size());
214 }
215 *length = value.size();
216 return ADBC_STATUS_OK;
217 } else if constexpr (std::is_same_v<T, Unset>) {
218 return status::NotFound("Unknown option").ToAdbc(error);
219 } else {
220 return status::NotFound("Option value is not a bytestring").ToAdbc(error);
221 }
222 },
223 value_);
224 }
225 AdbcStatusCode CGet(int64_t* out, AdbcError* error) const {
226 {
227 if (!out) {
228 return status::InvalidArgument("Must provide out to GetOption").ToAdbc(error);
229 }
230 return std::visit(
231 [&](auto&& value) -> AdbcStatusCode {
232 using T = std::decay_t<decltype(value)>;
233 if constexpr (std::is_same_v<T, int64_t>) {
234 *out = value;
235 return ADBC_STATUS_OK;
236 } else if constexpr (std::is_same_v<T, Unset>) {
237 return status::NotFound("Unknown option").ToAdbc(error);
238 } else {
239 return status::NotFound("Option value is not an integer").ToAdbc(error);
240 }
241 },
242 value_);
243 }
244 }
245 AdbcStatusCode CGet(double* out, AdbcError* error) const {
246 if (!out) {
247 return status::InvalidArgument("Must provide out to GetOption").ToAdbc(error);
248 }
249 return std::visit(
250 [&](auto&& value) -> AdbcStatusCode {
251 using T = std::decay_t<decltype(value)>;
252 if constexpr (std::is_same_v<T, double> || std::is_same_v<T, int64_t>) {
253 *out = static_cast<double>(value);
254 return ADBC_STATUS_OK;
255 } else if constexpr (std::is_same_v<T, Unset>) {
256 return status::NotFound("Unknown option").ToAdbc(error);
257 } else {
258 return status::NotFound("Option value is not a double").ToAdbc(error);
259 }
260 },
261 value_);
262 }
263};
264
269class ObjectBase {
270 public:
271 ObjectBase() = default;
272 virtual ~ObjectBase() = default;
273
274 // Called After zero or more SetOption() calls. The parent is the
275 // private_data of the AdbcDatabase, or AdbcConnection when initializing a
276 // subclass of ConnectionObjectBase, and StatementObjectBase (respectively),
277 // or otherwise nullptr. For example, if you have defined
278 // Driver<MyDatabase, MyConnection, MyStatement>, you can
279 // reinterpret_cast<MyDatabase>(parent) in MyConnection::Init().
280
289 virtual AdbcStatusCode Init(void* parent, AdbcError* error) {
290 lifecycle_state_ = LifecycleState::kInitialized;
291 return ADBC_STATUS_OK;
292 }
293
304 virtual AdbcStatusCode Release(AdbcError* error) { return ADBC_STATUS_OK; }
305
307 virtual Result<Option> GetOption(std::string_view key) {
308 Option option(nullptr);
309 return option;
310 }
311
313 virtual AdbcStatusCode SetOption(std::string_view key, Option value, AdbcError* error) {
315 }
316
317 protected:
318 LifecycleState lifecycle_state_;
319
320 private:
321 // Let the Driver use these to expose C callables wrapping option setters/getters
322 template <typename DatabaseT, typename ConnectionT, typename StatementT>
323 friend class Driver;
324
325 template <typename T>
326 AdbcStatusCode CSetOption(const char* key, T value, AdbcError* error) {
327 Option option(value);
328 return SetOption(key, std::move(option), error);
329 }
330
331 AdbcStatusCode CSetOptionBytes(const char* key, const uint8_t* value, size_t length,
332 AdbcError* error) {
333 std::vector<uint8_t> cppvalue(value, value + length);
334 Option option(std::move(cppvalue));
335 return SetOption(key, std::move(option), error);
336 }
337
338 template <typename T>
339 AdbcStatusCode CGetOptionStringLike(const char* key, T* value, size_t* length,
340 AdbcError* error) {
341 Option option;
342 RAISE_RESULT(error, option, GetOption(key));
343 return option.CGet(value, length, error);
344 }
345
346 template <typename T>
347 AdbcStatusCode CGetOptionNumeric(const char* key, T* value, AdbcError* error) {
348 Option option;
349 RAISE_RESULT(error, option, GetOption(key));
350 return option.CGet(value, error);
351 }
352};
353
355template <typename DatabaseT, typename ConnectionT, typename StatementT, typename T>
357
358template <typename DatabaseT, typename ConnectionT, typename StatementT>
359struct ResolveObjectTImpl<DatabaseT, ConnectionT, StatementT, struct AdbcDatabase> {
360 using type = DatabaseT;
361};
362template <typename DatabaseT, typename ConnectionT, typename StatementT>
363struct ResolveObjectTImpl<DatabaseT, ConnectionT, StatementT, struct AdbcConnection> {
364 using type = ConnectionT;
365};
366template <typename DatabaseT, typename ConnectionT, typename StatementT>
367struct ResolveObjectTImpl<DatabaseT, ConnectionT, StatementT, struct AdbcStatement> {
368 using type = StatementT;
369};
370
372template <typename DatabaseT, typename ConnectionT, typename StatementT, typename T>
373using ResolveObjectT =
375
376// Driver authors can declare a template specialization of the Driver class
377// and use it to provide their driver init function. It is possible, but
378// rarely useful, to subclass a driver.
379template <typename DatabaseT, typename ConnectionT, typename StatementT>
380class Driver {
381 public:
382 static AdbcStatusCode Init(int version, void* raw_driver, AdbcError* error) {
383 if (version != ADBC_VERSION_1_0_0 && version != ADBC_VERSION_1_1_0) {
385 }
386
387 auto* driver = reinterpret_cast<AdbcDriver*>(raw_driver);
388 if (version >= ADBC_VERSION_1_1_0) {
389 std::memset(driver, 0, ADBC_DRIVER_1_1_0_SIZE);
390
391 driver->ErrorGetDetailCount = &CErrorGetDetailCount;
392 driver->ErrorGetDetail = &CErrorGetDetail;
393
394 driver->DatabaseGetOption = &CGetOption<AdbcDatabase>;
395 driver->DatabaseGetOptionBytes = &CGetOptionBytes<AdbcDatabase>;
396 driver->DatabaseGetOptionInt = &CGetOptionInt<AdbcDatabase>;
397 driver->DatabaseGetOptionDouble = &CGetOptionDouble<AdbcDatabase>;
398 driver->DatabaseSetOptionBytes = &CSetOptionBytes<AdbcDatabase>;
399 driver->DatabaseSetOptionInt = &CSetOptionInt<AdbcDatabase>;
400 driver->DatabaseSetOptionDouble = &CSetOptionDouble<AdbcDatabase>;
401
402 driver->ConnectionCancel = &CConnectionCancel;
403 driver->ConnectionGetOption = &CGetOption<AdbcConnection>;
404 driver->ConnectionGetOptionBytes = &CGetOptionBytes<AdbcConnection>;
405 driver->ConnectionGetOptionInt = &CGetOptionInt<AdbcConnection>;
406 driver->ConnectionGetOptionDouble = &CGetOptionDouble<AdbcConnection>;
407 driver->ConnectionGetStatistics = &CConnectionGetStatistics;
408 driver->ConnectionGetStatisticNames = &CConnectionGetStatisticNames;
409 driver->ConnectionSetOptionBytes = &CSetOptionBytes<AdbcConnection>;
410 driver->ConnectionSetOptionInt = &CSetOptionInt<AdbcConnection>;
411 driver->ConnectionSetOptionDouble = &CSetOptionDouble<AdbcConnection>;
412
413 driver->StatementCancel = &CStatementCancel;
414 driver->StatementExecuteSchema = &CStatementExecuteSchema;
415 driver->StatementGetOption = &CGetOption<AdbcStatement>;
416 driver->StatementGetOptionBytes = &CGetOptionBytes<AdbcStatement>;
417 driver->StatementGetOptionInt = &CGetOptionInt<AdbcStatement>;
418 driver->StatementGetOptionDouble = &CGetOptionDouble<AdbcStatement>;
419 driver->StatementSetOptionBytes = &CSetOptionBytes<AdbcStatement>;
420 driver->StatementSetOptionInt = &CSetOptionInt<AdbcStatement>;
421 driver->StatementSetOptionDouble = &CSetOptionDouble<AdbcStatement>;
422 } else {
423 std::memset(driver, 0, ADBC_DRIVER_1_0_0_SIZE);
424 }
425
426 driver->private_data = new Driver();
427 driver->release = &CDriverRelease;
428
429 driver->DatabaseInit = &CDatabaseInit;
430 driver->DatabaseNew = &CNew<AdbcDatabase>;
431 driver->DatabaseRelease = &CRelease<AdbcDatabase>;
432 driver->DatabaseSetOption = &CSetOption<AdbcDatabase>;
433
434 driver->ConnectionCommit = &CConnectionCommit;
435 driver->ConnectionGetInfo = &CConnectionGetInfo;
436 driver->ConnectionGetObjects = &CConnectionGetObjects;
437 driver->ConnectionGetTableSchema = &CConnectionGetTableSchema;
438 driver->ConnectionGetTableTypes = &CConnectionGetTableTypes;
439 driver->ConnectionInit = &CConnectionInit;
440 driver->ConnectionNew = &CNew<AdbcConnection>;
441 driver->ConnectionRelease = &CRelease<AdbcConnection>;
442 driver->ConnectionReadPartition = &CConnectionReadPartition;
443 driver->ConnectionRollback = &CConnectionRollback;
444 driver->ConnectionSetOption = &CSetOption<AdbcConnection>;
445
446 driver->StatementBind = &CStatementBind;
447 driver->StatementBindStream = &CStatementBindStream;
448 driver->StatementExecutePartitions = &CStatementExecutePartitions;
449 driver->StatementExecuteQuery = &CStatementExecuteQuery;
450 driver->StatementGetParameterSchema = &CStatementGetParameterSchema;
451 driver->StatementNew = &CStatementNew;
452 driver->StatementPrepare = &CStatementPrepare;
453 driver->StatementRelease = &CRelease<AdbcStatement>;
454 driver->StatementSetOption = &CSetOption<AdbcStatement>;
455 driver->StatementSetSqlQuery = &CStatementSetSqlQuery;
456 driver->StatementSetSubstraitPlan = &CStatementSetSubstraitPlan;
457
458 return ADBC_STATUS_OK;
459 }
460
461 // Driver trampolines
462 static AdbcStatusCode CDriverRelease(AdbcDriver* driver, AdbcError* error) {
463 auto driver_private = reinterpret_cast<Driver*>(driver->private_data);
464 delete driver_private;
465 driver->private_data = nullptr;
466 return ADBC_STATUS_OK;
467 }
468
469 static int CErrorGetDetailCount(const AdbcError* error) {
471 return 0;
472 }
473
474 auto error_obj = reinterpret_cast<Status*>(error->private_data);
475 if (!error_obj) {
476 return 0;
477 }
478 return error_obj->CDetailCount();
479 }
480
481 static AdbcErrorDetail CErrorGetDetail(const AdbcError* error, int index) {
483 return {nullptr, nullptr, 0};
484 }
485
486 auto error_obj = reinterpret_cast<Status*>(error->private_data);
487 if (!error_obj) {
488 return {nullptr, nullptr, 0};
489 }
490
491 return error_obj->CDetail(index);
492 }
493
494 // Templatable trampolines
495
496 template <typename T>
497 static AdbcStatusCode CNew(T* obj, AdbcError* error) {
498 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
499 auto private_data = new ObjectT();
500 obj->private_data = private_data;
501 return ADBC_STATUS_OK;
502 }
503
504 template <typename T>
505 static AdbcStatusCode CRelease(T* obj, AdbcError* error) {
506 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
507 if (obj == nullptr) return ADBC_STATUS_INVALID_STATE;
508 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
509 if (private_data == nullptr) return ADBC_STATUS_INVALID_STATE;
510 AdbcStatusCode result = private_data->Release(error);
511 if (result != ADBC_STATUS_OK) {
512 return result;
513 }
514
515 delete private_data;
516 obj->private_data = nullptr;
517 return ADBC_STATUS_OK;
518 }
519
520 template <typename T>
521 static AdbcStatusCode CSetOption(T* obj, const char* key, const char* value,
522 AdbcError* error) {
523 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
524 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
525 return private_data->template CSetOption<>(key, value, error);
526 }
527
528 template <typename T>
529 static AdbcStatusCode CSetOptionBytes(T* obj, const char* key, const uint8_t* value,
530 size_t length, AdbcError* error) {
531 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
532 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
533 return private_data->CSetOptionBytes(key, value, length, error);
534 }
535
536 template <typename T>
537 static AdbcStatusCode CSetOptionInt(T* obj, const char* key, int64_t value,
538 AdbcError* error) {
539 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
540 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
541 return private_data->template CSetOption<>(key, value, error);
542 }
543
544 template <typename T>
545 static AdbcStatusCode CSetOptionDouble(T* obj, const char* key, double value,
546 AdbcError* error) {
547 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
548 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
549 return private_data->template CSetOption<>(key, value, error);
550 }
551
552 template <typename T>
553 static AdbcStatusCode CGetOption(T* obj, const char* key, char* value, size_t* length,
554 AdbcError* error) {
555 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
556 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
557 return private_data->template CGetOptionStringLike<>(key, value, length, error);
558 }
559
560 template <typename T>
561 static AdbcStatusCode CGetOptionBytes(T* obj, const char* key, uint8_t* value,
562 size_t* length, AdbcError* error) {
563 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
564 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
565 return private_data->template CGetOptionStringLike<>(key, value, length, error);
566 }
567
568 template <typename T>
569 static AdbcStatusCode CGetOptionInt(T* obj, const char* key, int64_t* value,
570 AdbcError* error) {
571 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
572 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
573 return private_data->template CGetOptionNumeric<>(key, value, error);
574 }
575
576 template <typename T>
577 static AdbcStatusCode CGetOptionDouble(T* obj, const char* key, double* value,
578 AdbcError* error) {
579 using ObjectT = ResolveObjectT<DatabaseT, ConnectionT, StatementT, T>;
580 auto private_data = reinterpret_cast<ObjectT*>(obj->private_data);
581 return private_data->template CGetOptionNumeric<>(key, value, error);
582 }
583
584#define CHECK_INIT(DATABASE, ERROR) \
585 if (!(DATABASE) || !(DATABASE)->private_data) { \
586 return status::InvalidState("Database is uninitialized").ToAdbc(ERROR); \
587 }
588
589 // Database trampolines
590 static AdbcStatusCode CDatabaseInit(AdbcDatabase* database, AdbcError* error) {
591 CHECK_INIT(database, error);
592 auto private_data = reinterpret_cast<DatabaseT*>(database->private_data);
593 return private_data->Init(nullptr, error);
594 }
595
596#undef CHECK_INIT
597#define CHECK_INIT(CONNECTION, ERROR) \
598 if (!(CONNECTION) || !(CONNECTION)->private_data) { \
599 return status::InvalidState("Connection is uninitialized").ToAdbc(ERROR); \
600 }
601
602 // Connection trampolines
603 static AdbcStatusCode CConnectionInit(AdbcConnection* connection,
604 AdbcDatabase* database, AdbcError* error) {
605 CHECK_INIT(connection, error);
606 if (!database || !database->private_data) {
607 return status::InvalidState("Database is uninitialized").ToAdbc(error);
608 }
609 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
610 return private_data->Init(database->private_data, error);
611 }
612
613 static AdbcStatusCode CConnectionCancel(AdbcConnection* connection, AdbcError* error) {
614 CHECK_INIT(connection, error);
615 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
616 return private_data->Cancel(error);
617 }
618
619 static AdbcStatusCode CConnectionGetInfo(AdbcConnection* connection,
620 const uint32_t* info_codes,
621 size_t info_codes_length,
622 ArrowArrayStream* out, AdbcError* error) {
623 CHECK_INIT(connection, error);
624 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
625 return private_data->GetInfo(info_codes, info_codes_length, out, error);
626 }
627
628 static AdbcStatusCode CConnectionGetObjects(AdbcConnection* connection, int depth,
629 const char* catalog, const char* db_schema,
630 const char* table_name,
631 const char** table_type,
632 const char* column_name,
633 ArrowArrayStream* out, AdbcError* error) {
634 CHECK_INIT(connection, error);
635 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
636 return private_data->GetObjects(depth, catalog, db_schema, table_name, table_type,
637 column_name, out, error);
638 }
639
640 static AdbcStatusCode CConnectionGetStatistics(
641 AdbcConnection* connection, const char* catalog, const char* db_schema,
642 const char* table_name, char approximate, ArrowArrayStream* out, AdbcError* error) {
643 CHECK_INIT(connection, error);
644 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
645 return private_data->GetStatistics(catalog, db_schema, table_name, approximate, out,
646 error);
647 }
648
649 static AdbcStatusCode CConnectionGetStatisticNames(AdbcConnection* connection,
650 ArrowArrayStream* out,
651 AdbcError* error) {
652 CHECK_INIT(connection, error);
653 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
654 return private_data->GetStatisticNames(out, error);
655 }
656
657 static AdbcStatusCode CConnectionGetTableSchema(AdbcConnection* connection,
658 const char* catalog,
659 const char* db_schema,
660 const char* table_name,
661 ArrowSchema* schema, AdbcError* error) {
662 CHECK_INIT(connection, error);
663 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
664 return private_data->GetTableSchema(catalog, db_schema, table_name, schema, error);
665 }
666
667 static AdbcStatusCode CConnectionGetTableTypes(AdbcConnection* connection,
668 ArrowArrayStream* out,
669 AdbcError* error) {
670 CHECK_INIT(connection, error);
671 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
672 return private_data->GetTableTypes(out, error);
673 }
674
675 static AdbcStatusCode CConnectionReadPartition(AdbcConnection* connection,
676 const uint8_t* serialized_partition,
677 size_t serialized_length,
678 ArrowArrayStream* out,
679 AdbcError* error) {
680 CHECK_INIT(connection, error);
681 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
682 return private_data->ReadPartition(serialized_partition, serialized_length, out,
683 error);
684 }
685
686 static AdbcStatusCode CConnectionCommit(AdbcConnection* connection, AdbcError* error) {
687 CHECK_INIT(connection, error);
688 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
689 return private_data->Commit(error);
690 }
691
692 static AdbcStatusCode CConnectionRollback(AdbcConnection* connection,
693 AdbcError* error) {
694 CHECK_INIT(connection, error);
695 auto private_data = reinterpret_cast<ConnectionT*>(connection->private_data);
696 return private_data->Rollback(error);
697 }
698
699#undef CHECK_INIT
700#define CHECK_INIT(STATEMENT, ERROR) \
701 if (!(STATEMENT) || !(STATEMENT)->private_data) { \
702 return status::InvalidState("Statement is uninitialized").ToAdbc(ERROR); \
703 }
704
705 // Statement trampolines
706 static AdbcStatusCode CStatementNew(AdbcConnection* connection,
707 AdbcStatement* statement, AdbcError* error) {
708 if (!connection || !connection->private_data) {
709 return status::InvalidState("Connection is uninitialized").ToAdbc(error);
710 }
711 auto private_data = new StatementT();
712 AdbcStatusCode status = private_data->Init(connection->private_data, error);
713 if (status != ADBC_STATUS_OK) {
714 delete private_data;
715 }
716
717 statement->private_data = private_data;
718 return ADBC_STATUS_OK;
719 }
720
721 static AdbcStatusCode CStatementBind(AdbcStatement* statement, ArrowArray* values,
722 ArrowSchema* schema, AdbcError* error) {
723 CHECK_INIT(statement, error);
724 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
725 return private_data->Bind(values, schema, error);
726 }
727
728 static AdbcStatusCode CStatementBindStream(AdbcStatement* statement,
729 ArrowArrayStream* stream, AdbcError* error) {
730 CHECK_INIT(statement, error);
731 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
732 return private_data->BindStream(stream, error);
733 }
734
735 static AdbcStatusCode CStatementCancel(AdbcStatement* statement, AdbcError* error) {
736 CHECK_INIT(statement, error);
737 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
738 return private_data->Cancel(error);
739 }
740
741 static AdbcStatusCode CStatementExecutePartitions(AdbcStatement* statement,
742 struct ArrowSchema* schema,
743 struct AdbcPartitions* partitions,
744 int64_t* rows_affected,
745 AdbcError* error) {
746 CHECK_INIT(statement, error);
747 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
748 return private_data->ExecutePartitions(schema, partitions, rows_affected, error);
749 }
750
751 static AdbcStatusCode CStatementExecuteQuery(AdbcStatement* statement,
752 ArrowArrayStream* stream,
753 int64_t* rows_affected, AdbcError* error) {
754 CHECK_INIT(statement, error);
755 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
756 return private_data->ExecuteQuery(stream, rows_affected, error);
757 }
758
759 static AdbcStatusCode CStatementExecuteSchema(AdbcStatement* statement,
760 ArrowSchema* schema, AdbcError* error) {
761 CHECK_INIT(statement, error);
762 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
763 return private_data->ExecuteSchema(schema, error);
764 }
765
766 static AdbcStatusCode CStatementGetParameterSchema(AdbcStatement* statement,
767 ArrowSchema* schema,
768 AdbcError* error) {
769 CHECK_INIT(statement, error);
770 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
771 return private_data->GetParameterSchema(schema, error);
772 }
773
774 static AdbcStatusCode CStatementPrepare(AdbcStatement* statement, AdbcError* error) {
775 CHECK_INIT(statement, error);
776 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
777 return private_data->Prepare(error);
778 }
779
780 static AdbcStatusCode CStatementSetSqlQuery(AdbcStatement* statement, const char* query,
781 AdbcError* error) {
782 CHECK_INIT(statement, error);
783 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
784 return private_data->SetSqlQuery(query, error);
785 }
786
787 static AdbcStatusCode CStatementSetSubstraitPlan(AdbcStatement* statement,
788 const uint8_t* plan, size_t length,
789 AdbcError* error) {
790 CHECK_INIT(statement, error);
791 auto private_data = reinterpret_cast<StatementT*>(statement->private_data);
792 return private_data->SetSubstraitPlan(plan, length, error);
793 }
794
795#undef CHECK_INIT
796};
797
798template <typename Derived>
799class BaseDatabase : public ObjectBase {
800 public:
801 using Base = BaseDatabase<Derived>;
802
803 BaseDatabase() : ObjectBase() {}
804 ~BaseDatabase() = default;
805
807 AdbcStatusCode Init(void* parent, AdbcError* error) override {
808 RAISE_STATUS(error, impl().InitImpl());
809 return ObjectBase::Init(parent, error);
810 }
811
814 RAISE_STATUS(error, impl().ReleaseImpl());
815 return ADBC_STATUS_OK;
816 }
817
819 AdbcStatusCode SetOption(std::string_view key, Option value,
820 AdbcError* error) override {
821 RAISE_STATUS(error, impl().SetOptionImpl(key, std::move(value)));
822 return ADBC_STATUS_OK;
823 }
824
826 virtual Status InitImpl() { return status::Ok(); }
827
829 virtual Status ReleaseImpl() { return status::Ok(); }
830
832 virtual Status SetOptionImpl(std::string_view key, Option value) {
833 return status::NotImplemented(Derived::kErrorPrefix, " Unknown database option ", key,
834 "=", value.Format());
835 }
836
837 private:
838 Derived& impl() { return static_cast<Derived&>(*this); }
839};
840
841template <typename Derived>
842class BaseConnection : public ObjectBase {
843 public:
844 using Base = BaseConnection<Derived>;
845
847 enum class AutocommitState {
848 kAutocommit,
849 kTransaction,
850 };
851
853 ~BaseConnection() = default;
854
856 AdbcStatusCode Init(void* parent, AdbcError* error) override {
857 RAISE_STATUS(error, impl().InitImpl(parent));
858 return ObjectBase::Init(parent, error);
859 }
860
862 virtual Status InitImpl(void* parent) { return status::Ok(); }
863
865 AdbcStatusCode Cancel(AdbcError* error) { return impl().CancelImpl().ToAdbc(error); }
866
867 Status CancelImpl() { return status::NotImplemented("Cancel"); }
868
870 AdbcStatusCode Commit(AdbcError* error) { return impl().CommitImpl().ToAdbc(error); }
871
872 Status CommitImpl() { return status::NotImplemented("Commit"); }
873
875 AdbcStatusCode GetInfo(const uint32_t* info_codes, size_t info_codes_length,
876 ArrowArrayStream* out, AdbcError* error) {
877 std::vector<uint32_t> codes(info_codes, info_codes + info_codes_length);
878 RAISE_STATUS(error, impl().GetInfoImpl(codes, out));
879 return ADBC_STATUS_OK;
880 }
881
882 Status GetInfoImpl(const std::vector<uint32_t> info_codes, ArrowArrayStream* out) {
883 return status::NotImplemented("GetInfo");
884 }
885
887 AdbcStatusCode GetObjects(int c_depth, const char* catalog, const char* db_schema,
888 const char* table_name, const char** table_type,
889 const char* column_name, ArrowArrayStream* out,
890 AdbcError* error) {
891 const auto catalog_filter =
892 catalog ? std::make_optional(std::string_view(catalog)) : std::nullopt;
893 const auto schema_filter =
894 db_schema ? std::make_optional(std::string_view(db_schema)) : std::nullopt;
895 const auto table_filter =
896 table_name ? std::make_optional(std::string_view(table_name)) : std::nullopt;
897 const auto column_filter =
898 column_name ? std::make_optional(std::string_view(column_name)) : std::nullopt;
899 std::vector<std::string_view> table_type_filter;
900 while (table_type && *table_type) {
901 if (*table_type) {
902 table_type_filter.push_back(std::string_view(*table_type));
903 }
904 table_type++;
905 }
906
908 error, impl().GetObjectsImpl(c_depth, catalog_filter, schema_filter, table_filter,
909 column_filter, table_type_filter, out));
910
911 return ADBC_STATUS_OK;
912 }
913
914 Status GetObjectsImpl(int c_depth, std::optional<std::string_view> catalog_filter,
915 std::optional<std::string_view> schema_filter,
916 std::optional<std::string_view> table_filter,
917 std::optional<std::string_view> column_filter,
918 const std::vector<std::string_view>& table_types,
919 struct ArrowArrayStream* out) {
920 return status::NotImplemented("GetObjects");
921 }
922
924 AdbcStatusCode GetStatistics(const char* catalog, const char* db_schema,
925 const char* table_name, char approximate,
926 ArrowArrayStream* out, AdbcError* error) {
927 const auto catalog_filter =
928 catalog ? std::make_optional(std::string_view(catalog)) : std::nullopt;
929 const auto schema_filter =
930 db_schema ? std::make_optional(std::string_view(db_schema)) : std::nullopt;
931 const auto table_filter =
932 table_name ? std::make_optional(std::string_view(table_name)) : std::nullopt;
933 RAISE_STATUS(error, impl().GetStatisticsImpl(catalog_filter, schema_filter,
934 table_filter, approximate != 0, out));
935 return ADBC_STATUS_OK;
936 }
937
938 Status GetStatisticsImpl(std::optional<std::string_view> catalog,
939 std::optional<std::string_view> db_schema,
940 std::optional<std::string_view> table_name, bool approximate,
941 ArrowArrayStream* out) {
942 return status::NotImplemented("GetStatistics");
943 }
944
946 AdbcStatusCode GetStatisticNames(ArrowArrayStream* out, AdbcError* error) {
947 RAISE_STATUS(error, impl().GetStatisticNames(out));
948 return ADBC_STATUS_OK;
949 }
950
951 Status GetStatisticNames(ArrowArrayStream* out) {
952 return status::NotImplemented("GetStatisticNames");
953 }
954
956 AdbcStatusCode GetTableSchema(const char* catalog, const char* db_schema,
957 const char* table_name, ArrowSchema* schema,
958 AdbcError* error) {
959 if (!table_name) {
960 return status::InvalidArgument(Derived::kErrorPrefix,
961 " GetTableSchema: must provide table_name")
962 .ToAdbc(error);
963 }
964
965 std::optional<std::string_view> catalog_param =
966 catalog ? std::make_optional(std::string_view(catalog)) : std::nullopt;
967 std::optional<std::string_view> db_schema_param =
968 db_schema ? std::make_optional(std::string_view(db_schema)) : std::nullopt;
969
970 RAISE_STATUS(error, impl().GetTableSchemaImpl(catalog_param, db_schema_param,
971 table_name, schema));
972 return ADBC_STATUS_OK;
973 }
974
975 Status GetTableSchemaImpl(std::optional<std::string_view> catalog,
976 std::optional<std::string_view> db_schema,
977 std::string_view table_name, ArrowSchema* out) {
978 return status::NotImplemented("GetTableSchema");
979 }
980
982 AdbcStatusCode GetTableTypes(ArrowArrayStream* out, AdbcError* error) {
983 RAISE_STATUS(error, impl().GetTableTypesImpl(out));
984 return ADBC_STATUS_OK;
985 }
986
987 Status GetTableTypesImpl(ArrowArrayStream* out) {
988 return status::NotImplemented("GetTableTypes");
989 }
990
992 AdbcStatusCode ReadPartition(const uint8_t* serialized_partition,
993 size_t serialized_length, ArrowArrayStream* out,
994 AdbcError* error) {
995 std::string_view partition(reinterpret_cast<const char*>(serialized_partition),
996 serialized_length);
997 RAISE_STATUS(error, impl().ReadPartitionImpl(partition, out));
998 return ADBC_STATUS_OK;
999 }
1000
1001 Status ReadPartitionImpl(std::string_view serialized_partition, ArrowArrayStream* out) {
1002 return status::NotImplemented("ReadPartition");
1003 }
1004
1007 RAISE_STATUS(error, impl().ReleaseImpl());
1008 return ADBC_STATUS_OK;
1009 }
1010
1011 Status ReleaseImpl() { return status::Ok(); }
1012
1014 AdbcStatusCode Rollback(AdbcError* error) {
1015 RAISE_STATUS(error, impl().RollbackImpl());
1016 return ADBC_STATUS_OK;
1017 }
1018
1019 Status RollbackImpl() { return status::NotImplemented("Rollback"); }
1020
1022 AdbcStatusCode SetOption(std::string_view key, Option value,
1023 AdbcError* error) override {
1024 RAISE_STATUS(error, impl().SetOptionImpl(key, value));
1025 return ADBC_STATUS_OK;
1026 }
1027
1029 virtual Status SetOptionImpl(std::string_view key, Option value) {
1030 return status::NotImplemented(Derived::kErrorPrefix, " Unknown connection option ",
1031 key, "=", value.Format());
1032 }
1033
1034 private:
1035 Derived& impl() { return static_cast<Derived&>(*this); }
1036};
1037
1038template <typename Derived>
1039class BaseStatement : public ObjectBase {
1040 public:
1041 using Base = BaseStatement<Derived>;
1042
1044 AdbcStatusCode Init(void* parent, AdbcError* error) override {
1045 RAISE_STATUS(error, impl().InitImpl(parent));
1046 return ObjectBase::Init(parent, error);
1047 }
1048
1050 Status InitImpl(void* parent) { return status::Ok(); }
1051
1054 RAISE_STATUS(error, impl().ReleaseImpl());
1055 return ADBC_STATUS_OK;
1056 }
1057
1058 Status ReleaseImpl() { return status::Ok(); }
1059
1061 AdbcStatusCode SetOption(std::string_view key, Option value,
1062 AdbcError* error) override {
1063 RAISE_STATUS(error, impl().SetOptionImpl(key, value));
1064 return ADBC_STATUS_OK;
1065 }
1066
1068 virtual Status SetOptionImpl(std::string_view key, Option value) {
1069 return status::NotImplemented(Derived::kErrorPrefix, " Unknown statement option ",
1070 key, "=", value.Format());
1071 }
1072
1073 AdbcStatusCode ExecuteQuery(ArrowArrayStream* stream, int64_t* rows_affected,
1074 AdbcError* error) {
1075 int64_t rows_affected_result;
1076 RAISE_RESULT(error, rows_affected_result, impl().ExecuteQueryImpl(stream));
1077 if (rows_affected) {
1078 *rows_affected = rows_affected_result;
1079 }
1080
1081 return ADBC_STATUS_OK;
1082 }
1083
1084 Result<int64_t> ExecuteQueryImpl(ArrowArrayStream* stream) {
1085 return status::NotImplemented("ExecuteQuery");
1086 }
1087
1088 AdbcStatusCode ExecuteSchema(ArrowSchema* schema, AdbcError* error) {
1089 RAISE_STATUS(error, impl().ExecuteSchemaImpl(schema));
1090 return ADBC_STATUS_OK;
1091 }
1092
1093 Status ExecuteSchemaImpl(ArrowSchema* schema) {
1094 return status::NotImplemented("ExecuteSchema");
1095 }
1096
1097 AdbcStatusCode Prepare(AdbcError* error) {
1098 RAISE_STATUS(error, impl().PrepareImpl());
1099 return ADBC_STATUS_OK;
1100 }
1101
1102 Status PrepareImpl() { return status::NotImplemented("Prepare"); }
1103
1104 AdbcStatusCode SetSqlQuery(const char* query, AdbcError* error) {
1105 RAISE_STATUS(error, impl().SetSqlQueryImpl(query));
1106 return ADBC_STATUS_OK;
1107 }
1108
1109 Status SetSqlQueryImpl(std::string_view query) {
1110 return status::NotImplemented("SetSqlQuery");
1111 }
1112
1113 AdbcStatusCode SetSubstraitPlan(const uint8_t* plan, size_t length, AdbcError* error) {
1114 RAISE_STATUS(error, impl().SetSubstraitPlanImpl(std::string_view(
1115 reinterpret_cast<const char*>(plan), length)));
1116 return ADBC_STATUS_OK;
1117 }
1118
1119 Status SetSubstraitPlanImpl(std::string_view plan) {
1120 return status::NotImplemented("SetSubstraitPlan");
1121 }
1122
1123 AdbcStatusCode Bind(ArrowArray* values, ArrowSchema* schema, AdbcError* error) {
1124 RAISE_STATUS(error, impl().BindImpl(values, schema));
1125 return ADBC_STATUS_OK;
1126 }
1127
1128 Status BindImpl(ArrowArray* values, ArrowSchema* schema) {
1129 return status::NotImplemented("Bind");
1130 }
1131
1132 AdbcStatusCode BindStream(ArrowArrayStream* stream, AdbcError* error) {
1133 RAISE_STATUS(error, impl().BindStreamImpl(stream));
1134 return ADBC_STATUS_OK;
1135 }
1136
1137 Status BindStreamImpl(ArrowArrayStream* stream) {
1138 return status::NotImplemented("BindStream");
1139 }
1140
1141 AdbcStatusCode GetParameterSchema(ArrowSchema* schema, AdbcError* error) {
1142 RAISE_STATUS(error, impl().GetParameterSchemaImpl(schema));
1143 return ADBC_STATUS_OK;
1144 }
1145
1146 Status GetParameterSchemaImpl(struct ArrowSchema* schema) {
1147 return status::NotImplemented("GetParameterSchema");
1148 }
1149
1150 AdbcStatusCode ExecutePartitions(ArrowSchema* schema, AdbcPartitions* partitions,
1151 int64_t* rows_affected, AdbcError* error) {
1153 }
1154
1155 AdbcStatusCode Cancel(AdbcError* error) {
1156 RAISE_STATUS(error, impl().Cancel());
1157 return ADBC_STATUS_OK;
1158 }
1159
1160 Status Cancel() { return status::NotImplemented("Cancel"); }
1161
1162 private:
1163 Derived& impl() { return static_cast<Derived&>(*this); }
1164};
1165
1166} // namespace adbc::driver
Definition base_driver.h:842
virtual Status InitImpl(void *parent)
Initialize the database.
Definition base_driver.h:862
AdbcStatusCode SetOption(std::string_view key, Option value, AdbcError *error) override
Set an option value.
Definition base_driver.h:1022
AutocommitState
Whether autocommit is enabled or not (by default: enabled).
Definition base_driver.h:847
AdbcStatusCode Release(AdbcError *error) override
Finalize the object.
Definition base_driver.h:1006
virtual Status SetOptionImpl(std::string_view key, Option value)
Set an option. May be called prior to InitImpl.
Definition base_driver.h:1029
AdbcStatusCode Init(void *parent, AdbcError *error) override
Initialize the object.
Definition base_driver.h:856
AdbcStatusCode Init(void *parent, AdbcError *error) override
Initialize the object.
Definition base_driver.h:807
virtual Status InitImpl()
Initialize the database.
Definition base_driver.h:826
AdbcStatusCode Release(AdbcError *error) override
Finalize the object.
Definition base_driver.h:813
virtual Status SetOptionImpl(std::string_view key, Option value)
Set an option. May be called prior to InitImpl.
Definition base_driver.h:832
AdbcStatusCode SetOption(std::string_view key, Option value, AdbcError *error) override
Set an option value.
Definition base_driver.h:819
virtual Status ReleaseImpl()
Release the database.
Definition base_driver.h:829
Definition base_driver.h:1039
Status InitImpl(void *parent)
Initialize the statement.
Definition base_driver.h:1050
AdbcStatusCode Release(AdbcError *error) override
Finalize the object.
Definition base_driver.h:1053
AdbcStatusCode SetOption(std::string_view key, Option value, AdbcError *error) override
Set an option value.
Definition base_driver.h:1061
AdbcStatusCode Init(void *parent, AdbcError *error) override
Initialize the object.
Definition base_driver.h:1044
virtual Status SetOptionImpl(std::string_view key, Option value)
Set an option. May be called prior to InitImpl.
Definition base_driver.h:1068
Definition base_driver.h:380
Base class for private_data of AdbcDatabase, AdbcConnection, and AdbcStatement.
Definition base_driver.h:269
virtual AdbcStatusCode SetOption(std::string_view key, Option value, AdbcError *error)
Set an option value.
Definition base_driver.h:313
virtual AdbcStatusCode Release(AdbcError *error)
Finalize the object.
Definition base_driver.h:304
virtual AdbcStatusCode Init(void *parent, AdbcError *error)
Initialize the object.
Definition base_driver.h:289
virtual Result< Option > GetOption(std::string_view key)
Get an option value.
Definition base_driver.h:307
A typed option value wrapper. Attempts some conversions between types.
Definition base_driver.h:60
Option(const char *value)
Construct an option from a C string. NULL strings are treated as unset.
Definition base_driver.h:70
Result< std::string_view > AsString() const
Get the value if it is a string.
Definition base_driver.h:128
std::variant< Unset, std::string, std::vector< uint8_t >, int64_t, double > Value
The possible values of an option.
Definition base_driver.h:65
std::string Format() const
Provide a human-readable summary of the value.
Definition base_driver.h:142
Result< int64_t > AsInt() const
Try to parse a string or integer value as an integer.
Definition base_driver.h:101
Result< bool > AsBool() const
Try to parse a string value as a boolean.
Definition base_driver.h:84
bool has_value() const
Check whether this option is set.
Definition base_driver.h:81
A wrapper around a value, or an error.
Definition status.h:202
A wrapper around AdbcStatusCode + AdbcError.
Definition status.h:42
void * private_data
Opaque implementation-defined state. This field is NULLPTR iff the connection is uninitialized/freed.
Definition adbc.h:886
An active database connection.
Definition adbc.h:883
#define ADBC_VERSION_1_0_0
ADBC revision 1.0.0.
Definition adbc.h:416
#define ADBC_VERSION_1_1_0
ADBC revision 1.1.0.
Definition adbc.h:424
#define ADBC_OPTION_VALUE_DISABLED
Canonical option value for disabling an option.
Definition adbc.h:434
#define ADBC_OPTION_VALUE_ENABLED
Canonical option value for enabling an option.
Definition adbc.h:429
void * private_data
Opaque implementation-defined state. This field is NULLPTR iff the connection is uninitialized/freed.
Definition adbc.h:863
An instance of a database.
Definition adbc.h:860
void * private_data
Opaque driver-defined state. This field is NULL if the driver is uninitialized/freed (but it need not...
Definition adbc.h:992
#define ADBC_DRIVER_1_0_0_SIZE
The size of the AdbcDriver structure in ADBC 1.0.0. Drivers written for ADBC 1.1.0 and later should n...
Definition adbc.h:1146
#define ADBC_DRIVER_1_1_0_SIZE
The size of the AdbcDriver structure in ADBC 1.1.0. Drivers written for ADBC 1.1.0 and later should n...
Definition adbc.h:1154
An instance of an initialized database driver.
Definition adbc.h:988
int32_t vendor_code
A vendor-specific error code, if applicable.
Definition adbc.h:288
void * private_data
Opaque implementation-defined state.
Definition adbc.h:308
#define ADBC_ERROR_VENDOR_CODE_PRIVATE_DATA
Inform the driver/driver manager that we are using the extended AdbcError struct from ADBC 1....
Definition adbc.h:271
#define ADBC_STATUS_NOT_IMPLEMENTED
The operation is not implemented or supported.
Definition adbc.h:189
uint8_t AdbcStatusCode
Error codes for operations that may fail.
Definition adbc.h:176
#define ADBC_STATUS_OK
No error.
Definition adbc.h:179
#define ADBC_STATUS_INVALID_STATE
The preconditions for the operation are not met, likely a programming error.
Definition adbc.h:215
A detailed error message for an operation.
Definition adbc.h:283
Extra key-value metadata for an error.
Definition adbc.h:365
The partitions of a distributed/partitioned result set.
Definition adbc.h:949
void * private_data
Opaque implementation-defined state. This field is NULLPTR iff the connection is uninitialized/freed.
Definition adbc.h:924
A container for all state needed to execute a database query, such as the query itself,...
Definition adbc.h:921
#define RAISE_RESULT(ERROR, LHS, RHS)
A helper to unwrap a Result in functions returning AdbcStatusCode.
Definition status.h:285
#define RAISE_STATUS(ERROR, RHS)
A helper to unwrap a Status in functions returning AdbcStatusCode.
Definition status.h:289
The option is unset.
Definition base_driver.h:63
Helper for below: given the ADBC type, pick the right driver type.
Definition base_driver.h:356