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