ITADN

as.double() / as.numeric() treated as "AS NUMERIC" by the dplyr backend

#2023Closedlentinj 创建于 2026-01-30
L
lentinjcommented
When using dplyr, ``as.numeric()``/``as.double()`` is converted to ``AS NUMERIC``. In duckdb, NUMERIC is an [alias to DECIMAL(18, 3)](https://duckdb.org/docs/stable/sql/data_types/overview#general-purpose-data-types). Similar to other databases (https://github.com/tidyverse/dbplyr/issues/379, https://github.com/tidyverse/dbplyr/issues/408), ``AS DOUBLE`` would be a better fit to what is expected: ```r > packageVersion("duckdb") [1] ‘1.4.0’ > packageVersion("dplyr") [1] ‘1.1.4’ > packageVersion("dbplyr") [1] ‘2.5.1’ > packageVersion("duckdb") [1] ‘1.4.0’ > > con <- DBI::dbConnect(duckdb::duckdb(), ":memory:") > > # Write a double to a table first > DBI::dbWriteTable(con, "table", data.frame(a = c(0.0091792656587473))) > > # Casting the value gives surprising results > dplyr::tbl(con, "table") |> dplyr::mutate(b = a * 1e6, c = as.double(a) * 1e6) # Source: SQL [?? x 3] # Database: DuckDB 1.4.0 [lentinj@Linux 6.17.13+deb14-amd64:R 4.5.2/:memory:] a b c <dbl> <dbl> <dbl> 1 0.00918 9179. 9000 > dplyr::tbl(con, "table") |> dplyr::mutate(b = a * 1e6, c = as.double(a) * 1e6) |> dplyr::show_query() <SQL> SELECT "table".*, a * 1000000.0 AS b, CAST(a AS NUMERIC) * 1000000.0 AS c FROM "table" ``` That said, there are tests explicitly for this so maybe I'm missing something very obvious? https://github.com/duckdb/duckdb-r/blob/277776ebf40058a67f4909b0f616645a22e6a71f/tests/testthat/test-backend-dbplyr__duckdb_connection.R#L9-L10 Adding something along these lines into backend-dbplyr__duckdb_connection.R should help: https://github.com/tidyverse/dbplyr/blob/ce9c71188cb9b5d676bc7c99f83f001edef9221e/R/backend-redshift.R#L68-L69 https://github.com/duckdb/duckdb-r/issues/1585 is also related, although that is purely about ``Inf``, some of the tests there are stumbling on this too.
关闭于 2026-02-27 0 条评论