#r #dplyr #tidyr #dbplyr #duckdb
Вопрос:
Следующий пример из документов tidyr::expand()
работает, как и ожидалось, на локальном фрейме данных в памяти. Тот же пример работает с tbl_dbi
объектом при вызове в одном столбце, но отображает ошибку синтаксического анализа SQL при применении к нескольким столбцам:
library(tidyverse, quietly = TRUE)
library(duckdb, quietly = TRUE)
fruits <- tibble(
type = c("apple", "orange", "apple", "orange", "orange", "orange"),
year = c(2010, 2010, 2012, 2010, 2010, 2012),
size = factor(
c("XS", "S", "M", "S", "S", "M"),
levels = c("XS", "S", "M", "L")
),
weights = rnorm(6, as.numeric(size) 2)
)
fruits %>% tidyr::expand(type, size)
#> # A tibble: 8 × 2
#> type size
#> <chr> <fct>
#> 1 apple XS
#> 2 apple S
#> 3 apple M
#> 4 apple L
#> 5 orange XS
#> 6 orange S
#> 7 orange M
#> 8 orange L
## now create a remote tbl
con <- dbConnect(duckdb::duckdb())
dbWriteTable(con, "fruits", fruits)
fruits_db <- tbl(con, "fruits")
## same command works with one column:
fruits_db %>% tidyr::expand(type)
#> # Source: lazy query [?? x 1]
#> # Database: duckdb_connection
#> type
#> <chr>
#> 1 apple
#> 2 orange
## but fails with two:
fruits_db %>% tidyr::expand(type, size)
#> Error in .local(conn, statement, ...): duckdb_prepare_R: Failed to prepare query SELECT *
#> FROM (SELECT "type", "size"
#> FROM (SELECT DISTINCT "type"
#> FROM "fruits") "LHS"
#> LEFT JOIN (SELECT DISTINCT "size"
#> FROM "fruits") "RHS"
#> ) "q01"
#> LIMIT 11
#> Error: Parser Error: syntax error at or near ")"
#> LINE 7: ) "q01"
#> ^
Создано 2021-10-01 пакетом reprex (v2.0.1)
Почему это происходит и как мы можем этого избежать? (Мне кажется, что к концу SQL, сгенерированного переводом tidyr, прикрепляется очень ложный «q01», но я понятия не имею, почему это должно быть так и почему это произойдет только в случае расширения с двумя столбцами).
Я подозреваю, что это ошибка, но в данном контексте я не уверен, как лучше определить источник ошибки-т. Е. Проблема связана с ошибкой в duckdb
, dbplyr
tidyr
, или с каким-либо другим компонентом перевода?
Комментарии:
1. Вероятно, сгенерированный синтаксис может не работать в duckdb. Я попробовал то же самое с
sqlite
, и это работает нормальноfruits_db2 %>% tidyr::expand(type, size) # Source: lazy query [?? x 2] # Database: sqlite 3.35.5 [:memory:]
2. Единственное отличие
show_query
, которое я нахожу, — это двойная кавычка по сравнению с размеромSELECT
типа,
обратной кавычки «ОТ (ВЫБЕРИТЕ ОТДЕЛЬНЫЙtype`` in sqlite and
, ВЫБЕРИТЕ» тип»,» размер » ОТ (ВЫБЕРИТЕ ОТДЕЛЬНЫЙ «тип»` и в duckdb3. Я попробовал этот запрос за пределами расширения, но он все еще выдает ошибку, так что, возможно, это не реализовано
dbGetQuery(con, "SELECT type, size FROM (SELECT DISTINCT type FROM fruits) AS LHS LEFT JOIN (SELECT DISTINCT size FROM fruits) AS RHS")
4. Спасибо @akrun . Я сообщил об этом разработчикам duckdb, github.com/duckdb/duckdb/issues/2362 , хотя это звучит так, как будто
dbplyr
может генерировать несовершенный синтаксис SQL (СОЕДИНЕНИЕ без включения), которое SQLite решает считать на самом деле ПЕРЕКРЕСТНЫМ СОЕДИНЕНИЕМ?