Skip to content

Commit

Permalink
Get rid of type .sql
Browse files Browse the repository at this point in the history
  • Loading branch information
mgirlich committed Jun 30, 2023
1 parent 649cd08 commit ed6b09c
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 31 deletions.
4 changes: 2 additions & 2 deletions R/backend-mssql.R
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ mssql_version <- function(con) {
...) {

# https://stackoverflow.com/q/16683758/946850
glue_sql2(con, "SELECT * INTO {.tbl name} FROM (\n {.sql sql}\n) AS temp")
glue_sql2(con, "SELECT * INTO {.tbl name} FROM (\n {sql}\n) AS temp")
}

#' @export
Expand Down Expand Up @@ -532,7 +532,7 @@ mssql_infix_comparison <- function(f) {
check_string(f)
f <- toupper(f)
function(x, y) {
mssql_as_bit(glue_sql2(sql_current_con(), "{.val x} {.sql f} {.val y}"))
mssql_as_bit(glue_sql2(sql_current_con(), "{.val x} {f} {.val y}"))
}
}

Expand Down
4 changes: 2 additions & 2 deletions R/backend-oracle.R
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ sql_translation.Oracle <- function(con) {
sql_query_explain.Oracle <- function(con, sql, ...) {
glue_sql2(
con,
"EXPLAIN PLAN FOR {.sql sql};\n",
"EXPLAIN PLAN FOR {sql};\n",
"SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY()));",
)
}
Expand All @@ -160,7 +160,7 @@ sql_table_analyze.Oracle <- function(con, table, ...) {
#' @export
sql_query_save.Oracle <- function(con, sql, name, temporary = TRUE, ...) {
type <- if (temporary) "GLOBAL TEMPORARY " else ""
glue_sql2(con, "CREATE {type}TABLE {.tbl name} AS\n{.sql sql}")
glue_sql2(con, "CREATE {type}TABLE {.tbl name} AS\n{sql}")
}

#' @export
Expand Down
2 changes: 1 addition & 1 deletion R/backend-sqlite.R
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ db_connection_describe.SQLiteConnection <- function(con, ...) {

#' @export
sql_query_explain.SQLiteConnection <- function(con, sql, ...) {
glue_sql2(con, "EXPLAIN QUERY PLAN {.sql sql}")
glue_sql2(con, "EXPLAIN QUERY PLAN {sql}")
}

#' @export
Expand Down
49 changes: 32 additions & 17 deletions R/build-sql.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,37 @@ build_sql <- function(..., .env = parent.frame(), con = sql_current_con()) {
sql(paste0(pieces, collapse = ""))
}

#' A dbplyr specific version of glue
#'
#' Similar to the inline markup of cli this function makes SQL generation easier
#' and safer by providing a couple of types. For example
#'
#' ```
#' glue_sql2(
#' con,
#' "CREATE ", if (unique) "UNIQUE ", "INDEX {.name name}",
#' " ON {.tbl table} ({.col columns*})"
#' )
#' ```
#'
#' The following types are supported:
#'
#' * .tbl A table identifier, e.g. `DBI::Id()`. Converted via `as_table_ident()`.
#' * .from A subquery or a table identifier. Converted via `as_from()`.
#' * .name A name, e.g. for an index or a subquery. Can be a string or a scalar (quoted) ident.
#' * .col A column or multiple columns if expression ends with `*`.
#' * .kw An SQL keyword - e.g. `SELECT` or `WHERE` - that should be highlighted.
#' * .val Any value - e.g. an integer vector, a Date, SQL - which is escaped as
#' usual via `escape()`.
#'
#' If no type is specified the value must be a string or scalar SQL and it isn't
#' escaped or collapsed.
#'
#' @noRd
#'
#' @examples
#' glue_sql2(con, "COLLECT STATISTICS {.tbl table}")
#' glue_sql2(con, "{f}({.val x}, {.val y})")
glue_sql2 <- function(.con,
...,
.sep = "",
Expand All @@ -73,22 +104,6 @@ glue_sql2 <- function(.con,
))
}

#' The following types are supported:
#'
#' * .tbl A table identifier, e.g. `DBI::Id()`. Converted via `as_table_ident()`.
#' * .from A subquery or a table identifier. Converted via `as_from()`.
#' * .name A name, e.g. for an index or a subquery. Can be a string or a scalar (quoted) ident.
#' * .col A column or multiple columns if expression ends with `*`.
#' * .sql
#' * .kw An SQL keyword - e.g. `SELECT` or `WHERE` - that should be highlighted.
#' * .val
#'
#' If no type is specified the value isn't escaped or collapsed.
#'
#' @param connection
#' @noRd
#'
#' @examples
sql_quote_transformer <- function(connection) {
function(text, envir) {
collapse_regex <- "[*][[:space:]]*$"
Expand All @@ -97,7 +112,7 @@ sql_quote_transformer <- function(connection) {
text <- sub(collapse_regex, "", text)
}

type_regex <- "^\\.(tbl|sql|col|name|from|kw|val) (.*)"
type_regex <- "^\\.(tbl|col|name|from|kw|val) (.*)"
m <- regexec(type_regex, text)
is_quoted <- any(m[[1]] != -1)
if (is_quoted) {
Expand Down
2 changes: 1 addition & 1 deletion R/db-sql.R
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ sql_query_wrap.DBIConnection <- function(con, from, name = NULL, ..., lvl = 0) {
from <- sql_indent_subquery(from, con, lvl)
# some backends, e.g. Postgres, require an alias for a subquery
name <- name %||% unique_subquery_name()
out <- glue_sql2(con, "{.sql from}", as_sql, "{.name name}")
out <- glue_sql2(con, "{from}", as_sql, "{.name name}")
return(out)
}

Expand Down
2 changes: 1 addition & 1 deletion R/sql-build.R
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ cte_render <- function(query_list, con) {
ctes <- purrr::imap(
query_list[-n],
function(query, name) {
glue_sql2(con, "{.name name} {.kw 'AS'} (\n{.sql query}\n)")
glue_sql2(con, "{.name name} {.kw 'AS'} (\n{query}\n)")
}
)
cte_query <- sql_vector(unname(ctes), parens = FALSE, collapse = ",\n", con = con)
Expand Down
2 changes: 1 addition & 1 deletion R/translate-sql-conditional.R
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ sql_switch <- function(x, ...) {
}

clauses_collapsed <- paste0(clauses, collapse = " ")
glue_sql2(con, "CASE {.val x} {.sql clauses_collapsed} END")
glue_sql2(con, "CASE {.val x} {clauses_collapsed} END")
}

sql_is_null <- function(x) {
Expand Down
12 changes: 6 additions & 6 deletions R/translate-sql-window.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ rows <- function(from = -Inf, to = 0) {
if (to == 0) {
sql(bound(from))
} else {
glue_sql2(sql_current_con(), "BETWEEN {.sql bound(from)} AND {.sql bound(to)}")
glue_sql2(sql_current_con(), "BETWEEN {bound(from)} AND {bound(to)}")
}
}

Expand Down Expand Up @@ -261,19 +261,19 @@ sql_nth <- function(x,
if (is.numeric(n)) {
n <- as.integer(n)
}
args <- glue_sql2(con, "{.sql args}, {.val n}")
args <- glue_sql2(con, "{args}, {.val n}")
}

if (na_rm) {
if (ignore_nulls == "inside") {
sql_expr <- "{.sql sql_f}({.sql args} IGNORE NULLS)"
sql_expr <- "{sql_f}({args} IGNORE NULLS)"
} else if (ignore_nulls == "outside") {
sql_expr <- "{.sql sql_f}({.sql args}) IGNORE NULLS"
sql_expr <- "{sql_f}({args}) IGNORE NULLS"
} else {
sql_expr <- "{.sql sql_f}({.sql args}, TRUE)"
sql_expr <- "{sql_f}({args}, TRUE)"
}
} else {
sql_expr <- "{.sql sql_f}({.sql args})"
sql_expr <- "{sql_f}({args})"
}

win_over(
Expand Down

0 comments on commit ed6b09c

Please sign in to comment.