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-nanoarrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 100ded67 feat(r): Add zstd decompression support to R package (#733)
100ded67 is described below

commit 100ded67605f41b68be90cd3ebb65533cb6e4773
Author: Dewey Dunnington <[email protected]>
AuthorDate: Sat Mar 29 14:31:15 2025 -0500

    feat(r): Add zstd decompression support to R package (#733)
    
    This PR adds support for ZSTD decompression when reading IPC streams.
    This works on R >= 4.0 although doesn't support ZSTD on 32-bit Windows
    or Linux where a user didn't install libzstd before installing the
    package. Another approach would be to vendor if the system lib isn't
    found, but I'll leave that as a battle for another day (if it ever comes
    up that somebody requests that support).
    
    ``` r
    library(nanoarrow)
    
    url <- 
"https://github.com/geoarrow/geoarrow-data/releases/download/v0.2.0-rc6/ns-water_water-point_wkb.arrows";
    read_nanoarrow(url) |> tibble::as_tibble()
    #> # A tibble: 44,690 × 8
    #>    OBJECTID FEAT_CODE ZVALUE PT_CLASS NAMEID_1 NAME_1 HID               
geometry
    #>       <dbl> <chr>      <dbl>    <int> <chr>    <chr>  <chr>              
 <blob>
    #>  1     1055 WARK60      -0.5        4 <NA>     <NA>   252C345D59374D… 
<raw 29 B>
    #>  2     1023 WARK60       0.6        4 <NA>     <NA>   1DAB1D800FB84E… 
<raw 29 B>
    #>  3     1021 WARK60       0.5        4 <NA>     <NA>   838438F1BBE745… 
<raw 29 B>
    #>  4      985 WARK60       0          4 <NA>     <NA>   0A4BE2AB03D845… 
<raw 29 B>
    #>  5      994 WARK60       1.9        4 <NA>     <NA>   6ACD71128B6B49… 
<raw 29 B>
    #>  6      995 WARK60       1.4        4 <NA>     <NA>   B10B26FA32FB44… 
<raw 29 B>
    #>  7      997 WARK60       1.1        4 <NA>     <NA>   28E47E22D71549… 
<raw 29 B>
    #>  8      993 WARK60       1.9        4 <NA>     <NA>   FC9A29123BEF4A… 
<raw 29 B>
    #>  9     1003 WARK60       0.7        4 <NA>     <NA>   3C7CA3CD0E8840… 
<raw 29 B>
    #> 10     1001 WARK60       0.7        4 <NA>     <NA>   A6F508B066DC4A… 
<raw 29 B>
    #> # ℹ 44,680 more rows
    ```
    
    <sup>Created on 2025-03-24 with [reprex
    v2.1.1](https://reprex.tidyverse.org)</sup>
---
 .github/workflows/r-check.yaml                |  8 +++-
 r/.Rbuildignore                               |  2 +-
 r/DESCRIPTION                                 |  1 +
 r/NAMESPACE                                   |  1 +
 r/R/ipc.R                                     | 63 ++++++++++++++++++++-------
 r/R/nanoarrow-package.R                       |  8 +++-
 r/configure                                   | 36 +++++++++++++--
 r/man/example_ipc_stream.Rd                   | 20 +++++++++
 r/man/nanoarrow_version.Rd                    |  5 ++-
 r/man/read_nanoarrow.Rd                       |  3 --
 r/src/.gitignore                              |  1 +
 r/src/{Makevars => Makevars.in}               |  4 +-
 r/{configure => src/Makevars.ucrt}            | 22 +++++-----
 r/{R/nanoarrow-package.R => src/Makevars.win} | 43 ++++++++----------
 r/src/as_array.c                              |  8 ++--
 r/src/init.c                                  |  2 +
 r/src/version.c                               |  8 ++++
 r/tests/testthat/test-ipc.R                   | 25 ++++++++---
 r/{src/version.c => tools/test_zstd.c}        | 18 ++++----
 19 files changed, 194 insertions(+), 84 deletions(-)

diff --git a/.github/workflows/r-check.yaml b/.github/workflows/r-check.yaml
index cc70e1ea..aaa308b0 100644
--- a/.github/workflows/r-check.yaml
+++ b/.github/workflows/r-check.yaml
@@ -40,7 +40,8 @@ jobs:
       matrix:
         config:
           - {os: macOS-latest,   r: 'release'}
-          - {os: windows-latest, r: '4.0'}
+          - {os: windows-latest, r: '4.1'}
+          - {os: windows-latest, r: '4.2'}
           - {os: windows-latest, r: 'release'}
           - {os: ubuntu-latest,   r: 'devel', http-user-agent: 'release'}
           - {os: ubuntu-latest,   r: 'release'}
@@ -83,3 +84,8 @@ jobs:
         with:
           upload-snapshots: true
           working-directory: r
+
+      - name: Show install output
+        if: always()
+        run: find r/check -name '00install.out*' -exec cat '{}' \; || true
+        shell: bash
diff --git a/r/.Rbuildignore b/r/.Rbuildignore
index a9b36934..03c55bc6 100644
--- a/r/.Rbuildignore
+++ b/r/.Rbuildignore
@@ -12,5 +12,5 @@
 ^bootstrap\.R$
 ^\.cache$
 ^compile_commands\.json$
+^src/Makevars$
 ^configure\.win$
-^configure$
diff --git a/r/DESCRIPTION b/r/DESCRIPTION
index 71dfc1ff..fd18b0c9 100644
--- a/r/DESCRIPTION
+++ b/r/DESCRIPTION
@@ -34,5 +34,6 @@ Suggests:
     tibble,
     vctrs,
     withr
+SystemRequirements: libzstd (optional)
 Config/testthat/edition: 3
 Config/build/bootstrap: TRUE
diff --git a/r/NAMESPACE b/r/NAMESPACE
index f1331649..a374be98 100644
--- a/r/NAMESPACE
+++ b/r/NAMESPACE
@@ -215,6 +215,7 @@ export(nanoarrow_schema_modify)
 export(nanoarrow_schema_parse)
 export(nanoarrow_vctr)
 export(nanoarrow_version)
+export(nanoarrow_with_zstd)
 export(read_nanoarrow)
 export(register_nanoarrow_extension)
 export(resolve_nanoarrow_extension)
diff --git a/r/R/ipc.R b/r/R/ipc.R
index 14f49f92..881b0f36 100644
--- a/r/R/ipc.R
+++ b/r/R/ipc.R
@@ -145,9 +145,20 @@ write_nanoarrow.character <- function(data, x, ...) {
   write_nanoarrow(data, con)
 }
 
-#' @rdname read_nanoarrow
+#' Example Arrow IPC Data
+#'
+#' An example stream that can be used for testing or examples.
+#'
+#' @param compression One of "none" or "zstd"
+#'
+#' @return A raw vector that can be passed to [read_nanoarrow()]
 #' @export
-example_ipc_stream <- function() {
+#'
+#' @examples
+#' as.data.frame(read_nanoarrow(example_ipc_stream()))
+example_ipc_stream <- function(compression = c("none", "zstd")) {
+  compression <- match.arg(compression)
+
   # data.frame(some_col = c(1L, 2L, 3L)) as a serialized schema/batch
   schema <- as.raw(c(
     0xff, 0xff, 0xff, 0xff, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
0x00, 0x00,
@@ -172,20 +183,40 @@ example_ipc_stream <- function() {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00
   ))
 
-  batch <- as.raw(c(
-    0xff, 0xff, 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 
0x00, 0x00,
-    0x00, 0x00, 0x0c, 0x00, 0x16, 0x00, 0x06, 0x00, 0x05, 0x00, 0x08, 0x00, 
0x0c, 0x00,
-    0x0c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 
0x10, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x18, 0x00, 
0x0c, 0x00,
-    0x04, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
0x10, 0x00,
-    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
-    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
-    0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x01, 0x00,
-    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
0x03, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-  ))
+  if (identical(compression, "zstd")) {
+    batch <- as.raw(c(
+      0xff, 0xff, 0xff, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x06, 0x00, 0x05, 0x00, 0x08, 0x00, 
0x0c, 0x00,
+      0x0c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 
0x20, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 
0x1e, 0x00,
+      0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 
0x50, 0x00,
+      0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 
0x08, 0x00,
+      0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
0x03, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xb5, 0x2f, 0xfd, 
0x20, 0x0c,
+      0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 
0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00
+    ))
+  } else {
+    batch <- as.raw(c(
+      0xff, 0xff, 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x0c, 0x00, 0x16, 0x00, 0x06, 0x00, 0x05, 0x00, 0x08, 0x00, 
0x0c, 0x00,
+      0x0c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 
0x10, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x18, 0x00, 
0x0c, 0x00,
+      0x04, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
0x10, 0x00,
+      0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x01, 0x00,
+      0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
0x02, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    ))
+  }
 
   c(schema, batch)
 }
diff --git a/r/R/nanoarrow-package.R b/r/R/nanoarrow-package.R
index 4c5511a8..e2bd3c60 100644
--- a/r/R/nanoarrow-package.R
+++ b/r/R/nanoarrow-package.R
@@ -35,7 +35,7 @@ NULL
 #'
 #' @examples
 #' nanoarrow_version()
-#'
+#' nanoarrow_with_zstd()
 nanoarrow_version <- function(runtime = TRUE) {
   if (runtime) {
     .Call(nanoarrow_c_version_runtime)
@@ -43,3 +43,9 @@ nanoarrow_version <- function(runtime = TRUE) {
     .Call(nanoarrow_c_version)
   }
 }
+
+#' @rdname nanoarrow_version
+#' @export
+nanoarrow_with_zstd <- function() {
+  .Call(nanoarrow_c_with_zstd)
+}
diff --git a/r/configure b/r/configure
index 07777590..301bb4d1 100755
--- a/r/configure
+++ b/r/configure
@@ -23,9 +23,37 @@ fi
 
 if [ -f "src/nanoarrow.h" ] && [ -f "src/nanoarrow.c" ]; then
   echo "Found vendored nanoarrow"
-  exit 0
+else
+  echo "Vendored src/nanoarrow.h and/or src/nanoarrow.c are missing"
+  echo "This source tarball was built incorrectly."
+  exit 1
 fi
 
-echo "Vendored src/nanoarrow.h and/or src/nanoarrow.c are missing"
-echo "This source tarball was built incorrectly."
-exit 1
+# Check to see if a zstd test file compiles and links without any help from 
pkg-config
+ZSTD_FOUND=""
+PKG_CPPFLAGS="$PKG_CPPFLAGS" PKG_LIBS="$PKG_LIBS -lzstd" \
+  $R_HOME/bin/R CMD SHLIB tools/test_zstd.c -o test_zstd >test_zstd.log 2>&1
+if [ $? -eq 0 ]; then
+  echo "tools/test_zstd.c compiled without error"
+  PKG_CPPFLAGS="$PKG_CPPFLAGS -DNANOARROW_IPC_WITH_ZSTD"
+  PKG_LIBS="$PKG_LIBS -lzstd"
+  ZSTD_FOUND="yes"
+fi
+
+# Add pkg-config for libzstd if possible
+if [ -z "$ZSTD_FOUND" ] && pkg-config libzstd --exists >/dev/null 2>&1; then
+  PKG_CPPFLAGS="`pkg-config libzstd --cflags` -DNANOARROW_IPC_WITH_ZSTD 
$PKG_CPPFLAGS"
+  PKG_LIBS="`pkg-config libzstd --libs` $PKG_LIBS"
+  echo "Using pkg-config libzstd"
+  ZSTD_FOUND="yes"
+fi
+
+rm -f tools/test_zstd.o test_zstd test_zstd.log || true
+
+echo "Using PKG_CPPFLAGS=$PKG_CPPFLAGS"
+echo "Using PKG_LIBS=$PKG_LIBS"
+
+sed \
+  -e "s|@cppflags@|$PKG_CPPFLAGS|" \
+  -e "s|@libs@|$PKG_LIBS|" \
+  src/Makevars.in > src/Makevars
diff --git a/r/man/example_ipc_stream.Rd b/r/man/example_ipc_stream.Rd
new file mode 100644
index 00000000..14ad124c
--- /dev/null
+++ b/r/man/example_ipc_stream.Rd
@@ -0,0 +1,20 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/ipc.R
+\name{example_ipc_stream}
+\alias{example_ipc_stream}
+\title{Example Arrow IPC Data}
+\usage{
+example_ipc_stream(compression = c("none", "zstd"))
+}
+\arguments{
+\item{compression}{One of "none" or "zstd"}
+}
+\value{
+A raw vector that can be passed to 
\code{\link[=read_nanoarrow]{read_nanoarrow()}}
+}
+\description{
+An example stream that can be used for testing or examples.
+}
+\examples{
+as.data.frame(read_nanoarrow(example_ipc_stream()))
+}
diff --git a/r/man/nanoarrow_version.Rd b/r/man/nanoarrow_version.Rd
index 18f9efcf..00fd3097 100644
--- a/r/man/nanoarrow_version.Rd
+++ b/r/man/nanoarrow_version.Rd
@@ -2,9 +2,12 @@
 % Please edit documentation in R/nanoarrow-package.R
 \name{nanoarrow_version}
 \alias{nanoarrow_version}
+\alias{nanoarrow_with_zstd}
 \title{Underlying 'nanoarrow' C library build}
 \usage{
 nanoarrow_version(runtime = TRUE)
+
+nanoarrow_with_zstd()
 }
 \arguments{
 \item{runtime}{Compare TRUE and FALSE values to detect a
@@ -19,5 +22,5 @@ Underlying 'nanoarrow' C library build
 }
 \examples{
 nanoarrow_version()
-
+nanoarrow_with_zstd()
 }
diff --git a/r/man/read_nanoarrow.Rd b/r/man/read_nanoarrow.Rd
index cf4d423e..f23436d7 100644
--- a/r/man/read_nanoarrow.Rd
+++ b/r/man/read_nanoarrow.Rd
@@ -3,14 +3,11 @@
 \name{read_nanoarrow}
 \alias{read_nanoarrow}
 \alias{write_nanoarrow}
-\alias{example_ipc_stream}
 \title{Read/write serialized streams of Arrow data}
 \usage{
 read_nanoarrow(x, ..., lazy = FALSE)
 
 write_nanoarrow(data, x, ...)
-
-example_ipc_stream()
 }
 \arguments{
 \item{x}{A \code{raw()} vector, connection, or file path from which to read
diff --git a/r/src/.gitignore b/r/src/.gitignore
index 9d89d07a..c5bf0ca6 100644
--- a/r/src/.gitignore
+++ b/r/src/.gitignore
@@ -23,3 +23,4 @@ nanoarrow.h
 nanoarrow_ipc.h
 nanoarrow_ipc.c
 flatcc*
+Makevars
diff --git a/r/src/Makevars b/r/src/Makevars.in
similarity index 96%
rename from r/src/Makevars
rename to r/src/Makevars.in
index 045201a9..eb0e4edf 100644
--- a/r/src/Makevars
+++ b/r/src/Makevars.in
@@ -19,4 +19,6 @@
 # that do not provide aligned_alloc. Allocating flatbuffers memory is not
 # performance-critical for what we do in the nanoarrow R package (and may not
 # occur at all until IPC write support is added)
-PKG_CPPFLAGS=-I../inst/include -I../src -DFLATCC_USE_GENERIC_ALIGNED_ALLOC
+
+PKG_CPPFLAGS=-I../inst/include -I../src -DFLATCC_USE_GENERIC_ALIGNED_ALLOC 
@cppflags@
+PKG_LIBS=@libs@
diff --git a/r/configure b/r/src/Makevars.ucrt
old mode 100755
new mode 100644
similarity index 63%
copy from r/configure
copy to r/src/Makevars.ucrt
index 07777590..e9abf967
--- a/r/configure
+++ b/r/src/Makevars.ucrt
@@ -15,17 +15,15 @@
 # specific language governing permissions and limitations
 # under the License.
 
-# If we are building from within the nanoarrow repo, bootstrap.R will (1)
-# exist and (2) perform the necessary vendoring steps
-if [ -f bootstrap.R ]; then
-  $R_HOME/bin/Rscript bootstrap.R
-fi
+# This Makevars handles R >= 4.2 on Windows (pkg-config is available on all 
such versions)
 
-if [ -f "src/nanoarrow.h" ] && [ -f "src/nanoarrow.c" ]; then
-  echo "Found vendored nanoarrow"
-  exit 0
-fi
+ifeq (,$(shell pkg-config libzstd --libs 2>/dev/null))
+  ZSTD_CFLAGS =
+  ZSTD_LIB_FLAGS =
+else
+  ZSTD_CFLAGS = $(shell pkg-config --cflags libzstd) -DNANOARROW_IPC_WITH_ZSTD
+  ZSTD_LIB_FLAGS = $(shell pkg-config --libs libzstd)
+endif
 
-echo "Vendored src/nanoarrow.h and/or src/nanoarrow.c are missing"
-echo "This source tarball was built incorrectly."
-exit 1
+PKG_CPPFLAGS = -I../inst/include -I../src -DFLATCC_USE_GENERIC_ALIGNED_ALLOC 
$(ZSTD_CFLAGS)
+PKG_LIBS = $(ZSTD_LIB_FLAGS)
diff --git a/r/R/nanoarrow-package.R b/r/src/Makevars.win
similarity index 54%
copy from r/R/nanoarrow-package.R
copy to r/src/Makevars.win
index 4c5511a8..7efd4791 100644
--- a/r/R/nanoarrow-package.R
+++ b/r/src/Makevars.win
@@ -15,31 +15,22 @@
 # specific language governing permissions and limitations
 # under the License.
 
-#' @keywords internal
-"_PACKAGE"
+# This Makevars handles R 4.0 and 4.1 on Windows. These packages are no longer 
built
+# by CRAN, but on GitHub Actions pkg-config seems to be able to resolve and 
link a
+# zstd that works on 64-bit (but not 32-bit).
 
-## usethis namespace: start
-#' @importFrom utils getFromNamespace
-#' @useDynLib nanoarrow, .registration = TRUE
-## usethis namespace: end
-NULL
+ifeq (,$(shell pkg-config libzstd --libs 2>/dev/null))
+  ZSTD_CFLAGS =
+  ZSTD_LIB_FLAGS =
+else
+  ifeq "$(WIN)" "64"
+    ZSTD_CFLAGS = $(shell pkg-config --cflags libzstd) 
-DNANOARROW_IPC_WITH_ZSTD
+    ZSTD_LIB_FLAGS = $(shell pkg-config --libs libzstd)
+  else
+    ZSTD_CFLAGS =
+    ZSTD_LIB_FLAGS =
+  endif
+endif
 
-#' Underlying 'nanoarrow' C library build
-#'
-#' @param runtime Compare TRUE and FALSE values to detect a
-#'   possible ABI mismatch.
-#'
-#' @return A string identifying the version of nanoarrow this package
-#'   was compiled against.
-#' @export
-#'
-#' @examples
-#' nanoarrow_version()
-#'
-nanoarrow_version <- function(runtime = TRUE) {
-  if (runtime) {
-    .Call(nanoarrow_c_version_runtime)
-  } else {
-    .Call(nanoarrow_c_version)
-  }
-}
+PKG_CPPFLAGS = -I../inst/include -I../src -DFLATCC_USE_GENERIC_ALIGNED_ALLOC 
$(ZSTD_CFLAGS)
+PKG_LIBS = $(ZSTD_LIB_FLAGS)
diff --git a/r/src/as_array.c b/r/src/as_array.c
index 24926ee6..8790013d 100644
--- a/r/src/as_array.c
+++ b/r/src/as_array.c
@@ -406,12 +406,14 @@ static void as_decimal_array(SEXP x_sexp, struct 
ArrowArray* array, SEXP schema_
     } else {
       item_digits_view.data = CHAR(item_sexp);
       item_digits_view.size_bytes = Rf_length(item_sexp);
-      ArrowDecimalSetDigits(&item, item_digits_view);
-      result = ArrowArrayAppendDecimal(array, &item);
+      result = ArrowDecimalSetDigits(&item, item_digits_view);
+      if (result == NANOARROW_OK) {
+        result = ArrowArrayAppendDecimal(array, &item);
+      }
     }
 
     if (result != NANOARROW_OK) {
-      Rf_error("ArrowArrayAppendDecimal() failed");
+      Rf_error("ArrowArrayAppendDecimal() or ArrowDecimalSetDigits() failed");
     }
   }
 
diff --git a/r/src/init.c b/r/src/init.c
index 58fe9f83..e3288dd4 100644
--- a/r/src/init.c
+++ b/r/src/init.c
@@ -98,6 +98,7 @@ extern SEXP nanoarrow_c_vctr_chunk_resolve(SEXP indices_sexp, 
SEXP offsets_sexp)
 extern SEXP nanoarrow_c_vctr_as_slice(SEXP indices_sexp);
 extern SEXP nanoarrow_c_version(void);
 extern SEXP nanoarrow_c_version_runtime(void);
+extern SEXP nanoarrow_c_with_zstd(void);
 
 static const R_CallMethodDef CallEntries[] = {
     {"nanoarrow_c_make_altrep_chr", (DL_FUNC)&nanoarrow_c_make_altrep_chr, 1},
@@ -178,6 +179,7 @@ static const R_CallMethodDef CallEntries[] = {
     {"nanoarrow_c_vctr_as_slice", (DL_FUNC)&nanoarrow_c_vctr_as_slice, 1},
     {"nanoarrow_c_version", (DL_FUNC)&nanoarrow_c_version, 0},
     {"nanoarrow_c_version_runtime", (DL_FUNC)&nanoarrow_c_version_runtime, 0},
+    {"nanoarrow_c_with_zstd", (DL_FUNC)&nanoarrow_c_with_zstd, 0},
     {NULL, NULL, 0}};
 /* end generated by tools/make-callentries.R */
 
diff --git a/r/src/version.c b/r/src/version.c
index c099bde2..36095770 100644
--- a/r/src/version.c
+++ b/r/src/version.c
@@ -24,3 +24,11 @@
 SEXP nanoarrow_c_version(void) { return Rf_mkString(NANOARROW_VERSION); }
 
 SEXP nanoarrow_c_version_runtime(void) { return 
Rf_mkString(ArrowNanoarrowVersion()); }
+
+SEXP nanoarrow_c_with_zstd(void) {
+#if defined(NANOARROW_IPC_WITH_ZSTD)
+  return Rf_ScalarLogical(1);
+#else
+  return Rf_ScalarLogical(0);
+#endif
+}
diff --git a/r/tests/testthat/test-ipc.R b/r/tests/testthat/test-ipc.R
index 8a4c2bfe..ebf6bfd0 100644
--- a/r/tests/testthat/test-ipc.R
+++ b/r/tests/testthat/test-ipc.R
@@ -20,7 +20,7 @@ test_that("read_nanoarrow() works for raw vectors", {
   expect_s3_class(stream, "nanoarrow_array_stream")
   expect_identical(
     as.data.frame(stream),
-    data.frame(some_col = c(1L, 2L, 3L))
+    data.frame(some_col = c(0L, 1L, 2L))
   )
 })
 
@@ -32,7 +32,7 @@ test_that("read_nanoarrow() works for open connections", {
   expect_s3_class(stream, "nanoarrow_array_stream")
   expect_identical(
     as.data.frame(stream),
-    data.frame(some_col = c(1L, 2L, 3L))
+    data.frame(some_col = c(0L, 1L, 2L))
   )
 })
 
@@ -95,7 +95,7 @@ test_that("read_nanoarrow() works for file paths", {
   stream <- read_nanoarrow(tf)
   expect_identical(
     as.data.frame(stream),
-    data.frame(some_col = c(1L, 2L, 3L))
+    data.frame(some_col = c(0L, 1L, 2L))
   )
 })
 
@@ -119,7 +119,18 @@ test_that("read_nanoarrow() works for URLs", {
   stream <- read_nanoarrow(paste0("file://", tf))
   expect_identical(
     as.data.frame(stream),
-    data.frame(some_col = c(1L, 2L, 3L))
+    data.frame(some_col = c(0L, 1L, 2L))
+  )
+})
+
+test_that("read_nanoarrow() works with buffer compression", {
+  skip_if_not(nanoarrow_with_zstd())
+
+  stream <- read_nanoarrow(example_ipc_stream(compression = "zstd"))
+  expect_s3_class(stream, "nanoarrow_array_stream")
+  expect_identical(
+    as.data.frame(stream),
+    data.frame(some_col = c(0L, 1L, 2L))
   )
 })
 
@@ -143,7 +154,7 @@ test_that("read_nanoarrow() works for compressed .gz file 
paths", {
   stream <- read_nanoarrow(tf)
   expect_identical(
     as.data.frame(stream),
-    data.frame(some_col = c(1L, 2L, 3L))
+    data.frame(some_col = c(0L, 1L, 2L))
   )
 })
 
@@ -167,7 +178,7 @@ test_that("read_nanoarrow() works for compressed .bz2 file 
paths", {
   stream <- read_nanoarrow(tf)
   expect_identical(
     as.data.frame(stream),
-    data.frame(some_col = c(1L, 2L, 3L))
+    data.frame(some_col = c(0L, 1L, 2L))
   )
 })
 
@@ -204,7 +215,7 @@ test_that("read_nanoarrow() works for compressed .zip file 
paths", {
   stream <- read_nanoarrow(tf)
   expect_identical(
     as.data.frame(stream),
-    data.frame(some_col = c(1L, 2L, 3L))
+    data.frame(some_col = c(0L, 1L, 2L))
   )
 })
 
diff --git a/r/src/version.c b/r/tools/test_zstd.c
similarity index 73%
copy from r/src/version.c
copy to r/tools/test_zstd.c
index c099bde2..74089114 100644
--- a/r/src/version.c
+++ b/r/tools/test_zstd.c
@@ -15,12 +15,14 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#define R_NO_REMAP
-#include <R.h>
-#include <Rinternals.h>
+#include <stdint.h>
+#include <string.h>
+#include <zstd.h>
 
-#include "nanoarrow.h"
-
-SEXP nanoarrow_c_version(void) { return Rf_mkString(NANOARROW_VERSION); }
-
-SEXP nanoarrow_c_version_runtime(void) { return 
Rf_mkString(ArrowNanoarrowVersion()); }
+// Function that requires at least one symbol from zstd.h
+size_t test_zstd(void) {
+  uint8_t src[128];
+  memset(src, 0, sizeof(src));
+  uint8_t dst[128];
+  return ZSTD_compress(dst, sizeof(dst), src, sizeof(src), 
ZSTD_CLEVEL_DEFAULT);
+}

Reply via email to