You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by li...@apache.org on 2022/06/09 14:56:41 UTC

[arrow-adbc] branch main updated: Fix build for ld.bfd (#10)

This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new fc17ed0  Fix build for ld.bfd (#10)
fc17ed0 is described below

commit fc17ed0802340b4768521a19e0b4136b3592a56d
Author: David Li <li...@gmail.com>
AuthorDate: Thu Jun 9 10:56:37 2022 -0400

    Fix build for ld.bfd (#10)
    
    The driver manager and drivers define the same symbols.  Normally,
    this means that if the driver manager loads a driver, and then the
    driver attempts to resolve ADBC functions (e.g. to populate the
    driver function pointer table), the dynamic linker will actually
    resolve the driver manager's symbols, which is a problem.
    
    Previously, we used __attribute__(visibility("protected")).  But
    it turns out ld.bfd doesn't like this, complaining about an invalid
    relocation (ld.mold worked fine).  The driver manager could use
    RTLD_DEEPBIND, but this doesn't work with ASan.  We could also try
    -Bsymbolic(-functions) too, but this is additional work for the
    build process.  So instead, just take the tedious-but-easy route
    and define each symbol twice.
---
 drivers/flight_sql/CMakeLists.txt |   6 +-
 drivers/flight_sql/flight_sql.cc  | 214 ++++++++++++++++++++--------
 drivers/sqlite/sqlite.cc          | 293 ++++++++++++++++++++++++++------------
 drivers/util.cc                   |  59 --------
 drivers/util.h                    |  18 +--
 5 files changed, 364 insertions(+), 226 deletions(-)

diff --git a/drivers/flight_sql/CMakeLists.txt b/drivers/flight_sql/CMakeLists.txt
index fd1314b..9cc03ba 100644
--- a/drivers/flight_sql/CMakeLists.txt
+++ b/drivers/flight_sql/CMakeLists.txt
@@ -34,10 +34,10 @@ find_package(ArrowFlightSql REQUIRED HINTS ${ARROW_CONFIG_PATH})
 add_arrow_lib(adbc_driver_flight_sql
               SOURCES
               flight_sql.cc
-              ../util.cc
               SHARED_LINK_LIBS
-              arrow_shared
-              arrow_flight_sql_shared)
+              arrow_flight_sql_shared
+              arrow_flight_shared
+              arrow_shared)
 include_directories(SYSTEM ${REPOSITORY_ROOT})
 
 if(ARROW_TEST_LINKAGE STREQUAL "shared")
diff --git a/drivers/flight_sql/flight_sql.cc b/drivers/flight_sql/flight_sql.cc
index 66226e6..c090ec0 100644
--- a/drivers/flight_sql/flight_sql.cc
+++ b/drivers/flight_sql/flight_sql.cc
@@ -346,35 +346,31 @@ class FlightSqlStatementImpl : public arrow::RecordBatchReader {
   std::unique_ptr<flight::FlightStreamReader> current_stream_;
 };
 
-}  // namespace
-
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseNew(struct AdbcDatabase* database, struct AdbcError* error) {
+AdbcStatusCode FlightSqlDatabaseNew(struct AdbcDatabase* database,
+                                    struct AdbcError* error) {
   auto impl = std::make_shared<FlightSqlDatabaseImpl>();
   database->private_data = new std::shared_ptr<FlightSqlDatabaseImpl>(impl);
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char* key,
-                                     const char* value, struct AdbcError* error) {
+AdbcStatusCode FlightSqlDatabaseSetOption(struct AdbcDatabase* database, const char* key,
+                                          const char* value, struct AdbcError* error) {
   if (!database || !database->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlDatabaseImpl>*>(database->private_data);
   return (*ptr)->SetOption(key, value, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* error) {
+AdbcStatusCode FlightSqlDatabaseInit(struct AdbcDatabase* database,
+                                     struct AdbcError* error) {
   if (!database->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlDatabaseImpl>*>(database->private_data);
   return (*ptr)->Init(error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseRelease(struct AdbcDatabase* database,
-                                   struct AdbcError* error) {
+AdbcStatusCode FlightSqlDatabaseRelease(struct AdbcDatabase* database,
+                                        struct AdbcError* error) {
   if (!database->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlDatabaseImpl>*>(database->private_data);
@@ -384,32 +380,27 @@ AdbcStatusCode AdbcDatabaseRelease(struct AdbcDatabase* database,
   return status;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionDeserializePartitionDesc(struct AdbcConnection* connection,
-                                                      const uint8_t* serialized_partition,
-                                                      size_t serialized_length,
-                                                      struct AdbcStatement* statement,
-                                                      struct AdbcError* error) {
+AdbcStatusCode FlightSqlConnectionDeserializePartitionDesc(
+    struct AdbcConnection* connection, const uint8_t* serialized_partition,
+    size_t serialized_length, struct AdbcStatement* statement, struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
   return (*ptr)->DeserializePartitionDesc(serialized_partition, serialized_length, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionGetTableTypes(struct AdbcConnection* connection,
-                                           struct AdbcStatement* statement,
-                                           struct AdbcError* error) {
+AdbcStatusCode FlightSqlConnectionGetTableTypes(struct AdbcConnection* connection,
+                                                struct AdbcStatement* statement,
+                                                struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
   return (*ptr)->GetTableTypes(error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionNew(struct AdbcDatabase* database,
-                                 struct AdbcConnection* connection,
-                                 struct AdbcError* error) {
+AdbcStatusCode FlightSqlConnectionNew(struct AdbcDatabase* database,
+                                      struct AdbcConnection* connection,
+                                      struct AdbcError* error) {
   auto ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlDatabaseImpl>*>(database->private_data);
   auto impl = std::make_shared<FlightSqlConnectionImpl>(*ptr);
@@ -417,24 +408,22 @@ AdbcStatusCode AdbcConnectionNew(struct AdbcDatabase* database,
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection* connection, const char* key,
-                                       const char* value, struct AdbcError* error) {
+AdbcStatusCode FlightSqlConnectionSetOption(struct AdbcConnection* connection,
+                                            const char* key, const char* value,
+                                            struct AdbcError* error) {
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection,
-                                  struct AdbcError* error) {
+AdbcStatusCode FlightSqlConnectionInit(struct AdbcConnection* connection,
+                                       struct AdbcError* error) {
   if (!connection->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr = reinterpret_cast<std::shared_ptr<FlightSqlConnectionImpl>*>(
       connection->private_data);
   return (*ptr)->Init(error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
-                                     struct AdbcError* error) {
+AdbcStatusCode FlightSqlConnectionRelease(struct AdbcConnection* connection,
+                                          struct AdbcError* error) {
   if (!connection->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr = reinterpret_cast<std::shared_ptr<FlightSqlConnectionImpl>*>(
       connection->private_data);
@@ -444,49 +433,44 @@ AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
   return status;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementExecute(struct AdbcStatement* statement,
-                                    struct AdbcError* error) {
+AdbcStatusCode FlightSqlStatementExecute(struct AdbcStatement* statement,
+                                         struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
   return (*ptr)->Execute(*ptr, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementGetPartitionDesc(struct AdbcStatement* statement,
-                                             uint8_t* partition_desc,
-                                             struct AdbcError* error) {
+AdbcStatusCode FlightSqlStatementGetPartitionDesc(struct AdbcStatement* statement,
+                                                  uint8_t* partition_desc,
+                                                  struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
   return (*ptr)->GetPartitionDesc(partition_desc, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementGetPartitionDescSize(struct AdbcStatement* statement,
-                                                 size_t* length,
-                                                 struct AdbcError* error) {
+AdbcStatusCode FlightSqlStatementGetPartitionDescSize(struct AdbcStatement* statement,
+                                                      size_t* length,
+                                                      struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
   return (*ptr)->GetPartitionDescSize(length, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementGetStream(struct AdbcStatement* statement,
-                                      struct ArrowArrayStream* out,
-                                      struct AdbcError* error) {
+AdbcStatusCode FlightSqlStatementGetStream(struct AdbcStatement* statement,
+                                           struct ArrowArrayStream* out,
+                                           struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
   return (*ptr)->GetStream(*ptr, out, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementNew(struct AdbcConnection* connection,
-                                struct AdbcStatement* statement,
-                                struct AdbcError* error) {
+AdbcStatusCode FlightSqlStatementNew(struct AdbcConnection* connection,
+                                     struct AdbcStatement* statement,
+                                     struct AdbcError* error) {
   auto* ptr = reinterpret_cast<std::shared_ptr<FlightSqlConnectionImpl>*>(
       connection->private_data);
   auto impl = std::make_shared<FlightSqlStatementImpl>(*ptr);
@@ -494,9 +478,8 @@ AdbcStatusCode AdbcStatementNew(struct AdbcConnection* connection,
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
-                                    struct AdbcError* error) {
+AdbcStatusCode FlightSqlStatementRelease(struct AdbcStatement* statement,
+                                         struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
@@ -506,15 +489,126 @@ AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
   return status;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementSetSqlQuery(struct AdbcStatement* statement,
-                                        const char* query, struct AdbcError* error) {
+AdbcStatusCode FlightSqlStatementSetSqlQuery(struct AdbcStatement* statement,
+                                             const char* query, struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<FlightSqlStatementImpl>*>(statement->private_data);
   return (*ptr)->SetSqlQuery(*ptr, query, error);
 }
 
+}  // namespace
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* error) {
+  return FlightSqlDatabaseInit(database, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseNew(struct AdbcDatabase* database, struct AdbcError* error) {
+  return FlightSqlDatabaseNew(database, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char* key,
+                                     const char* value, struct AdbcError* error) {
+  return FlightSqlDatabaseSetOption(database, key, value, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseRelease(struct AdbcDatabase* database,
+                                   struct AdbcError* error) {
+  return FlightSqlDatabaseRelease(database, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionDeserializePartitionDesc(struct AdbcConnection* connection,
+                                                      const uint8_t* serialized_partition,
+                                                      size_t serialized_length,
+                                                      struct AdbcStatement* statement,
+                                                      struct AdbcError* error) {
+  return FlightSqlConnectionDeserializePartitionDesc(connection, serialized_partition,
+                                                     serialized_length, statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionGetTableTypes(struct AdbcConnection* connection,
+                                           struct AdbcStatement* statement,
+                                           struct AdbcError* error) {
+  return FlightSqlConnectionGetTableTypes(connection, statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection,
+                                  struct AdbcError* error) {
+  return FlightSqlConnectionInit(connection, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionNew(struct AdbcDatabase* database,
+                                 struct AdbcConnection* connection,
+                                 struct AdbcError* error) {
+  return FlightSqlConnectionNew(database, connection, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection* connection, const char* key,
+                                       const char* value, struct AdbcError* error) {
+  return FlightSqlConnectionSetOption(connection, key, value, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
+                                     struct AdbcError* error) {
+  return FlightSqlConnectionRelease(connection, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementExecute(struct AdbcStatement* statement,
+                                    struct AdbcError* error) {
+  return FlightSqlStatementExecute(statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementGetPartitionDesc(struct AdbcStatement* statement,
+                                             uint8_t* partition_desc,
+                                             struct AdbcError* error) {
+  return FlightSqlStatementGetPartitionDesc(statement, partition_desc, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementGetPartitionDescSize(struct AdbcStatement* statement,
+                                                 size_t* length,
+                                                 struct AdbcError* error) {
+  return FlightSqlStatementGetPartitionDescSize(statement, length, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementGetStream(struct AdbcStatement* statement,
+                                      struct ArrowArrayStream* out,
+                                      struct AdbcError* error) {
+  return FlightSqlStatementGetStream(statement, out, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementNew(struct AdbcConnection* connection,
+                                struct AdbcStatement* statement,
+                                struct AdbcError* error) {
+  return FlightSqlStatementNew(connection, statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
+                                    struct AdbcError* error) {
+  return FlightSqlStatementRelease(statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementSetSqlQuery(struct AdbcStatement* statement,
+                                        const char* query, struct AdbcError* error) {
+  return FlightSqlStatementSetSqlQuery(statement, query, error);
+}
+
 extern "C" {
 ARROW_EXPORT
 AdbcStatusCode AdbcFlightSqlDriverInit(size_t count, struct AdbcDriver* driver,
diff --git a/drivers/sqlite/sqlite.cc b/drivers/sqlite/sqlite.cc
index 0f5a99e..e141fa6 100644
--- a/drivers/sqlite/sqlite.cc
+++ b/drivers/sqlite/sqlite.cc
@@ -601,35 +601,45 @@ class SqliteStatementImpl : public arrow::RecordBatchReader {
   bool done_;
 };
 
-}  // namespace
+// ADBC interface implementation - as private functions so that these
+// don't get replaced by the dynamic linker. If we implemented these
+// under the Adbc* names, then DriverInit, the linker may resolve
+// functions to the address of the functions provided by the driver
+// manager instead of our functions.
+//
+// We could also:
+// - Play games with RTLD_DEEPBIND - but this doesn't work with ASan
+// - Use __attribute__((visibility("protected"))) - but this is
+//   apparently poorly supported by some linkers
+// - Play with -Bsymbolic(-functions) - but this has other
+//   consequences and complicates the build setup
+//
+// So in the end some manual effort here was chosen.
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseNew(struct AdbcDatabase* database, struct AdbcError* error) {
+AdbcStatusCode SqliteDatabaseNew(struct AdbcDatabase* database, struct AdbcError* error) {
   auto impl = std::make_shared<SqliteDatabaseImpl>();
   database->private_data = new std::shared_ptr<SqliteDatabaseImpl>(impl);
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char* key,
-                                     const char* value, struct AdbcError* error) {
-  if (!database || !database->private_data) return ADBC_STATUS_UNINITIALIZED;
+AdbcStatusCode SqliteDatabaseInit(struct AdbcDatabase* database,
+                                  struct AdbcError* error) {
+  if (!database->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<SqliteDatabaseImpl>*>(database->private_data);
-  return (*ptr)->SetOption(key, value, error);
+  return (*ptr)->Init(error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* error) {
-  if (!database->private_data) return ADBC_STATUS_UNINITIALIZED;
+AdbcStatusCode SqliteDatabaseSetOption(struct AdbcDatabase* database, const char* key,
+                                       const char* value, struct AdbcError* error) {
+  if (!database || !database->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<SqliteDatabaseImpl>*>(database->private_data);
-  return (*ptr)->Init(error);
+  return (*ptr)->SetOption(key, value, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcDatabaseRelease(struct AdbcDatabase* database,
-                                   struct AdbcError* error) {
+AdbcStatusCode SqliteDatabaseRelease(struct AdbcDatabase* database,
+                                     struct AdbcError* error) {
   if (!database->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<SqliteDatabaseImpl>*>(database->private_data);
@@ -639,10 +649,9 @@ AdbcStatusCode AdbcDatabaseRelease(struct AdbcDatabase* database,
   return status;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionNew(struct AdbcDatabase* database,
-                                 struct AdbcConnection* connection,
-                                 struct AdbcError* error) {
+AdbcStatusCode SqliteConnectionNew(struct AdbcDatabase* database,
+                                   struct AdbcConnection* connection,
+                                   struct AdbcError* error) {
   auto ptr =
       reinterpret_cast<std::shared_ptr<SqliteDatabaseImpl>*>(database->private_data);
   auto impl = std::make_shared<SqliteConnectionImpl>(*ptr);
@@ -650,24 +659,22 @@ AdbcStatusCode AdbcConnectionNew(struct AdbcDatabase* database,
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection* connection, const char* key,
-                                       const char* value, struct AdbcError* error) {
+AdbcStatusCode SqliteConnectionSetOption(struct AdbcConnection* connection,
+                                         const char* key, const char* value,
+                                         struct AdbcError* error) {
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection,
-                                  struct AdbcError* error) {
+AdbcStatusCode SqliteConnectionInit(struct AdbcConnection* connection,
+                                    struct AdbcError* error) {
   if (!connection->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<SqliteConnectionImpl>*>(connection->private_data);
   return (*ptr)->Init(error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
-                                     struct AdbcError* error) {
+AdbcStatusCode SqliteConnectionRelease(struct AdbcConnection* connection,
+                                       struct AdbcError* error) {
   if (!connection->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto ptr =
       reinterpret_cast<std::shared_ptr<SqliteConnectionImpl>*>(connection->private_data);
@@ -677,63 +684,56 @@ AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
   return status;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementBind(struct AdbcStatement* statement,
-                                 struct ArrowArray* values, struct ArrowSchema* schema,
-                                 struct AdbcError* error) {
+AdbcStatusCode SqliteStatementBind(struct AdbcStatement* statement,
+                                   struct ArrowArray* values, struct ArrowSchema* schema,
+                                   struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<SqliteStatementImpl>*>(statement->private_data);
   return (*ptr)->Bind(*ptr, values, schema, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementBindStream(struct AdbcStatement* statement,
-                                       struct ArrowArrayStream* stream,
-                                       struct AdbcError* error) {
+AdbcStatusCode SqliteStatementBindStream(struct AdbcStatement* statement,
+                                         struct ArrowArrayStream* stream,
+                                         struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<SqliteStatementImpl>*>(statement->private_data);
   return (*ptr)->Bind(*ptr, stream, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementExecute(struct AdbcStatement* statement,
-                                    struct AdbcError* error) {
+AdbcStatusCode SqliteStatementExecute(struct AdbcStatement* statement,
+                                      struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<SqliteStatementImpl>*>(statement->private_data);
   return (*ptr)->Execute(*ptr, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementGetPartitionDesc(struct AdbcStatement* statement,
-                                             uint8_t* partition_desc,
-                                             struct AdbcError* error) {
+AdbcStatusCode SqliteStatementGetPartitionDesc(struct AdbcStatement* statement,
+                                               uint8_t* partition_desc,
+                                               struct AdbcError* error) {
   return ADBC_STATUS_NOT_IMPLEMENTED;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementGetPartitionDescSize(struct AdbcStatement* statement,
-                                                 size_t* length,
-                                                 struct AdbcError* error) {
+AdbcStatusCode SqliteStatementGetPartitionDescSize(struct AdbcStatement* statement,
+                                                   size_t* length,
+                                                   struct AdbcError* error) {
   return ADBC_STATUS_NOT_IMPLEMENTED;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementGetStream(struct AdbcStatement* statement,
-                                      struct ArrowArrayStream* out,
-                                      struct AdbcError* error) {
+AdbcStatusCode SqliteStatementGetStream(struct AdbcStatement* statement,
+                                        struct ArrowArrayStream* out,
+                                        struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<SqliteStatementImpl>*>(statement->private_data);
   return (*ptr)->GetStream(*ptr, out, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementNew(struct AdbcConnection* connection,
-                                struct AdbcStatement* statement,
-                                struct AdbcError* error) {
+AdbcStatusCode SqliteStatementNew(struct AdbcConnection* connection,
+                                  struct AdbcStatement* statement,
+                                  struct AdbcError* error) {
   auto conn_ptr =
       reinterpret_cast<std::shared_ptr<SqliteConnectionImpl>*>(connection->private_data);
   auto impl = std::make_shared<SqliteStatementImpl>(*conn_ptr);
@@ -741,17 +741,15 @@ AdbcStatusCode AdbcStatementNew(struct AdbcConnection* connection,
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementPrepare(struct AdbcStatement* statement,
-                                    struct AdbcError* error) {
+AdbcStatusCode SqliteStatementPrepare(struct AdbcStatement* statement,
+                                      struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   // No-op
   return ADBC_STATUS_OK;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
-                                    struct AdbcError* error) {
+AdbcStatusCode SqliteStatementRelease(struct AdbcStatement* statement,
+                                      struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<SqliteStatementImpl>*>(statement->private_data);
@@ -761,24 +759,143 @@ AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
   return status;
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementSetOption(struct AdbcStatement* statement, const char* key,
-                                      const char* value, struct AdbcError* error) {
+AdbcStatusCode SqliteStatementSetOption(struct AdbcStatement* statement, const char* key,
+                                        const char* value, struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<SqliteStatementImpl>*>(statement->private_data);
   return (*ptr)->SetOption(*ptr, key, value, error);
 }
 
-ADBC_DRIVER_EXPORT
-AdbcStatusCode AdbcStatementSetSqlQuery(struct AdbcStatement* statement,
-                                        const char* query, struct AdbcError* error) {
+AdbcStatusCode SqliteStatementSetSqlQuery(struct AdbcStatement* statement,
+                                          const char* query, struct AdbcError* error) {
   if (!statement->private_data) return ADBC_STATUS_UNINITIALIZED;
   auto* ptr =
       reinterpret_cast<std::shared_ptr<SqliteStatementImpl>*>(statement->private_data);
   return (*ptr)->SetSqlQuery(*ptr, query, error);
 }
 
+}  // namespace
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* error) {
+  return SqliteDatabaseInit(database, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseNew(struct AdbcDatabase* database, struct AdbcError* error) {
+  return SqliteDatabaseNew(database, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char* key,
+                                     const char* value, struct AdbcError* error) {
+  return SqliteDatabaseSetOption(database, key, value, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcDatabaseRelease(struct AdbcDatabase* database,
+                                   struct AdbcError* error) {
+  return SqliteDatabaseRelease(database, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionNew(struct AdbcDatabase* database,
+                                 struct AdbcConnection* connection,
+                                 struct AdbcError* error) {
+  return SqliteConnectionNew(database, connection, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection* connection, const char* key,
+                                       const char* value, struct AdbcError* error) {
+  return SqliteConnectionSetOption(connection, key, value, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection,
+                                  struct AdbcError* error) {
+  return SqliteConnectionInit(connection, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection* connection,
+                                     struct AdbcError* error) {
+  return SqliteConnectionRelease(connection, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementBind(struct AdbcStatement* statement,
+                                 struct ArrowArray* values, struct ArrowSchema* schema,
+                                 struct AdbcError* error) {
+  return SqliteStatementBind(statement, values, schema, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementBindStream(struct AdbcStatement* statement,
+                                       struct ArrowArrayStream* stream,
+                                       struct AdbcError* error) {
+  return SqliteStatementBindStream(statement, stream, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementExecute(struct AdbcStatement* statement,
+                                    struct AdbcError* error) {
+  return SqliteStatementExecute(statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementGetPartitionDesc(struct AdbcStatement* statement,
+                                             uint8_t* partition_desc,
+                                             struct AdbcError* error) {
+  return SqliteStatementGetPartitionDesc(statement, partition_desc, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementGetPartitionDescSize(struct AdbcStatement* statement,
+                                                 size_t* length,
+                                                 struct AdbcError* error) {
+  return SqliteStatementGetPartitionDescSize(statement, length, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementGetStream(struct AdbcStatement* statement,
+                                      struct ArrowArrayStream* out,
+                                      struct AdbcError* error) {
+  return SqliteStatementGetStream(statement, out, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementNew(struct AdbcConnection* connection,
+                                struct AdbcStatement* statement,
+                                struct AdbcError* error) {
+  return SqliteStatementNew(connection, statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementPrepare(struct AdbcStatement* statement,
+                                    struct AdbcError* error) {
+  return SqliteStatementPrepare(statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementRelease(struct AdbcStatement* statement,
+                                    struct AdbcError* error) {
+  return SqliteStatementRelease(statement, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementSetOption(struct AdbcStatement* statement, const char* key,
+                                      const char* value, struct AdbcError* error) {
+  return SqliteStatementSetOption(statement, key, value, error);
+}
+
+ADBC_DRIVER_EXPORT
+AdbcStatusCode AdbcStatementSetSqlQuery(struct AdbcStatement* statement,
+                                        const char* query, struct AdbcError* error) {
+  return SqliteStatementSetSqlQuery(statement, query, error);
+}
+
 extern "C" {
 ARROW_EXPORT
 AdbcStatusCode AdbcSqliteDriverInit(size_t count, struct AdbcDriver* driver,
@@ -786,27 +903,27 @@ AdbcStatusCode AdbcSqliteDriverInit(size_t count, struct AdbcDriver* driver,
   if (count < ADBC_VERSION_0_0_1) return ADBC_STATUS_NOT_IMPLEMENTED;
 
   std::memset(driver, 0, sizeof(*driver));
-  driver->DatabaseInit = AdbcDatabaseInit;
-  driver->DatabaseNew = AdbcDatabaseNew;
-  driver->DatabaseRelease = AdbcDatabaseRelease;
-  driver->DatabaseSetOption = AdbcDatabaseSetOption;
-
-  driver->ConnectionInit = AdbcConnectionInit;
-  driver->ConnectionNew = AdbcConnectionNew;
-  driver->ConnectionRelease = AdbcConnectionRelease;
-  driver->ConnectionSetOption = AdbcConnectionSetOption;
-
-  driver->StatementBind = AdbcStatementBind;
-  driver->StatementBindStream = AdbcStatementBindStream;
-  driver->StatementExecute = AdbcStatementExecute;
-  driver->StatementGetPartitionDesc = AdbcStatementGetPartitionDesc;
-  driver->StatementGetPartitionDescSize = AdbcStatementGetPartitionDescSize;
-  driver->StatementGetStream = AdbcStatementGetStream;
-  driver->StatementNew = AdbcStatementNew;
-  driver->StatementPrepare = AdbcStatementPrepare;
-  driver->StatementRelease = AdbcStatementRelease;
-  driver->StatementSetOption = AdbcStatementSetOption;
-  driver->StatementSetSqlQuery = AdbcStatementSetSqlQuery;
+  driver->DatabaseInit = SqliteDatabaseInit;
+  driver->DatabaseNew = SqliteDatabaseNew;
+  driver->DatabaseRelease = SqliteDatabaseRelease;
+  driver->DatabaseSetOption = SqliteDatabaseSetOption;
+
+  driver->ConnectionInit = SqliteConnectionInit;
+  driver->ConnectionNew = SqliteConnectionNew;
+  driver->ConnectionRelease = SqliteConnectionRelease;
+  driver->ConnectionSetOption = SqliteConnectionSetOption;
+
+  driver->StatementBind = SqliteStatementBind;
+  driver->StatementBindStream = SqliteStatementBindStream;
+  driver->StatementExecute = SqliteStatementExecute;
+  driver->StatementGetPartitionDesc = SqliteStatementGetPartitionDesc;
+  driver->StatementGetPartitionDescSize = SqliteStatementGetPartitionDescSize;
+  driver->StatementGetStream = SqliteStatementGetStream;
+  driver->StatementNew = SqliteStatementNew;
+  driver->StatementPrepare = SqliteStatementPrepare;
+  driver->StatementRelease = SqliteStatementRelease;
+  driver->StatementSetOption = SqliteStatementSetOption;
+  driver->StatementSetSqlQuery = SqliteStatementSetSqlQuery;
   *initialized = ADBC_VERSION_0_0_1;
   return ADBC_STATUS_OK;
 }
diff --git a/drivers/util.cc b/drivers/util.cc
deleted file mode 100644
index dfdea3d..0000000
--- a/drivers/util.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#include "drivers/util.h"
-#include <arrow/status.h>
-#include <arrow/util/string_view.h>
-
-namespace adbc {
-
-using arrow::util::string_view;
-
-arrow::Result<std::unordered_map<std::string, std::string>> ParseConnectionString(
-    string_view target) {
-  // TODO: this does not properly implement the ODBC connection string format.
-  std::unordered_map<std::string, std::string> option_pairs;
-  string_view cur(target);
-
-  while (true) {
-    auto divider = cur.find_first_of('=');
-    if (divider == string_view::npos) {
-      if (!cur.empty()) {
-        return arrow::Status::Invalid("Trailing characters: ", cur);
-      }
-      break;
-    }
-    string_view key = cur.substr(0, divider);
-    cur = cur.substr(divider + 1);
-    auto end = cur.find_first_of(';');
-    string_view value;
-    if (end == string_view::npos) {
-      value = cur;
-      cur = string_view();
-    } else {
-      value = cur.substr(0, end);
-      cur = cur.substr(end + 1);
-    }
-
-    if (!option_pairs.insert({std::string(key), std::string(value)}).second) {
-      return arrow::Status::Invalid("Duplicate option: ", key);
-    }
-  }
-  return option_pairs;
-}
-
-}  // namespace adbc
diff --git a/drivers/util.h b/drivers/util.h
index df49f9f..da998a0 100644
--- a/drivers/util.h
+++ b/drivers/util.h
@@ -21,15 +21,9 @@
 #include "arrow/result.h"
 #include "arrow/util/string_view.h"
 
-// XXX: We want to export Adbc* functions, but inside
-// AdbcSqliteDriverInit, we want to always point to the local
-// function, not the global function (so we can cooperate with the
-// driver manager). "protected" visibility gives us this.
-// RTLD_DEEPBIND also works but is glibc-specific and does not work
-// with AddressSanitizer.
-// TODO: should this go in adbc.h instead?
+// TODO: dllimport/dllexport for Windows. Should that go in adbc.h instead?
 #ifdef __linux__
-#define ADBC_DRIVER_EXPORT __attribute__((visibility("protected")))
+#define ADBC_DRIVER_EXPORT
 #else
 #define ADBC_DRIVER_EXPORT
 #endif  // ifdef __linux__
@@ -39,11 +33,3 @@
     auto _s = (expr);                    \
     if (_s != ADBC_STATUS_OK) return _s; \
   } while (false)
-
-namespace adbc {
-
-/// \brief Parse a connection string.
-arrow::Result<std::unordered_map<std::string, std::string>> ParseConnectionString(
-    arrow::util::string_view target);
-
-}  // namespace adbc