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