You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by pa...@apache.org on 2023/06/22 16:40:25 UTC

[arrow-adbc] branch main updated: feat(r): Add FlightSQL driver wrapper (#835)

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

paleolimbot 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 997caa34 feat(r): Add FlightSQL driver wrapper (#835)
997caa34 is described below

commit 997caa34d787b97c11244f182be52714a05a47e3
Author: Dewey Dunnington <de...@voltrondata.com>
AuthorDate: Thu Jun 22 13:40:20 2023 -0300

    feat(r): Add FlightSQL driver wrapper (#835)
    
    This PR adds an R wrapper around the FlightSQL Go/C driver. It follows
    the exact pattern of the Snowflake driver, which also requires building
    a Go library and linking it into an R package.
    
    An obvious concern is that there's a lot of duplication between the
    Snowflake FlightSQL R drivers...I'd like to do something like @zeroshade
    did with the Go portion where there's a common template that can be used
    to generate parts where there's duplication. I'd like to tackle that in
    a follow-up PR so that I can inspect the diffs before/after the
    templating as part of the GitHub PR view.
    
    I'm having trouble getting the usual `remotes::install_github()` command
    to work...if you'd like to give it a try you should also be able to
    checkout this branch and `R CMD INSTALL r/adbcflightsql`. I didn't have
    any trouble getting this to build on MacOS/Windows/Ubuntu in CI (and
    tested locally on MacOS M1).
    
    ``` r
    # (This used to work but I'm having trouble getting this exact set of install
    # commands to work at the moment)
    # install.packages("remotes")
    # remotes::install_github("apache/arrow-adbc/r/adbcdrivermanager", build = FALSE)
    # remotes::install_github("apache/arrow-adbc/r/adbcflightsql#835", build = FALSE)
    
    library(adbcdrivermanager)
    
    # Use the driver manager to connect to a database.
    # I'm running `docker compose up golang-sqlite-flightsql` in the
    # ADBC repo for this example
    
    uri <- "grpc://localhost:8080"
    db <- adbc_database_init(adbcflightsql::adbcflightsql(), uri = uri)
    con <- adbc_connection_init(db)
    
    # Write a table
    stmt <- adbc_statement_init(con)
    adbc_statement_set_sql_query(
      stmt,
      "CREATE TABLE crossfit (exercise TEXT, difficulty_level INTEGER)"
    )
    adbc_statement_execute_query(stmt)
    #> [1] 4
    adbc_statement_release(stmt)
    
    stmt <- adbc_statement_init(con)
    adbc_statement_set_sql_query(
      stmt,
      "INSERT INTO crossfit values
        ('Push Ups', 3),
        ('Pull Ups', 5),
        ('Push Jerk', 7),
        ('Bar Muscle Up', 10);"
    )
    adbc_statement_execute_query(stmt)
    #> [1] 4
    adbc_statement_release(stmt)
    
    # Query it
    stmt <- adbc_statement_init(con)
    stream <- nanoarrow::nanoarrow_allocate_array_stream()
    
    adbc_statement_set_sql_query(stmt, "SELECT * from crossfit")
    adbc_statement_execute_query(stmt, stream)
    #> [1] -1
    result <- tibble::as_tibble(stream)
    adbc_statement_release(stmt)
    
    result
    #> # A tibble: 4 × 2
    #>   exercise      difficulty_level
    #>   <chr>                    <dbl>
    #> 1 Push Ups                     3
    #> 2 Pull Ups                     5
    #> 3 Push Jerk                    7
    #> 4 Bar Muscle Up               10
    
    # Clean up
    stmt <- adbc_statement_init(con)
    adbc_statement_set_sql_query(stmt, "DROP TABLE crossfit")
    adbc_statement_execute_query(stmt)
    #> [1] 4
    adbc_statement_release(stmt)
    
    adbc_connection_release(con)
    adbc_database_release(db)
    ```
    
    <sup>Created on 2023-06-22 with [reprex
    v2.0.2](https://reprex.tidyverse.org)</sup>
---
 .github/workflows/native-unix.yml                  |  16 +-
 dev/release/rat_exclude_files.txt                  |  19 +-
 r/adbcflightsql/.Rbuildignore                      |   9 +
 r/adbcflightsql/.gitignore                         |  19 ++
 r/adbcflightsql/DESCRIPTION                        |  25 +++
 r/adbcflightsql/LICENSE.md                         | 194 +++++++++++++++++++++
 r/adbcflightsql/NAMESPACE                          |  10 ++
 r/adbcflightsql/R/adbcflightsql-package.R          |  95 ++++++++++
 r/adbcflightsql/README.Rmd                         | 109 ++++++++++++
 r/adbcflightsql/README.md                          |  93 ++++++++++
 r/adbcflightsql/adbcflightsql.Rproj                |  22 +++
 r/adbcflightsql/bootstrap.R                        |  64 +++++++
 r/adbcflightsql/cleanup                            |  18 ++
 r/adbcflightsql/cleanup.win                        |  18 ++
 r/adbcflightsql/configure                          |  95 ++++++++++
 r/adbcflightsql/configure.win                      |  23 +++
 r/adbcflightsql/man/adbcflightsql-package.Rd       |  26 +++
 r/adbcflightsql/man/adbcflightsql.Rd               |  51 ++++++
 r/adbcflightsql/src/.gitignore                     |  19 ++
 r/adbcflightsql/src/Makevars.in                    |  30 ++++
 r/adbcflightsql/src/Makevars.win                   |  34 ++++
 r/adbcflightsql/src/go/.gitignore                  |  21 +++
 r/adbcflightsql/src/go/symbols.map                 |  26 +++
 r/adbcflightsql/src/init.c                         |  43 +++++
 r/adbcflightsql/tests/testthat.R                   |  29 +++
 .../tests/testthat/test-adbcflightsql-package.R    |  90 ++++++++++
 r/adbcflightsql/tools/download-go.R                |  87 +++++++++
 27 files changed, 1268 insertions(+), 17 deletions(-)

diff --git a/.github/workflows/native-unix.yml b/.github/workflows/native-unix.yml
index 6d01f4f7..ad838522 100644
--- a/.github/workflows/native-unix.yml
+++ b/.github/workflows/native-unix.yml
@@ -598,6 +598,9 @@ jobs:
           - {os: macOS-latest,   r: 'release', pkg: 'adbcsnowflake'}
           - {os: windows-latest,   r: 'release', pkg: 'adbcsnowflake'}
           - {os: ubuntu-latest,   r: 'release', pkg: 'adbcsnowflake'}
+          - {os: ubuntu-latest,   r: 'release', pkg: 'adbcflightsql'}
+          - {os: macOS-latest,   r: 'release', pkg: 'adbcflightsql'}
+          - {os: windows-latest,   r: 'release', pkg: 'adbcflightsql'}
 
     env:
       GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
@@ -652,6 +655,14 @@ jobs:
           ADBC_POSTGRESQL_TEST_URI="postgresql://localhost:5432/postgres?user=postgres&password=password"
           echo "ADBC_POSTGRESQL_TEST_URI=${ADBC_POSTGRESQL_TEST_URI}" >> $GITHUB_ENV
 
+      - name: Start FlightSQL test database
+        if: matrix.config.pkg == 'adbcflightsql' && runner.os == 'Linux'
+        run: |
+          cd r/adbcpostgresql
+          docker compose up --detach golang-sqlite-flightsql
+          ADBC_FLIGHTSQL_TEST_URI="grpc://localhost:8080"
+          echo "ADBC_FLIGHTSQL_TEST_URI=${ADBC_FLIGHTSQL_TEST_URI}" >> $GITHUB_ENV
+
       - uses: r-lib/actions/check-r-package@v2
         env:
           ADBC_SNOWFLAKE_TEST_URI: ${{ secrets.SNOWFLAKE_URI }}
@@ -659,8 +670,7 @@ jobs:
           upload-snapshots: true
           working-directory: r/${{ matrix.config.pkg }}
 
-      - name: Stop postgres test database
-        if: matrix.config.pkg == 'adbcpostgresql' && runner.os == 'Linux'
+      - name: Stop test database
+        if: runner.os == 'Linux'
         run: |
-          cd r/adbcpostgresql
           docker compose down
diff --git a/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt
index d9713c90..47ed4506 100644
--- a/dev/release/rat_exclude_files.txt
+++ b/dev/release/rat_exclude_files.txt
@@ -22,17 +22,8 @@ go/adbc/go.sum
 java/.mvn/jvm.config
 python/*/*/py.typed
 rat.txt
-r/adbcdrivermanager/DESCRIPTION
-r/adbcdrivermanager/NAMESPACE
-r/adbcdrivermanager/cran-comments.md
-r/adbcdrivermanager/.Rbuildignore
-r/adbcdrivermanager/tests/testthat/_snaps/*
-r/adbcsqlite/DESCRIPTION
-r/adbcsqlite/NAMESPACE
-r/adbcsqlite/.Rbuildignore
-r/adbcpostgresql/DESCRIPTION
-r/adbcpostgresql/NAMESPACE
-r/adbcpostgresql/.Rbuildignore
-r/adbcsnowflake/DESCRIPTION
-r/adbcsnowflake/NAMESPACE
-r/adbcsnowflake/.Rbuildignore
+r/*/DESCRIPTION
+r/*/NAMESPACE
+r/*/cran-comments.md
+r/*/.Rbuildignore
+r/*/tests/testthat/_snaps/*
diff --git a/r/adbcflightsql/.Rbuildignore b/r/adbcflightsql/.Rbuildignore
new file mode 100644
index 00000000..9f12a1fa
--- /dev/null
+++ b/r/adbcflightsql/.Rbuildignore
@@ -0,0 +1,9 @@
+^adbcflightsql\.Rproj$
+^\.Rproj\.user$
+^LICENSE\.md$
+^bootstrap\.R$
+^README\.Rmd$
+^src/Makevars$
+^configure\.win$
+^\.vscode$
+^src/go/tmp$
diff --git a/r/adbcflightsql/.gitignore b/r/adbcflightsql/.gitignore
new file mode 100644
index 00000000..d025a1b1
--- /dev/null
+++ b/r/adbcflightsql/.gitignore
@@ -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.
+
+.Rproj.user
+windows/
diff --git a/r/adbcflightsql/DESCRIPTION b/r/adbcflightsql/DESCRIPTION
new file mode 100644
index 00000000..df4b45b0
--- /dev/null
+++ b/r/adbcflightsql/DESCRIPTION
@@ -0,0 +1,25 @@
+Package: adbcflightsql
+Title: Arrow Database Connectivity (ADBC) FlightSQL Driver
+Version: 0.5.0.9000
+Authors@R: c(
+      person("Dewey", "Dunnington", , "dewey@dunnington.ca", role = c("aut", "cre"),
+             comment = c(ORCID = "0000-0002-9415-4582")),
+      person("Apache Arrow", email = "dev@arrow.apache.org", role = c("aut", "cph"))
+    )
+Description: Provides a developer-facing interface to the Arrow Database
+  Connectivity (ADBC) FlightSQL driver.
+License: Apache License (>= 2)
+Encoding: UTF-8
+Roxygen: list(markdown = TRUE)
+RoxygenNote: 7.2.3
+Suggests:
+    nanoarrow,
+    testthat (>= 3.0.0)
+Config/testthat/edition: 3
+Config/build/bootstrap: TRUE
+URL: https://github.com/apache/arrow-adbc
+BugReports: https://github.com/apache/arrow-adbc/issues
+Imports:
+    adbcdrivermanager
+Remotes:
+    adbcdrivermanager=apache/arrow-adbc/r/adbcdrivermanager
diff --git a/r/adbcflightsql/LICENSE.md b/r/adbcflightsql/LICENSE.md
new file mode 100644
index 00000000..b62a9b5f
--- /dev/null
+++ b/r/adbcflightsql/LICENSE.md
@@ -0,0 +1,194 @@
+Apache License
+==============
+
+_Version 2.0, January 2004_
+_&lt;<http://www.apache.org/licenses/>&gt;_
+
+### Terms and Conditions for use, reproduction, and distribution
+
+#### 1. Definitions
+
+“License” shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+“Licensor” shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+“Legal Entity” shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, “control” means **(i)** the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
+outstanding shares, or **(iii)** beneficial ownership of such entity.
+
+“You” (or “Your”) shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+“Source” form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+“Object” form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+“Work” shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+“Derivative Works” shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+“Contribution” shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+“submitted” means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as “Not a Contribution.”
+
+“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+#### 2. Grant of Copyright License
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+#### 3. Grant of Patent License
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+#### 4. Redistribution
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+* **(b)** You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+#### 5. Submission of Contributions
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+#### 6. Trademarks
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+#### 7. Disclaimer of Warranty
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+#### 8. Limitation of Liability
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+#### 9. Accepting Warranty or Additional Liability
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+_END OF TERMS AND CONDITIONS_
+
+### APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets `[]` replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same “printed page” as the copyright notice for easier identification within
+third-party archives.
+
+    Copyright [yyyy] [name of copyright owner]
+
+    Licensed 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.
diff --git a/r/adbcflightsql/NAMESPACE b/r/adbcflightsql/NAMESPACE
new file mode 100644
index 00000000..d793043a
--- /dev/null
+++ b/r/adbcflightsql/NAMESPACE
@@ -0,0 +1,10 @@
+# Generated by roxygen2: do not edit by hand
+
+S3method(adbc_connection_init,adbcflightsql_database)
+S3method(adbc_database_init,adbcflightsql_driver_flightsql)
+S3method(adbc_statement_init,adbcflightsql_connection)
+export(adbcflightsql)
+importFrom(adbcdrivermanager,adbc_connection_init)
+importFrom(adbcdrivermanager,adbc_database_init)
+importFrom(adbcdrivermanager,adbc_statement_init)
+useDynLib(adbcflightsql, .registration = TRUE)
diff --git a/r/adbcflightsql/R/adbcflightsql-package.R b/r/adbcflightsql/R/adbcflightsql-package.R
new file mode 100644
index 00000000..5eacc081
--- /dev/null
+++ b/r/adbcflightsql/R/adbcflightsql-package.R
@@ -0,0 +1,95 @@
+# 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.
+
+#' @keywords internal
+#' @aliases NULL
+"_PACKAGE"
+
+## usethis namespace: start
+#' @useDynLib adbcflightsql, .registration = TRUE
+## usethis namespace: end
+NULL
+
+#' ADBC FlightSQL Driver
+#'
+#' @inheritParams adbcdrivermanager::adbc_database_init
+#' @inheritParams adbcdrivermanager::adbc_connection_init
+#' @inheritParams adbcdrivermanager::adbc_statement_init
+#' @param uri A URI to a database path (e.g.,
+#'   `user[:password]@account/database[?param1=value1]`)
+#' @param adbc.connection.autocommit Use FALSE to disable the default
+#'   autocommit behaviour.
+#' @param adbc.ingest.target_table The name of the target table for a bulk insert.
+#' @param adbc.ingest.mode Whether to create (the default) or append.
+#' @param ... Extra key/value options passed to the driver.
+#'
+#' @return An [adbcdrivermanager::adbc_driver()]
+#' @export
+#'
+#' @examples
+#' adbcflightsql()
+#'
+adbcflightsql <- function() {
+  adbcdrivermanager::adbc_driver(
+    .Call(adbcflightsql_c_flightsql),
+    subclass = "adbcflightsql_driver_flightsql"
+  )
+}
+
+#' @rdname adbcflightsql
+#' @importFrom adbcdrivermanager adbc_database_init
+#' @export
+adbc_database_init.adbcflightsql_driver_flightsql <- function(driver, ..., uri = NULL) {
+  options <- list(..., uri = uri)
+  adbcdrivermanager::adbc_database_init_default(
+    driver,
+    options[!vapply(options, is.null, logical(1))],
+    subclass = "adbcflightsql_database"
+  )
+}
+
+#' @rdname adbcflightsql
+#' @importFrom adbcdrivermanager adbc_connection_init
+#' @export
+adbc_connection_init.adbcflightsql_database <- function(database, ...,
+                                                        adbc.connection.autocommit = NULL) {
+  options <- list(..., adbc.connection.autocommit = adbc.connection.autocommit)
+  adbcdrivermanager::adbc_connection_init_default(
+    database,
+    options[!vapply(options, is.null, logical(1))],
+    subclass = "adbcflightsql_connection"
+  )
+}
+
+#' @rdname adbcflightsql
+#' @importFrom adbcdrivermanager adbc_statement_init
+#' @export
+adbc_statement_init.adbcflightsql_connection <- function(connection, ...,
+                                                         adbc.ingest.target_table = NULL,
+                                                         adbc.ingest.mode = NULL) {
+  options <- list(
+    ...,
+    adbc.ingest.target_table = adbc.ingest.target_table,
+    adbc.ingest.mode = adbc.ingest.mode
+  )
+
+  adbcdrivermanager::adbc_statement_init_default(
+    connection,
+    options[!vapply(options, is.null, logical(1))],
+    subclass = "adbcflightsql_statement"
+  )
+}
diff --git a/r/adbcflightsql/README.Rmd b/r/adbcflightsql/README.Rmd
new file mode 100644
index 00000000..2cb743d4
--- /dev/null
+++ b/r/adbcflightsql/README.Rmd
@@ -0,0 +1,109 @@
+---
+output: github_document
+---
+
+<!---
+  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.
+-->
+
+<!-- README.md is generated from README.Rmd. Please edit that file -->
+
+```{r, include = FALSE}
+knitr::opts_chunk$set(
+  collapse = TRUE,
+  comment = "#>",
+  fig.path = "man/figures/README-",
+  out.width = "100%"
+)
+```
+
+# adbcflightsql
+
+<!-- badges: start -->
+<!-- badges: end -->
+
+The goal of adbcflightsql is to provide a low-level developer-facing interface
+to the Arrow Database Connectivity (ADBC) FlightSQL driver.
+
+## Installation
+
+You can install the development version of adbcflightsql from [GitHub](https://github.com/) with:
+
+``` r
+# install.packages("remotes")
+remotes::install_github("apache/arrow-adbc/r/adbcdrivermanager", build = FALSE)
+remotes::install_github("apache/arrow-adbc/r/adbcflightsql", build = FALSE)
+```
+
+## Example
+
+This is a basic example which shows you how to solve a common problem.
+
+
+```{r example}
+library(adbcdrivermanager)
+
+# Use the driver manager to connect to a database. This example URI is
+# grpc://localhost:8080 and uses a Go FlightSQL/SQLite server docker image
+uri <- Sys.getenv("ADBC_FLIGHTSQL_TEST_URI")
+db <- adbc_database_init(adbcflightsql::adbcflightsql(), uri = uri)
+con <- adbc_connection_init(db)
+
+# Write a table
+stmt <- adbc_statement_init(con)
+adbc_statement_set_sql_query(
+  stmt,
+  "CREATE TABLE crossfit (exercise TEXT, difficulty_level INTEGER)"
+)
+adbc_statement_execute_query(stmt)
+adbc_statement_release(stmt)
+
+stmt <- adbc_statement_init(con)
+adbc_statement_set_sql_query(
+  stmt,
+  "INSERT INTO crossfit values
+    ('Push Ups', 3),
+    ('Pull Ups', 5),
+    ('Push Jerk', 7),
+    ('Bar Muscle Up', 10);"
+)
+adbc_statement_execute_query(stmt)
+adbc_statement_release(stmt)
+
+# Query it
+stmt <- adbc_statement_init(con)
+stream <- nanoarrow::nanoarrow_allocate_array_stream()
+
+adbc_statement_set_sql_query(stmt, "SELECT * from crossfit")
+adbc_statement_execute_query(stmt, stream)
+result <- tibble::as_tibble(stream)
+adbc_statement_release(stmt)
+
+result
+```
+
+```{r example-clean-up, include=FALSE}
+stmt <- adbc_statement_init(con)
+adbc_statement_set_sql_query(stmt, "DROP TABLE crossfit")
+adbc_statement_execute_query(stmt)
+adbc_statement_release(stmt)
+```
+
+```{r example-clean-up2, include=FALSE}
+# Clean up
+adbc_connection_release(con)
+adbc_database_release(db)
+```
diff --git a/r/adbcflightsql/README.md b/r/adbcflightsql/README.md
new file mode 100644
index 00000000..eabc8a1e
--- /dev/null
+++ b/r/adbcflightsql/README.md
@@ -0,0 +1,93 @@
+
+<!---
+  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.
+-->
+<!-- README.md is generated from README.Rmd. Please edit that file -->
+
+# adbcflightsql
+
+<!-- badges: start -->
+<!-- badges: end -->
+
+The goal of adbcflightsql is to provide a low-level developer-facing
+interface to the Arrow Database Connectivity (ADBC) FlightSQL driver.
+
+## Installation
+
+You can install the development version of adbcflightsql from
+[GitHub](https://github.com/) with:
+
+``` r
+# install.packages("remotes")
+remotes::install_github("apache/arrow-adbc/r/adbcdrivermanager", build = FALSE)
+remotes::install_github("apache/arrow-adbc/r/adbcflightsql", build = FALSE)
+```
+
+## Example
+
+This is a basic example which shows you how to solve a common problem.
+
+``` r
+library(adbcdrivermanager)
+
+# Use the driver manager to connect to a database. This example URI is
+# grpc://localhost:8080 and uses a Go FlightSQL/SQLite server docker image
+uri <- Sys.getenv("ADBC_FLIGHTSQL_TEST_URI")
+db <- adbc_database_init(adbcflightsql::adbcflightsql(), uri = uri)
+con <- adbc_connection_init(db)
+
+# Write a table
+stmt <- adbc_statement_init(con)
+adbc_statement_set_sql_query(
+  stmt,
+  "CREATE TABLE crossfit (exercise TEXT, difficulty_level INTEGER)"
+)
+adbc_statement_execute_query(stmt)
+#> [1] 4
+adbc_statement_release(stmt)
+
+stmt <- adbc_statement_init(con)
+adbc_statement_set_sql_query(
+  stmt,
+  "INSERT INTO crossfit values
+    ('Push Ups', 3),
+    ('Pull Ups', 5),
+    ('Push Jerk', 7),
+    ('Bar Muscle Up', 10);"
+)
+adbc_statement_execute_query(stmt)
+#> [1] 4
+adbc_statement_release(stmt)
+
+# Query it
+stmt <- adbc_statement_init(con)
+stream <- nanoarrow::nanoarrow_allocate_array_stream()
+
+adbc_statement_set_sql_query(stmt, "SELECT * from crossfit")
+adbc_statement_execute_query(stmt, stream)
+#> [1] -1
+result <- tibble::as_tibble(stream)
+adbc_statement_release(stmt)
+
+result
+#> # A tibble: 4 × 2
+#>   exercise      difficulty_level
+#>   <chr>                    <dbl>
+#> 1 Push Ups                     3
+#> 2 Pull Ups                     5
+#> 3 Push Jerk                    7
+#> 4 Bar Muscle Up               10
+```
diff --git a/r/adbcflightsql/adbcflightsql.Rproj b/r/adbcflightsql/adbcflightsql.Rproj
new file mode 100644
index 00000000..69fafd4b
--- /dev/null
+++ b/r/adbcflightsql/adbcflightsql.Rproj
@@ -0,0 +1,22 @@
+Version: 1.0
+
+RestoreWorkspace: No
+SaveWorkspace: No
+AlwaysSaveHistory: Default
+
+EnableCodeIndexing: Yes
+UseSpacesForTab: Yes
+NumSpacesForTab: 2
+Encoding: UTF-8
+
+RnwWeave: Sweave
+LaTeX: pdfLaTeX
+
+AutoAppendNewline: Yes
+StripTrailingWhitespace: Yes
+LineEndingConversion: Posix
+
+BuildType: Package
+PackageUseDevtools: Yes
+PackageInstallArgs: --no-multiarch --with-keep.source
+PackageRoxygenize: rd,collate,namespace
diff --git a/r/adbcflightsql/bootstrap.R b/r/adbcflightsql/bootstrap.R
new file mode 100644
index 00000000..3e57feb3
--- /dev/null
+++ b/r/adbcflightsql/bootstrap.R
@@ -0,0 +1,64 @@
+# 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.
+
+# If we are building within the repo, copy the go sources into the go/
+# directory. Technically this copies all go drivers but this is easier
+# than remembering the internal dependency structure of the go sources.
+files_to_vendor <- list.files(
+  "../../go/adbc",
+  "\\.(go|mod|txt|sum|h|c)$",
+  recursive = TRUE
+)
+
+files_to_vendor_src <- file.path("../../go/adbc", files_to_vendor)
+files_to_vendor_dst <- file.path("src/go/adbc", files_to_vendor)
+
+# On Windows, file.copy does not handle symlinks. This
+# is not a problem for a user install, where this script
+# should not even exist, but the below helps development
+# on Windows.
+is_adbc_h <- basename(files_to_vendor_src) == "adbc.h"
+files_to_vendor_src[is_adbc_h] <- "../../adbc.h"
+
+if (all(file.exists(files_to_vendor_src))) {
+  unlink("src/go/adbc", recursive = TRUE)
+
+  cat(
+    sprintf(
+      "Vendoring files from arrow-adbc/go/adbc to src/go/adbc:\n%s\n",
+      paste(
+        "-", files_to_vendor_src, " -> ", files_to_vendor_dst,
+        collapse = "\n"
+      )
+    )
+  )
+
+  # Recreate the directory structure
+  dst_dirs <- unique(dirname(files_to_vendor_dst))
+  for (dst_dir in dst_dirs) {
+    if (!dir.exists(dst_dir)) {
+      dir.create(dst_dir, recursive = TRUE)
+    }
+  }
+
+  # Copy the files
+  if (all(file.copy(files_to_vendor_src, files_to_vendor_dst))) {
+    cat("All files successfully copied to src/go/adbc\n")
+  } else {
+    stop("Failed to vendor all files")
+  }
+}
diff --git a/r/adbcflightsql/cleanup b/r/adbcflightsql/cleanup
new file mode 100755
index 00000000..01e970b3
--- /dev/null
+++ b/r/adbcflightsql/cleanup
@@ -0,0 +1,18 @@
+# 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.
+
+rm src/*.o src/go/*.a
diff --git a/r/adbcflightsql/cleanup.win b/r/adbcflightsql/cleanup.win
new file mode 100755
index 00000000..7bee0e8f
--- /dev/null
+++ b/r/adbcflightsql/cleanup.win
@@ -0,0 +1,18 @@
+# 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.
+
+./cleanup
diff --git a/r/adbcflightsql/configure b/r/adbcflightsql/configure
new file mode 100755
index 00000000..b1b58657
--- /dev/null
+++ b/r/adbcflightsql/configure
@@ -0,0 +1,95 @@
+# 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.
+
+R_BIN="$R_HOME/bin/R"
+RSCRIPT_BIN="$R_HOME/bin/Rscript"
+
+# Run bootstrap.R. This will have already run if we are installing a source
+# package built with pkgbuild::build() with pkgbuild >1.4.0; however, we
+# run it again in case this is R CMD INSTALL on a directory or
+# devtools::load_all(). This will vendor files from elsewhere in the
+# ADBC repo into this package. If the file doesn't exist, we're installing
+# from a pre-built tarball.
+if [ -f bootstrap.R ]; then
+  "$RSCRIPT_BIN" bootstrap.R
+fi
+
+# Find the go binary so that we can go build!
+if [ -z "$GO_BIN" ]; then
+  GO_BIN=`which go`
+fi
+
+if [ -z "$GO_BIN"]; then
+  if [ ! -f src/go/tmp/go/bin/go ]; then
+    echo ""
+    echo "Downloading and extracting Go into the package source directory:"
+    echo "This may take a few minutes. To eliminate this step, install Go"
+    echo "from your faviourite package manager or set the GO_BIN environment variable:"
+    echo "- apt-get install golang"
+    echo "- brew install golang"
+    echo "- dnf install golang"
+    echo "- apk add go"
+    echo "- pacman -S go"
+
+    "$RSCRIPT_BIN" tools/download-go.R
+  fi
+
+  GO_BIN="`pwd`/src/go/tmp/go/bin/go"
+fi
+
+echo "Trying 'go version' with GO_BIN at '$GO_BIN'"
+"$GO_BIN" version
+if [ $? -ne 0 ]; then
+  echo "go --version had a non-zero exit code"
+  exit 1
+fi
+
+# Get the CC and CXX compilers
+CC=`"$R_BIN" CMD config CC`
+CXX=`"$R_BIN" CMD config CXX`
+
+# clang and gcc use different symbol-hiding syntax and we need to
+# make sure to hide any Adbc* symbols that might conflict with another
+# driver.
+if "$R_BIN" CMD config CC | grep -e "clang" ; then
+  SYMBOL_ARGS="-Wl,-exported_symbol,_adbcflightsql_c_flightsql -Wl,-exported_symbol,_R_init_adbcflightsql"
+elif "$R_BIN" CMD config CC | grep -e "gcc" ; then
+  SYMBOL_ARGS="-Wl,--version-script=go/symbols.map"
+fi
+
+# On OSX we need -framework Security because of some dependency somewhere
+if [ `uname` = "Darwin" ]; then
+  PKG_LIBS="-framework Security -lresolv $PKG_LIBS"
+fi
+
+PKG_LIBS="$PKG_LIBS $SYMBOL_ARGS"
+
+sed \
+  -e "s|@gobin@|$GO_BIN|" \
+  -e "s|@libs@|$PKG_LIBS|" \
+  -e "s|@cc@|$CC|" \
+  -e "s|@cxx@|$CXX|" \
+  src/Makevars.in > src/Makevars
+
+if [ -f "src/go/adbc/pkg/flightsql/driver.go" ]; then
+  echo "Found vendored ADBC FlightSQL driver"
+  exit 0
+fi
+
+echo "Vendored ADBC FlightSQL driver was not found."
+echo "This source package was probably built incorrectly and it's probably not your fault"
+exit 1
diff --git a/r/adbcflightsql/configure.win b/r/adbcflightsql/configure.win
new file mode 100755
index 00000000..caf6740f
--- /dev/null
+++ b/r/adbcflightsql/configure.win
@@ -0,0 +1,23 @@
+# 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.
+
+# See configure for a description of this process.
+# This is only for development: this file and bootstrap.R will be removed
+# prior to packaging
+if [ -f bootstrap.R ]; then
+  $R_HOME/bin/Rscript bootstrap.R
+fi
diff --git a/r/adbcflightsql/man/adbcflightsql-package.Rd b/r/adbcflightsql/man/adbcflightsql-package.Rd
new file mode 100644
index 00000000..63c14793
--- /dev/null
+++ b/r/adbcflightsql/man/adbcflightsql-package.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/adbcflightsql-package.R
+\docType{package}
+\name{adbcflightsql-package}
+\title{adbcflightsql: Arrow Database Connectivity (ADBC) FlightSQL Driver}
+\description{
+Provides a developer-facing interface to the Arrow Database Connectivity (ADBC) FlightSQL driver.
+}
+\seealso{
+Useful links:
+\itemize{
+  \item \url{https://github.com/apache/arrow-adbc}
+  \item Report bugs at \url{https://github.com/apache/arrow-adbc/issues}
+}
+
+}
+\author{
+\strong{Maintainer}: Dewey Dunnington \email{dewey@dunnington.ca} (\href{https://orcid.org/0000-0002-9415-4582}{ORCID})
+
+Authors:
+\itemize{
+  \item Apache Arrow \email{dev@arrow.apache.org} [copyright holder]
+}
+
+}
+\keyword{internal}
diff --git a/r/adbcflightsql/man/adbcflightsql.Rd b/r/adbcflightsql/man/adbcflightsql.Rd
new file mode 100644
index 00000000..ec5ffe70
--- /dev/null
+++ b/r/adbcflightsql/man/adbcflightsql.Rd
@@ -0,0 +1,51 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/adbcflightsql-package.R
+\name{adbcflightsql}
+\alias{adbcflightsql}
+\alias{adbc_database_init.adbcflightsql_driver_flightsql}
+\alias{adbc_connection_init.adbcflightsql_database}
+\alias{adbc_statement_init.adbcflightsql_connection}
+\title{ADBC FlightSQL Driver}
+\usage{
+adbcflightsql()
+
+\method{adbc_database_init}{adbcflightsql_driver_flightsql}(driver, ..., uri = NULL)
+
+\method{adbc_connection_init}{adbcflightsql_database}(database, ..., adbc.connection.autocommit = NULL)
+
+\method{adbc_statement_init}{adbcflightsql_connection}(
+  connection,
+  ...,
+  adbc.ingest.target_table = NULL,
+  adbc.ingest.mode = NULL
+)
+}
+\arguments{
+\item{driver}{An \code{\link[adbcdrivermanager:adbc_driver]{adbc_driver()}}.}
+
+\item{...}{Extra key/value options passed to the driver.}
+
+\item{uri}{A URI to a database path (e.g.,
+\verb{user[:password]@account/database[?param1=value1]})}
+
+\item{database}{An \link[adbcdrivermanager:adbc_database_init]{adbc_database}.}
+
+\item{adbc.connection.autocommit}{Use FALSE to disable the default
+autocommit behaviour.}
+
+\item{connection}{An \link[adbcdrivermanager:adbc_connection_init]{adbc_connection}}
+
+\item{adbc.ingest.target_table}{The name of the target table for a bulk insert.}
+
+\item{adbc.ingest.mode}{Whether to create (the default) or append.}
+}
+\value{
+An \code{\link[adbcdrivermanager:adbc_driver_void]{adbcdrivermanager::adbc_driver()}}
+}
+\description{
+ADBC FlightSQL Driver
+}
+\examples{
+adbcflightsql()
+
+}
diff --git a/r/adbcflightsql/src/.gitignore b/r/adbcflightsql/src/.gitignore
new file mode 100644
index 00000000..fb883613
--- /dev/null
+++ b/r/adbcflightsql/src/.gitignore
@@ -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.
+
+adbc.h
+Makevars
diff --git a/r/adbcflightsql/src/Makevars.in b/r/adbcflightsql/src/Makevars.in
new file mode 100644
index 00000000..dee44a7e
--- /dev/null
+++ b/r/adbcflightsql/src/Makevars.in
@@ -0,0 +1,30 @@
+# 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.
+
+PKG_CPPFLAGS=-I$(CURDIR)/src -DADBC_EXPORT=""
+PKG_LIBS=-L$(CURDIR)/go -ladbc_driver_flightsql @libs@
+
+CGO_CC = @cc@
+CGO_CXX = @cxx@
+CGO_CFLAGS = $(ALL_CPPFLAGS)
+
+.PHONY: all gostatic
+all: $(SHLIB)
+$(SHLIB): gostatic
+
+gostatic:
+		(cd "$(CURDIR)/go/adbc"; CC="$(CGO_CC)" CXX="$(CGO_CXX)" CGO_CFLAGS="$(CGO_CFLAGS)" "@gobin@" build -v -tags driverlib -o $(CURDIR)/go/libadbc_driver_flightsql.a -buildmode=c-archive "./pkg/flightsql")
diff --git a/r/adbcflightsql/src/Makevars.win b/r/adbcflightsql/src/Makevars.win
new file mode 100644
index 00000000..ca526b37
--- /dev/null
+++ b/r/adbcflightsql/src/Makevars.win
@@ -0,0 +1,34 @@
+# 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.
+
+PKG_CPPFLAGS=-I$(CURDIR) -DADBC_EXPORT=""
+PKG_LIBS=-L$(CURDIR)/go -ladbc_driver_flightsql
+
+CGO_CC = `"${R_HOME}/bin${R_ARCH_BIN}/R.exe" CMD config CC`
+CGO_CXX = `"${R_HOME}/bin${R_ARCH_BIN}/R.exe" CMD config CXX`
+CGO_CFLAGS = $(ALL_CPPFLAGS)
+GO_BIN = $(CURDIR)/go/tmp/go/bin/go.exe
+
+.PHONY: all gostatic gobin
+all: $(SHLIB)
+$(SHLIB): gostatic
+
+gostatic: gobin
+		(cd "$(CURDIR)/go/adbc"; CC="$(CGO_CC)" CXX="$(CGO_CXX)" CGO_CFLAGS="$(CGO_CFLAGS)" "$(GO_BIN)" build -v -tags driverlib -o $(CURDIR)/go/libadbc_driver_flightsql.a -buildmode=c-archive "./pkg/flightsql")
+
+gobin:
+		(cd ..; "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" "tools/download-go.R")
diff --git a/r/adbcflightsql/src/go/.gitignore b/r/adbcflightsql/src/go/.gitignore
new file mode 100644
index 00000000..5949a4e3
--- /dev/null
+++ b/r/adbcflightsql/src/go/.gitignore
@@ -0,0 +1,21 @@
+# 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.
+
+adbc/
+tmp/
+libadbc_driver_flightsql.a
+libadbc_driver_flightsql.h
diff --git a/r/adbcflightsql/src/go/symbols.map b/r/adbcflightsql/src/go/symbols.map
new file mode 100644
index 00000000..e53dfb15
--- /dev/null
+++ b/r/adbcflightsql/src/go/symbols.map
@@ -0,0 +1,26 @@
+# 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.
+
+{
+  global:
+    # Only expose symbols needed for R
+    R_init_adbcflightsql;
+    adbcflightsql_c_flightsql;
+
+  local:
+    *;
+};
diff --git a/r/adbcflightsql/src/init.c b/r/adbcflightsql/src/init.c
new file mode 100644
index 00000000..2f2ab503
--- /dev/null
+++ b/r/adbcflightsql/src/init.c
@@ -0,0 +1,43 @@
+// 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.
+
+#define R_NO_REMAP
+#include <R.h>
+#include <Rinternals.h>
+
+typedef int AdbcStatusCode;
+struct AdbcError;
+AdbcStatusCode AdbcDriverInit(int version, void* raw_driver, struct AdbcError* error);
+
+static SEXP init_func_xptr = 0;
+
+SEXP adbcflightsql_c_flightsql(void) { return init_func_xptr; }
+
+static const R_CallMethodDef CallEntries[] = {
+    {"adbcflightsql_c_flightsql", (DL_FUNC)&adbcflightsql_c_flightsql, 0},
+    {NULL, NULL, 0}};
+
+void R_init_adbcflightsql(DllInfo* dll) {
+  R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
+  R_useDynamicSymbols(dll, FALSE);
+
+  init_func_xptr =
+      PROTECT(R_MakeExternalPtrFn((DL_FUNC)AdbcDriverInit, R_NilValue, R_NilValue));
+  Rf_setAttrib(init_func_xptr, R_ClassSymbol, Rf_mkString("adbc_driver_init_func"));
+  R_PreserveObject(init_func_xptr);
+  UNPROTECT(1);
+}
diff --git a/r/adbcflightsql/tests/testthat.R b/r/adbcflightsql/tests/testthat.R
new file mode 100644
index 00000000..4173dba3
--- /dev/null
+++ b/r/adbcflightsql/tests/testthat.R
@@ -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.
+
+# This file is part of the standard setup for testthat.
+# It is recommended that you do not modify it.
+#
+# Where should you do additional test configuration?
+# Learn more about the roles of various files in:
+# * https://r-pkgs.org/tests.html
+# * https://testthat.r-lib.org/reference/test_package.html#special-files
+
+library(testthat)
+library(adbcflightsql)
+
+test_check("adbcflightsql")
diff --git a/r/adbcflightsql/tests/testthat/test-adbcflightsql-package.R b/r/adbcflightsql/tests/testthat/test-adbcflightsql-package.R
new file mode 100644
index 00000000..5ea333e7
--- /dev/null
+++ b/r/adbcflightsql/tests/testthat/test-adbcflightsql-package.R
@@ -0,0 +1,90 @@
+# 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.
+
+test_that("adbcflightsql() works", {
+  expect_s3_class(adbcflightsql(), "adbc_driver")
+})
+
+test_that("default options can open a database and execute a query", {
+  test_db_uri <- Sys.getenv("ADBC_FLIGHTSQL_TEST_URI", "")
+  skip_if(identical(test_db_uri, ""))
+
+  db <- adbcdrivermanager::adbc_database_init(
+    adbcflightsql(),
+    uri = test_db_uri
+  )
+  expect_s3_class(db, "adbcflightsql_database")
+
+  con <- adbcdrivermanager::adbc_connection_init(db)
+  expect_s3_class(con, "adbcflightsql_connection")
+
+  stmt <- adbcdrivermanager::adbc_statement_init(con)
+  expect_s3_class(stmt, "adbcflightsql_statement")
+
+  adbcdrivermanager::adbc_statement_set_sql_query(
+    stmt,
+    "CREATE TABLE crossfit (exercise TEXT, difficulty_level INTEGER)"
+  )
+  adbcdrivermanager::adbc_statement_execute_query(stmt)
+  adbcdrivermanager::adbc_statement_release(stmt)
+
+  # If we get this far, remove the table and disconnect when the test is done
+  on.exit({
+    stmt <- adbcdrivermanager::adbc_statement_init(con)
+    adbcdrivermanager::adbc_statement_set_sql_query(
+      stmt,
+      "DROP TABLE IF EXISTS crossfit;"
+    )
+    adbcdrivermanager::adbc_statement_execute_query(stmt)
+    adbcdrivermanager::adbc_statement_release(stmt)
+
+    adbcdrivermanager::adbc_connection_release(con)
+    adbcdrivermanager::adbc_database_release(db)
+  })
+
+  stmt <- adbcdrivermanager::adbc_statement_init(con)
+  adbcdrivermanager::adbc_statement_set_sql_query(
+    stmt,
+    "INSERT INTO crossfit values
+      ('Push Ups', 3),
+      ('Pull Ups', 5),
+      ('Push Jerk', 7),
+      ('Bar Muscle Up', 10);"
+  )
+  adbcdrivermanager::adbc_statement_execute_query(stmt)
+  adbcdrivermanager::adbc_statement_release(stmt)
+
+  stmt <- adbcdrivermanager::adbc_statement_init(con)
+  adbcdrivermanager::adbc_statement_set_sql_query(
+    stmt,
+    "SELECT * from crossfit"
+  )
+
+  stream <- nanoarrow::nanoarrow_allocate_array_stream()
+  adbcdrivermanager::adbc_statement_execute_query(stmt, stream)
+
+  expect_identical(
+    as.data.frame(stream),
+    data.frame(
+      exercise = c("Push Ups", "Pull Ups", "Push Jerk", "Bar Muscle Up"),
+      difficulty_level = c(3, 5, 7, 10),
+      stringsAsFactors = FALSE
+    )
+  )
+
+  adbcdrivermanager::adbc_statement_release(stmt)
+})
diff --git a/r/adbcflightsql/tools/download-go.R b/r/adbcflightsql/tools/download-go.R
new file mode 100644
index 00000000..3a9c40c7
--- /dev/null
+++ b/r/adbcflightsql/tools/download-go.R
@@ -0,0 +1,87 @@
+# 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.
+
+tmp_dir <- "src/go/tmp"
+
+go_version <- Sys.getenv("R_ADBC_GO_VERSION_DOWNLOAD", "1.19.9")
+
+go_platform <- tolower(Sys.info()[["sysname"]])
+if (!(go_platform %in% c("darwin", "linux", "windows"))) {
+  stop(sprintf("Go binary not available for os '%s'", go_platform))
+}
+
+r_arch <- R.version$arch
+if (identical(r_arch, "aarch64")) {
+  go_arch <- "arm64"
+} else if (identical(r_arch, "x86_64")) {
+  go_arch <- "amd64"
+} else if (identical(r_arch, "i386")) {
+  go_arch <- "386"
+} else {
+  stop(sprintf("Go binary not available for arch '%s'", r_arch))
+}
+
+if (identical(go_platform, "windows")) {
+  go_ext <- "zip"
+  go_bin <- paste0(tmp_dir, "/go/bin/go.exe")
+} else {
+  go_ext <- "tar.gz"
+  go_bin <- paste0(tmp_dir, "/go/bin/go")
+}
+
+archive_filename <- sprintf("go%s.%s-%s.%s",
+  go_version,
+  go_platform,
+  go_arch,
+  go_ext
+)
+
+archive_url <- sprintf("https://go.dev/dl/%s", archive_filename)
+archive_dest <- file.path(tmp_dir, archive_filename)
+
+if (!dir.exists(tmp_dir)) {
+  dir.create(tmp_dir)
+}
+
+if (!file.exists(archive_dest)) {
+  download.file(archive_url, archive_dest, mode = "wb")
+}
+
+# This step takes a while and there is no good way to communicate progress.
+# We need to make sure that if the user cancels that we delete the partially
+# extracted files (or else `go version`` passes but some parts of the standard
+# library may be missing)
+do_extract <- function() {
+  extract_completed <- FALSE
+  on.exit({
+    if (!extract_completed) {
+      unlink(file.path(tmp_dir, "go"), recursive = TRUE)
+    }
+  })
+
+  if (identical(go_ext, "zip")) {
+    unzip(archive_dest, exdir = tmp_dir)
+  } else {
+    stopifnot(untar(archive_dest, exdir = tmp_dir, verbose = TRUE) == 0L)
+  }
+
+  extract_completed <- TRUE
+}
+
+if (!file.exists(go_bin)) {
+  do_extract()
+}