From cefc8e84a20467ba2247febf2c1fe70010eff537 Mon Sep 17 00:00:00 2001 From: eitsupi Date: Fri, 20 Sep 2024 13:47:39 +0000 Subject: [PATCH] feat!: rewrite the `prql_compile()` function --- DESCRIPTION | 2 +- R/000-wrappers.R | 4 ++-- R/compile.R | 28 +++++++++++++++-------- man/prql_compile.Rd | 24 +++++++++++--------- src/init.c | 6 ++--- src/rust/Cargo.lock | 3 +-- src/rust/Cargo.toml | 3 +-- src/rust/api.h | 2 +- src/rust/src/lib.rs | 38 +++++++++++++------------------- tests/testthat/_snaps/compile.md | 37 ++++++++++++++++--------------- tests/testthat/test-compile.R | 17 ++++++++------ tools/lib-sums.tsv | 6 ----- 12 files changed, 86 insertions(+), 84 deletions(-) delete mode 100644 tools/lib-sums.tsv diff --git a/DESCRIPTION b/DESCRIPTION index ac36e7e..42a86b1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -47,4 +47,4 @@ Config/Needs/dev: rhub Config/Needs/website: pkgdown -Config/prqlr/LibVersion: 0.13.0 +Config/prqlr/LibVersion: 0.13.1 diff --git a/R/000-wrappers.R b/R/000-wrappers.R index a17fd14..cdec695 100644 --- a/R/000-wrappers.R +++ b/R/000-wrappers.R @@ -30,8 +30,8 @@ NULL #' @param signature_comment a logical flag. Whether to add a signature comment to the output SQL query. #' @return a list contains a SQL string or an error message. #' @noRd -`compile` <- function(`prql_query`, `target`, `format`, `signature_comment`) { - .Call(savvy_compile__impl, `prql_query`, `target`, `format`, `signature_comment`) +`compile` <- function(`prql_query`, `target`, `format`, `signature_comment`, `display`) { + .Call(savvy_compile__impl, `prql_query`, `target`, `format`, `signature_comment`, `display`) } #' @noRd diff --git a/R/compile.R b/R/compile.R index c673f9b..65b6f9d 100644 --- a/R/compile.R +++ b/R/compile.R @@ -1,13 +1,15 @@ #' @title Compile a PRQL query into a SQL query -#' @param prql_query a PRQL query string. -#' @param target a compile target name to use. If not specified (`NULL`), -#' the target contained in the query will be used. -#' All available target names can be listed with the [prql_get_targets] function. -#' @param format a logical flag (default: `TRUE`). Whether to format the SQL query. +#' @param prql_query A character of PRQL query. +#' @param target A character of the target name to use or `NULL`. +#' If `NULL`, the target contained in the query will be used. +#' All available target names can be listed with the [prql_get_targets()] function. +#' @param ... Ignored. +#' @param format A logical flag (default: `TRUE`). Whether to format the SQL query. #' @param signature_comment a logical flag. (default: `TRUE`). #' Whether to add a signature comment to the output SQL query. -#' @return a SQL query string -#' @seealso [prql_get_targets] +#' @param display A character, one of `"plain"` (default) or `"ansi_color"`. +#' If `"ansi_color"`, error will be displayed with ANSI color. +#' @return A character of the compiled SQL query. #' @examples #' "from mtcars | filter cyl > 6 | select {cyl, mpg}" |> #' prql_compile() @@ -37,10 +39,18 @@ #' @export prql_compile <- function( prql_query, + ..., target = getOption("prqlr.target", default = NULL), format = getOption("prqlr.format", default = TRUE), - signature_comment = getOption("prqlr.signature_comment", default = TRUE)) { - compile(prql_query, target %||% "sql.any", format, signature_comment) + signature_comment = getOption("prqlr.signature_comment", default = TRUE), + display = getOption("prqlr.display", default = "plain")) { + compile( + prql_query, + target = target %||% "sql.any", + format = format, + signature_comment = signature_comment, + display = display + ) } #' @title prqlc's version diff --git a/man/prql_compile.Rd b/man/prql_compile.Rd index 70f79f4..aa3123d 100644 --- a/man/prql_compile.Rd +++ b/man/prql_compile.Rd @@ -6,25 +6,32 @@ \usage{ prql_compile( prql_query, + ..., target = getOption("prqlr.target", default = NULL), format = getOption("prqlr.format", default = TRUE), - signature_comment = getOption("prqlr.signature_comment", default = TRUE) + signature_comment = getOption("prqlr.signature_comment", default = TRUE), + display = getOption("prqlr.display", default = "plain") ) } \arguments{ -\item{prql_query}{a PRQL query string.} +\item{prql_query}{A character of PRQL query.} -\item{target}{a compile target name to use. If not specified (\code{NULL}), -the target contained in the query will be used. -All available target names can be listed with the \link{prql_get_targets} function.} +\item{...}{Ignored.} -\item{format}{a logical flag (default: \code{TRUE}). Whether to format the SQL query.} +\item{target}{A character of the target name to use or \code{NULL}. +If \code{NULL}, the target contained in the query will be used. +All available target names can be listed with the \code{\link[=prql_get_targets]{prql_get_targets()}} function.} + +\item{format}{A logical flag (default: \code{TRUE}). Whether to format the SQL query.} \item{signature_comment}{a logical flag. (default: \code{TRUE}). Whether to add a signature comment to the output SQL query.} + +\item{display}{A character, one of \code{"plain"} (default) or \code{"ansi_color"}. +If \code{"ansi_color"}, error will be displayed with ANSI color.} } \value{ -a SQL query string +A character of the compiled SQL query. } \description{ Compile a PRQL query into a SQL query @@ -56,6 +63,3 @@ select !{cyl} prql_compile() |> cat() } -\seealso{ -\link{prql_get_targets} -} diff --git a/src/init.c b/src/init.c index d776e1d..62b7e14 100644 --- a/src/init.c +++ b/src/init.c @@ -34,8 +34,8 @@ SEXP handle_result(SEXP res_) { return (SEXP)res; } -SEXP savvy_compile__impl(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment) { - SEXP res = savvy_compile__ffi(c_arg__prql_query, c_arg__target, c_arg__format, c_arg__signature_comment); +SEXP savvy_compile__impl(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment, SEXP c_arg__display) { + SEXP res = savvy_compile__ffi(c_arg__prql_query, c_arg__target, c_arg__format, c_arg__signature_comment, c_arg__display); return handle_result(res); } @@ -66,7 +66,7 @@ SEXP savvy_prql_get_targets__impl(void) { static const R_CallMethodDef CallEntries[] = { - {"savvy_compile__impl", (DL_FUNC) &savvy_compile__impl, 4}, + {"savvy_compile__impl", (DL_FUNC) &savvy_compile__impl, 5}, {"savvy_prql_to_pl__impl", (DL_FUNC) &savvy_prql_to_pl__impl, 1}, {"savvy_pl_to_rq__impl", (DL_FUNC) &savvy_pl_to_rq__impl, 1}, {"savvy_rq_to_sql__impl", (DL_FUNC) &savvy_rq_to_sql__impl, 1}, diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index fb52d08..9344747 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -401,9 +401,8 @@ dependencies = [ [[package]] name = "prqlr" -version = "0.13.0" +version = "0.13.1" dependencies = [ - "anstream", "prqlc", "savvy", ] diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 015a0a2..47b2e47 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prqlr" -version = "0.13.0" +version = "0.13.1" edition = "2021" rust-version = "1.69" publish = false @@ -15,4 +15,3 @@ savvy = "0.6.8" # prqlc 0.13.0 is not compatible with Rust 1.69.0, so a slightly modified version is installed # See https://github.com/PRQL/prql/pull/4916 prqlc = { git = "https://github.com/PRQL/prql", rev = "c7bd7a6fc73040394ffbbd85cea2ed6f986fd9dd", default-features = false } -anstream = { version = "0", features = ["auto"] } diff --git a/src/rust/api.h b/src/rust/api.h index 8e5b617..487d6d4 100644 --- a/src/rust/api.h +++ b/src/rust/api.h @@ -1,4 +1,4 @@ -SEXP savvy_compile__ffi(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment); +SEXP savvy_compile__ffi(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment, SEXP c_arg__display); SEXP savvy_prql_to_pl__ffi(SEXP c_arg__prql_query); SEXP savvy_pl_to_rq__ffi(SEXP c_arg__pl_json); SEXP savvy_rq_to_sql__ffi(SEXP c_arg__rq_json); diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index a9d796b..eea4909 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -1,4 +1,4 @@ -use anstream::ColorChoice; +use prqlc::ErrorMessages; use savvy::{savvy, Sexp}; use std::str::FromStr; @@ -15,48 +15,40 @@ pub fn compile( target: &str, format: bool, signature_comment: bool, + display: &str, ) -> savvy::Result { let options = convert_options(CompileOptions { format, target: target.to_string(), signature_comment, - }); - - let result = options - .and_then(|opts| { - Ok(prql_query) - .and_then(prqlc::prql_to_pl) - .and_then(prqlc::pl_to_rq) - .and_then(|rq| prqlc::rq_to_sql(rq, &opts)) - }) - .map_err(|e| e.composed(&prql_query.into())); - - ColorChoice::write_global(self::ColorChoice::Never); + display: display.to_string(), + }) + .map_err(|e| e.to_string())?; - match result { - Ok(msg) => msg.try_into(), - Err(e) => Err(e.to_string().into()), - } + prqlc::compile(prql_query, &options) + .map_err(|e| savvy::Error::from(e.to_string())) + .and_then(|x| x.try_into()) } struct CompileOptions { format: bool, target: String, signature_comment: bool, + display: String, } -fn convert_options( - o: CompileOptions, -) -> core::result::Result { - let target = prqlc::Target::from_str(&o.target).map_err(prqlc::ErrorMessages::from)?; +fn convert_options(o: CompileOptions) -> core::result::Result { + let target = prqlc::Target::from_str(&o.target).map_err(ErrorMessages::from)?; + let display = prqlc::DisplayOptions::from_str(&o.display).map_err(|e| ErrorMessages { + inner: vec![prqlc::Error::new_simple(format!("Invalid display option: {}", e)).into()], + })?; - // TODO: support `display` option Ok(prqlc::Options { format: o.format, target, signature_comment: o.signature_comment, color: false, - ..std::default::Default::default() + display, }) } diff --git a/tests/testthat/_snaps/compile.md b/tests/testthat/_snaps/compile.md index 44ee73c..979d497 100644 --- a/tests/testthat/_snaps/compile.md +++ b/tests/testthat/_snaps/compile.md @@ -13,16 +13,17 @@ --- Code - cat(prql_compile("from a | select {b}", NULL, FALSE, FALSE)) + cat(prql_compile("from a | select {b}", target = NULL, format = FALSE, + signature_comment = FALSE)) Output SELECT b FROM a --- Code - cat(compile( + cat(prql_compile( "from star_wars\n select {star_wars.*}\n select !{jar_jar_binks, midichlorians}", - "sql.duckdb", TRUE, TRUE)) + target = "sql.duckdb", format = TRUE, signature_comment = TRUE)) Output SELECT * EXCLUDE (jar_jar_binks, midichlorians) @@ -34,7 +35,7 @@ # Syntax error query=Mississippi has four S’s and four I’s. Code - cat(prql_compile(query, "sql.any", TRUE, FALSE)) + cat(prql_compile(query, target = "sql.any", format = TRUE, signature_comment = FALSE)) Condition Error: ! Error: @@ -62,7 +63,7 @@ # Syntax error query=from a | select [b] Code - cat(prql_compile(query, "sql.any", TRUE, FALSE)) + cat(prql_compile(query, target = "sql.any", format = TRUE, signature_comment = FALSE)) Condition Error: ! Error: @@ -76,7 +77,7 @@ # Syntax error query=from a | select {{{b Code - cat(prql_compile(query, "sql.any", TRUE, FALSE)) + cat(prql_compile(query, target = "sql.any", format = TRUE, signature_comment = FALSE)) Condition Error: ! Error: @@ -90,7 +91,7 @@ # Targets target=sql.any Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -114,7 +115,7 @@ # Targets target=sql.ansi Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -138,7 +139,7 @@ # Targets target=sql.bigquery Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -162,7 +163,7 @@ # Targets target=sql.clickhouse Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -186,7 +187,7 @@ # Targets target=sql.duckdb Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -210,7 +211,7 @@ # Targets target=sql.generic Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -234,7 +235,7 @@ # Targets target=sql.glaredb Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -258,7 +259,7 @@ # Targets target=sql.mssql Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -282,7 +283,7 @@ # Targets target=sql.mysql Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -306,7 +307,7 @@ # Targets target=sql.postgres Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -330,7 +331,7 @@ # Targets target=sql.sqlite Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, @@ -354,7 +355,7 @@ # Targets target=sql.snowflake Code - cat(prql_compile(query, target, TRUE, FALSE)) + cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE)) Output SELECT origin, diff --git a/tests/testthat/test-compile.R b/tests/testthat/test-compile.R index 8b4f9e6..7c5e0cb 100644 --- a/tests/testthat/test-compile.R +++ b/tests/testthat/test-compile.R @@ -28,15 +28,15 @@ test_that("Not a string object", { test_that("Unsupported target", { expect_error( - prql_compile("from a | select {b}", "foo"), + prql_compile("from a | select {b}", target = "foo"), r"(target `"foo"` not found)" ) expect_error( - prql_compile("from a | select {b}", NA), + prql_compile("from a | select {b}", target = NA), "must be character, not logical" ) expect_error( - prql_compile("from a | select {b}", NA_character_), + prql_compile("from a | select {b}", target = NA_character_), "non-missing value" ) expect_error( @@ -58,20 +58,23 @@ test_that("Options", { test_that("PRQL query", { expect_snapshot(cat(prql_compile("from a | select {b}"))) - expect_snapshot(cat(prql_compile("from a | select {b}", NULL, FALSE, FALSE))) + expect_snapshot(cat(prql_compile("from a | select {b}", target = NULL, format = FALSE, signature_comment = FALSE))) expect_snapshot( "from star_wars select {star_wars.*} select !{jar_jar_binks, midichlorians}" |> - compile("sql.duckdb", TRUE, TRUE) |> + prql_compile(target = "sql.duckdb", format = TRUE, signature_comment = TRUE) |> cat() ) }) patrick::with_parameters_test_that("Syntax error", { - expect_snapshot(cat(prql_compile(query, "sql.any", TRUE, FALSE)), error = TRUE) + expect_snapshot( + cat(prql_compile(query, target = "sql.any", format = TRUE, signature_comment = FALSE)), + error = TRUE + ) }, query = c("Mississippi has four S’s and four I’s.", "from a | select [b]", "from a | select {{{b") ) @@ -91,7 +94,7 @@ group {origin, dest} ( sort {-origin, avg_delay} take 2 " - expect_snapshot(cat(prql_compile(query, target, TRUE, FALSE))) + expect_snapshot(cat(prql_compile(query, target = target, format = TRUE, signature_comment = FALSE))) }, target = prql_get_targets() ) diff --git a/tools/lib-sums.tsv b/tools/lib-sums.tsv deleted file mode 100644 index c7162a1..0000000 --- a/tools/lib-sums.tsv +++ /dev/null @@ -1,6 +0,0 @@ -url sha256sum -https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-aarch64-apple-darwin.tar.gz 1b83bf8eda8341b0d7dde0ee10aac681e86d48f6e32026f3e9c3d0b061130f8c -https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-aarch64-unknown-linux-musl.tar.gz c6d944886e058c401fa51f47b917a21a231e4b5f09a9b9a36589f06ca6db39e4 -https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-x86_64-apple-darwin.tar.gz f1b4dc4cc9f33fd66575afd1bf51a50f921929ddbb731265cde2959373abf84d -https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-x86_64-pc-windows-gnu.tar.gz 46c43712e6ede1d011233f300588e555ab58e7312464fa09d86c26e63f688ad2 -https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-x86_64-unknown-linux-musl.tar.gz 9f5e5d99b49fa3dff9e702e80960ef8ca452e78737751d01ca5a33f2307c606f