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 7d5f1f005 docs: describe how drivers/driver manager relate (#1655)
7d5f1f005 is described below
commit 7d5f1f0056f7fa94a545ff760aa900839b59d212
Author: David Li <[email protected]>
AuthorDate: Tue Mar 26 17:23:26 2024 -0400
docs: describe how drivers/driver manager relate (#1655)
Fixes #1651.
---
docs/mermaid.makefile | 8 +-
docs/source/_static/css/custom.css | 11 ++
docs/source/faq.rst | 11 ++
docs/source/format/DriverAlias.mmd | 32 +++++
docs/source/format/DriverAlias.mmd.svg | 19 +++
docs/source/format/DriverDirectLink.mmd | 29 ++++
docs/source/format/DriverDirectLink.mmd.svg | 19 +++
docs/source/format/DriverManagerUse.mmd | 53 +++++++
docs/source/format/DriverManagerUse.mmd.svg | 19 +++
docs/source/format/DriverTableLoad.mmd | 46 +++++++
docs/source/format/DriverTableLoad.mmd.svg | 19 +++
docs/source/format/DriverTableUse.mmd | 45 ++++++
docs/source/format/DriverTableUse.mmd.svg | 19 +++
docs/source/format/how_manager.rst | 207 ++++++++++++++++++++++++++++
docs/source/index.rst | 1 +
15 files changed, 537 insertions(+), 1 deletion(-)
diff --git a/docs/mermaid.makefile b/docs/mermaid.makefile
index 9b46cf35e..cf967f5d7 100644
--- a/docs/mermaid.makefile
+++ b/docs/mermaid.makefile
@@ -18,6 +18,9 @@
# Generate Mermaid diagrams statically. Sphinx has a mermaid
# extension, but this causes issues with the page shifting during
# load.
+# First: npm install -g @mermaid-js/mermaid-cli
+# (if you are using Conda, this will not be "global" but rather install to
+# your Conda prefix)
# Use as: make -f mermaid.makefile -j all
MERMAID := $(shell find source/ -type f -name '*.mmd')
@@ -27,7 +30,10 @@ define LICENSE
endef
%.mmd.svg : %.mmd
- mmdc --input $< --output $@
+# XXX: mermaid doesn't properly handle comments in all layouts (the parser is
+# written entirely from scratch each time, it looks like), so strip them
+# manually
+ grep -E -v "^%" $< | mmdc --input - --output $@
# Prepend the license header
mv $@ [email protected]
echo "<!--" >> $@
diff --git a/docs/source/_static/css/custom.css
b/docs/source/_static/css/custom.css
index e463f97f9..acfd176c6 100644
--- a/docs/source/_static/css/custom.css
+++ b/docs/source/_static/css/custom.css
@@ -24,3 +24,14 @@ p.admonition-title {
display: block;
margin: 0 auto;
}
+
+figcaption {
+ font-style: italic;
+ margin: 0 auto;
+ text-wrap: balance;
+ width: 90%;
+}
+
+h1, h2, h3, h4 {
+ text-wrap: balance;
+}
diff --git a/docs/source/faq.rst b/docs/source/faq.rst
index 9e315be0c..d755ec08f 100644
--- a/docs/source/faq.rst
+++ b/docs/source/faq.rst
@@ -146,6 +146,17 @@ JDBC driver in a bespoke Arrow-based API.
.. _arrow-jdbc:
https://central.sonatype.com/artifact/org.apache.arrow/arrow-jdbc/11.0.0
.. _Turbodbc: https://turbodbc.readthedocs.io/en/latest/
+What is the ADBC driver manager?
+================================
+
+The driver manager (in C/C++) is a library that implements the driver API but
+dynamically loads and manages multiple drivers behind the scenes. It allows
+applications to link to a single library but use more than one driver at a
+time. This avoids symbol conflicts between multiple drivers that would
+otherwise all provide the same ADBC APIs under the same names.
+
+For an in-depth look, see :doc:`format/how_manager`.
+
What is the ADBC SQL dialect?
=============================
diff --git a/docs/source/format/DriverAlias.mmd
b/docs/source/format/DriverAlias.mmd
new file mode 100644
index 000000000..12cbf63f2
--- /dev/null
+++ b/docs/source/format/DriverAlias.mmd
@@ -0,0 +1,32 @@
+%% 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.
+
+block-beta
+ columns 3
+ app["<b>Application</b>"]:3
+
+ space:3
+
+ driver["<b>Driver</b>"]:3
+ AdbcStatementExecuteQuery
+ AdbcStatementSetSqlQuery
+ ...
+ SqliteStatementExecuteQuery
+ SqliteStatementSetSqlQuery
+ ...
+
+ app --> SqliteStatementExecuteQuery
diff --git a/docs/source/format/DriverAlias.mmd.svg
b/docs/source/format/DriverAlias.mmd.svg
new file mode 100644
index 000000000..5c270b121
--- /dev/null
+++ b/docs/source/format/DriverAlias.mmd.svg
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<svg aria-roledescription="block" role="graphics-document document"
viewBox="-5 -87.25 695.0234375 174.5" style="max-width: 695.023px;
background-color: white;" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg" width="100%"
id="my-svg"><style>#my-svg{font-family:"trebuchet
ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#my-svg
.error-icon{fill:#552222;}#my-svg
.error-text{fill:#552222;stroke:#552222;}#my-svg
.edge-thickness-normal{stroke-width:2px;}#my [...]
diff --git a/docs/source/format/DriverDirectLink.mmd
b/docs/source/format/DriverDirectLink.mmd
new file mode 100644
index 000000000..7a9974fab
--- /dev/null
+++ b/docs/source/format/DriverDirectLink.mmd
@@ -0,0 +1,29 @@
+%% 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.
+
+block-beta
+ columns 3
+ app["<b>Application</b>"]:3
+
+ space:3
+
+ driver["<b>Driver</b>"]:3
+ AdbcStatementExecuteQuery
+ AdbcStatementSetSqlQuery
+ ...
+
+ app --> AdbcStatementExecuteQuery
diff --git a/docs/source/format/DriverDirectLink.mmd.svg
b/docs/source/format/DriverDirectLink.mmd.svg
new file mode 100644
index 000000000..c5471a022
--- /dev/null
+++ b/docs/source/format/DriverDirectLink.mmd.svg
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<svg aria-roledescription="block" role="graphics-document document"
viewBox="-5 -70 677.703125 140" style="max-width: 677.703px; background-color:
white;" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg" width="100%"
id="my-svg"><style>#my-svg{font-family:"trebuchet
ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#my-svg
.error-icon{fill:#552222;}#my-svg
.error-text{fill:#552222;stroke:#552222;}#my-svg
.edge-thickness-normal{stroke-width:2px;}#my-svg . [...]
diff --git a/docs/source/format/DriverManagerUse.mmd
b/docs/source/format/DriverManagerUse.mmd
new file mode 100644
index 000000000..c0abc7adc
--- /dev/null
+++ b/docs/source/format/DriverManagerUse.mmd
@@ -0,0 +1,53 @@
+%% 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.
+
+block-beta
+ columns 3
+ app["<b>Application</b>"]:3
+
+ space:3
+
+ drivermanager["<b>ADBC Driver Manager</b>"]:3
+
+ space
+ dm_execute_query["AdbcStatementExecuteQuery"]
+ dm_ellipsis["..."]
+
+ space:3
+
+ space
+
+ AdbcDriver["<b>struct AdbcDriver</b>"]:2
+
+ space
+
+ execute_query
+ ellipsis["..."]
+
+ space:3
+
+ driver["<b>Driver</b>"]:3
+ AdbcDriverInit
+ AdbcStatementExecuteQuery
+ ...
+ space
+ SqliteStatementExecuteQuery
+ ellipsis2["..."]
+
+ app --> dm_execute_query
+ dm_execute_query --> execute_query
+ execute_query --> SqliteStatementExecuteQuery
diff --git a/docs/source/format/DriverManagerUse.mmd.svg
b/docs/source/format/DriverManagerUse.mmd.svg
new file mode 100644
index 000000000..c658cf2b1
--- /dev/null
+++ b/docs/source/format/DriverManagerUse.mmd.svg
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<svg aria-roledescription="block" role="graphics-document document"
viewBox="-5 -190.75 695.0234375 381.5" style="max-width: 695.023px;
background-color: white;" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg" width="100%"
id="my-svg"><style>#my-svg{font-family:"trebuchet
ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#my-svg
.error-icon{fill:#552222;}#my-svg
.error-text{fill:#552222;stroke:#552222;}#my-svg
.edge-thickness-normal{stroke-width:2px;}#m [...]
diff --git a/docs/source/format/DriverTableLoad.mmd
b/docs/source/format/DriverTableLoad.mmd
new file mode 100644
index 000000000..44f2d4130
--- /dev/null
+++ b/docs/source/format/DriverTableLoad.mmd
@@ -0,0 +1,46 @@
+%% 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.
+
+block-beta
+ columns 3
+ app["<b>Application</b>"]:3
+
+ space:3
+
+ space
+
+ AdbcDriver["<b>struct AdbcDriver</b>"]:2
+
+ space
+
+ execute_query
+ ellipsis["..."]
+
+ space:3
+
+ driver["<b>Driver</b>"]:3
+ AdbcDriverInit
+ AdbcStatementExecuteQuery
+ ...
+ space
+ SqliteStatementExecuteQuery
+ ellipsis2["..."]
+
+ app --> AdbcDriverInit
+ AdbcDriverInit --> AdbcDriver
+ SqliteStatementExecuteQuery --> execute_query
+ ellipsis2 --> ellipsis
diff --git a/docs/source/format/DriverTableLoad.mmd.svg
b/docs/source/format/DriverTableLoad.mmd.svg
new file mode 100644
index 000000000..2b762f68e
--- /dev/null
+++ b/docs/source/format/DriverTableLoad.mmd.svg
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<svg aria-roledescription="block" role="graphics-document document"
viewBox="-5 -139 695.0234375 278" style="max-width: 695.023px;
background-color: white;" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg" width="100%"
id="my-svg"><style>#my-svg{font-family:"trebuchet
ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#my-svg
.error-icon{fill:#552222;}#my-svg
.error-text{fill:#552222;stroke:#552222;}#my-svg
.edge-thickness-normal{stroke-width:2px;}#my-svg [...]
diff --git a/docs/source/format/DriverTableUse.mmd
b/docs/source/format/DriverTableUse.mmd
new file mode 100644
index 000000000..84717b6ab
--- /dev/null
+++ b/docs/source/format/DriverTableUse.mmd
@@ -0,0 +1,45 @@
+%% 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.
+
+block-beta
+ columns 3
+ app["<b>Application</b>"]:3
+
+ space:3
+
+ space
+
+ AdbcDriver["<b>struct AdbcDriver</b>"]:2
+
+ space
+
+ execute_query
+ ellipsis["..."]
+
+ space:3
+
+ driver["<b>Driver</b>"]:3
+ AdbcDriverInit
+ AdbcStatementExecuteQuery
+ ...
+ space
+ SqliteStatementExecuteQuery
+ ellipsis2["..."]
+
+ app --> execute_query
+
+ execute_query --> SqliteStatementExecuteQuery
diff --git a/docs/source/format/DriverTableUse.mmd.svg
b/docs/source/format/DriverTableUse.mmd.svg
new file mode 100644
index 000000000..6521dfe93
--- /dev/null
+++ b/docs/source/format/DriverTableUse.mmd.svg
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<svg aria-roledescription="block" role="graphics-document document"
viewBox="-5 -139 695.0234375 278" style="max-width: 695.023px;
background-color: white;" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg" width="100%"
id="my-svg"><style>#my-svg{font-family:"trebuchet
ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#my-svg
.error-icon{fill:#552222;}#my-svg
.error-text{fill:#552222;stroke:#552222;}#my-svg
.edge-thickness-normal{stroke-width:2px;}#my-svg [...]
diff --git a/docs/source/format/how_manager.rst
b/docs/source/format/how_manager.rst
new file mode 100644
index 000000000..2c0218252
--- /dev/null
+++ b/docs/source/format/how_manager.rst
@@ -0,0 +1,207 @@
+.. 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.
+
+================================================
+How Drivers and the Driver Manager Work Together
+================================================
+
+.. note:: This document focuses on drivers/applications that implement or
+ consume the C API definitions in adbc.h. That includes C/C++,
+ Python, and Ruby; and possibly C#, Go, and Rust (when implementing
+ or consuming drivers via FFI).
+
+When an application calls a function like
+:cpp:func:`AdbcStatementExecuteQuery`, how does it "know" what function in
+which driver to actually call?
+
+This can happen in a few ways. In the simplest case, the application links to
+a single driver, and directly calls ADBC functions explicitly defined by the
+driver:
+
+.. figure:: DriverDirectLink.mmd.svg
+
+ In the simplest case, an application directly links to the driver and calls
+ ADBC functions.
+
+This doesn't work with multiple drivers, or applications that don't/can't link
+directly to drivers (think dynamic loading, perhaps in a language like
+Python). For this case, ADBC provides a table of function pointers
+(:cpp:struct:`AdbcDriver`), and a way to request this table from a driver.
+Then, the application proceeds in two steps. First, it dynamically loads a
+driver and calls an entrypoint function to get the function table:
+
+.. figure:: DriverTableLoad.mmd.svg
+
+ Now, the application asks the driver for a table of functions to call.
+
+Then, the application uses the driver by calling the functions in the table:
+
+.. figure:: DriverTableUse.mmd.svg
+
+ The application uses the table to call driver functions. This approach
+ scales to multiple drivers.
+
+Dealing with the table, however, is messy. So the overall recommended
+approach is to use the ADBC driver manager. This is a library that pretends
+to be a single driver that can be linked to and used "like normal".
+Internally, it loads the table of function pointers and tracks which
+database/connection/statement objects need which "actual" driver, making it
+easy to dynamically load drivers at runtime and use multiple drivers from the
+same application:
+
+.. figure:: DriverManagerUse.mmd.svg
+
+ The application uses driver manager to "feel like" it's just using a single
+ driver. The driver manager handles the details behind the scenes.
+
+In More Detail
+==============
+
+The `adbc.h`_ header ties everything together. It is the abstract API
+definition, akin to interface/trait/protocol definitions in other languages.
+C being C, however, all it consists of is a bunch of function prototypes and
+struct definitions without any implementation.
+
+.. _adbc.h: https://github.com/apache/arrow/blob/main/format/adbc.h
+
+A driver, at its core, is just a library that implements those function
+prototypes in adbc.h. Those functions may be implemented in C, or they can be
+implemented in a different language and exported through language-specific FFI
+mechanisms. For example, the Go and C# implementations of ADBC can both
+export drivers to consumers who expect the C API definitions. As long as the
+definitions in adbc.h are implemented somehow, then the application is
+generally none the wiser when it comes to what's actually underneath.
+
+How does an application call these functions, though? Here, there are several
+options.
+
+Again, the simplest case is as follows: if (1) the application links directly
+to the driver, and (2) the driver exposes the ADBC functions *under the same
+name* as in adbc.h, then the application can just ``#include <adbc.h>`` and
+call ``AdbcStatementExecuteQuery(...)`` directly. Here, the application and
+driver have a relationship no different than any other C library.
+
+.. figure:: DriverDirectLink.mmd.svg
+
+ In the simplest case, an application directly links to the driver and calls
+ ADBC functions. When the application calls ``StatementExecuteQuery``, that
+ is directly provided by the driver that it links against.
+
+Unfortunately, this doesn't work as well in other scenarios. For example, if
+an application wishes to use multiple ADBC drivers, this no longer works: both
+drivers define the same functions (the ones in adbc.h), and when the
+application links both of them, the linker has no way of telling which
+driver's function is meant when the application calls an ADBC function. On
+top of that, this violates the `One Definition Rule`_.
+
+In this case, the driver can provide driver-specific aliases that applications
+can use, say ``PostgresqlStatementExecuteQuery`` or
+``FlightSqlStatementExecuteQuery``. Then, the application can link both
+drivers, ignore the ``Adbc…`` functions (and ignore the technical violation of
+the One Definition Rule there), and use the aliases instead.
+
+.. figure:: DriverAlias.mmd.svg
+
+ To get around the One Definition Rule, we can provide aliases of the ADBC
+ APIs instead.
+
+This is rather inconvenient for the application, though. Additionally, this
+sort of defeats the point of using ADBC, since now the application has a
+separate API for each driver, even if they're technically all clones of the
+same API. And this doesn't solve the problem for applications that want to
+load drivers dynamically. For example, a Python script would want to load the
+driver at runtime. In that case, it would need to know which functions from
+the driver correspond to which functions in the ADBC API definitions, without
+having to hardcode this knowledge.
+
+ADBC anticipated this, and defined :cpp:struct:`AdbcDriver`. This is just a
+table of function pointers with one entry per ADBC function. That way, an
+application can dynamically load a driver and call an entrypoint function that
+returns this table of function pointers. (It does have to hardcode or guess
+the name of the entrypoint; the ADBC spec lists a set of names it can try,
+based on the name of the driver library itself.)
+
+.. figure:: DriverTableLoad.mmd.svg
+
+ The application first loads a table of function pointers from the driver.
+
+Then, it can use the driver by calling functions in that table:
+
+.. figure:: DriverTableUse.mmd.svg
+
+ The application uses the table to call driver functions. This approach
+ scales to multiple drivers.
+
+Of course, calling all functions by jumping through a giant table of function
+pointers is inconvenient. So ADBC provides the "driver manager", a library
+that _pretends_ to be a simple driver and implements all the ADBC functions.
+Internally, it loads drivers dynamically, requests the tables of function
+pointers, and keeps track of which connections are using which drivers. The
+application only needs to call the standard ADBC functions, just like in the
+simplest case we started out with:
+
+.. figure:: DriverManagerUse.mmd.svg
+
+ The application uses driver manager to "feel like" it's just using a single
+ driver. The driver manager handles the details behind the scenes.
+
+So to recap, a driver should implement these three things:
+
+#. An implementation of each ADBC function,
+#. A thin wrapper around each implementation function that exports the ADBC
+ name for each function, and
+#. An entrypoint function that returns a :cpp:struct:`AdbcDriver` table,
+ containing the functions from (1).
+
+Then, an application has these choices of ways to use a driver:
+
+- Link the driver directly and call ``Adbc…`` functions (only in the simplest
+ cases) using (2) above,
+- Link the driver directly/dynamically, load the :cpp:struct:`AdbcDriver`
+ via (3) above, and call ADBC functions through function pointers (generally
+ not recommended),
+- Link the ADBC driver manager, call ``Adbc…`` functions, and let the driver
+ manager deal with (3) above (what most applications will want to do).
+
+In other words, it's usually easiest to just always use the driver manager.
+But the magic it pulls isn't required or all that complex.
+
+.. note:: You may ask: when we have :cpp:struct:`AdbcDriver`, why do we bother
+ defining both ``AdbcStatementExecuteQuery`` and
+ ``SqliteStatementExecuteQuery`` (i.e., why do both (1) and (2)
+ above)? Can't we just define the ``Adbc…`` version, and put it into
+ the function table when requested?
+
+ Here, implementation constraints come in. At runtime, when the
+ driver looks up the address of (say) ``AdbcStatementExecuteQuery``
+ to put it into the table, the dynamic linker will come into play to
+ figure out where this function is. Unfortunately, it will probably
+ find it *in the driver manager*. This is a problem, since then the
+ driver manager will end up in an infinite loop when it goes to call
+ the "driver's" version of the function!
+
+ By having a seemingly redundant copy of the function, we can then
+ hide the "real implementation" from the dynamic linker and avoid
+ this behavior.
+
+ The driver manager could try to solve this by loading the drivers
+ with ``RTLD_DEEPBIND``. This, however, is not portable, and causes
+ problems if we also want to use things like AddressSanitizer during
+ development. The driver could also build with flags like
+ ``-Bsymbolic-functions``.
+
+.. _One Definition Rule:
https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 494ccfc71..e29d26c48 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -244,6 +244,7 @@ Why ADBC?
format/specification
format/versioning
format/comparison
+ format/how_manager
.. toctree::
:maxdepth: 1