Skip to content

Commit

Permalink
Refine table_name_table() interface
Browse files Browse the repository at this point in the history
  • Loading branch information
hadley committed Dec 18, 2023
1 parent 7ddea50 commit 86aeea5
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 42 deletions.
3 changes: 1 addition & 2 deletions R/backend-postgres-old.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ db_write_table.PostgreSQLConnection <- function(con,
values,
temporary = TRUE,
...) {
table <- as_table_name(table, con)
if (!isFALSE(temporary)) {
cli_abort(c(
"RPostgreSQL backend does not support creation of temporary tables",
Expand All @@ -27,7 +26,7 @@ db_write_table.PostgreSQLConnection <- function(con,
# the bare table name
dbWriteTable(
con,
name = db_table_name_extract(con, table),
name = table_name_table(table, con),
value = values,
field.types = types,
...,
Expand Down
4 changes: 2 additions & 2 deletions R/db-sql.R
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ sql_table_index.DBIConnection <- function(con,
table <- as_table_name(table, con)

if (is.null(name)) {
table_name <- db_table_name_extract(con, table)
table_name <- table_name_table(table, con)
name <- name %||% paste0(c(table_name, columns), collapse = "_")
}
glue_sql2(
Expand Down Expand Up @@ -259,7 +259,7 @@ sql_query_wrap.DBIConnection <- function(con, from, name = NULL, ..., lvl = 0) {
glue_sql2(con, "{from}", as_sql, "{.tbl name}")
} else { # must be a table_name
if (!is.null(name)) {
table <- db_table_name_extract(con, name)
table <- table_name_table(name, con)
names(from) <- as_table_name(table, con)
}
from
Expand Down
3 changes: 2 additions & 1 deletion R/lazy-join-query.R
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ op_vars.lazy_semi_join_query <- function(op) {

#' @export
sql_build.lazy_multi_join_query <- function(op, con, ..., sql_options = NULL) {

table_names_out <- generate_join_table_names(op$table_names, con)

tables <- set_names(c(list(op$x), op$joins$table), table_names_out)
Expand Down Expand Up @@ -188,7 +189,7 @@ sql_build.lazy_multi_join_query <- function(op, con, ..., sql_options = NULL) {
}

generate_join_table_names <- function(table_names, con) {
names <- db_table_name_extract(con, table_names$name)
names <- table_name_table(table_names$name, con)
table_name_length_max <- max(nchar(names))

if (length(table_names$name) != 2) {
Expand Down
21 changes: 6 additions & 15 deletions R/query-join.R
Original file line number Diff line number Diff line change
Expand Up @@ -331,29 +331,20 @@ sql_join_tbls <- function(con, by, na_matches) {
}

sql_table_prefix <- function(con, var, table = NULL) {

if (!is_bare_character(var)) {
cli_abort("{.arg var} must be a bare character.", .internal = TRUE)
}
var <- sql_escape_ident(con, var)

if (!is.null(table)) {
table <- as_table_name(table, con)
table <- db_table_name_extract(con, table)
table <- as_table_name(table, con)

sql(paste0(table, ".", var))
} else {
var
}
sql_table_name_prefix(con, table, var)
}

sql_star <- function(con, table = NULL) {
# TODO: sql_table_prefix(con, "*", table) ?
var <- sql("*")
sql_table_name_prefix(con, table, sql("*"))
}

sql_table_name_prefix <- function(con, table, var) {
if (!is.null(table)) {
table <- as_table_name(table, con)
table <- db_table_name_extract(con, table)
table <- table_name_table(table, con)
table <- as_table_name(table, con)

sql(paste0(table, ".", var))
Expand Down
2 changes: 1 addition & 1 deletion R/remote.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ remote_name <- function(x, null_if_local = TRUE) {
if (is.null(con)) {
table
} else {
db_table_name_extract(con, table)
table_name_table(table, con)
}
}
}
Expand Down
35 changes: 19 additions & 16 deletions R/table-name.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,20 @@ as_table_names <- function(x, con) {
make_table_name(x, con, collapse = FALSE)
}

# TODO: make this generic
db_parse_table_name <- function(con, x) {
quote_char <- substr( sql_escape_ident(con, ""), 1, 1)
# Extract just the table name from a full identifier
table_name_table <- function(x, con) {
x <- as_table_name(x, con)

vapply(x, FUN.VALUE = character(1), function(x) {
if (x == "") return("")

out <- table_name_components(x, con)
out[[length(out)]]
})
}
table_name_components <- function(x, con) {
quote_char <- substr(sql_escape_ident(con, ""), 1, 1)

scan(
text = x,
what = character(),
Expand All @@ -67,29 +78,21 @@ db_parse_table_name <- function(con, x) {
sep = "."
)
}
db_table_name_extract <- function(con, x) {
vapply(x, FUN.VALUE = character(1), function(x) {
if (x == "") return("")

out <- db_parse_table_name(con, x)
out[[length(out)]]
})
}

#' @export
escape.dbplyr_table_name <- function(x, parens = FALSE, collapse = ", ", con = NULL) {
alias <- names2(x) # assume alias is already escaped
x <- unname(x)

table_name <- as_table_name(db_table_name_extract(con, x), con)
# names are always already escaped
alias <- names2(x)
table_name <- as_table_name(table_name_table(x, con), con)
has_alias <- alias == "" | alias == table_name

if (db_supports_table_alias_with_as(con)) {
as_sql <- style_kw(" AS ")
} else {
as_sql <- " "
}

out <- ifelse(alias == "" | alias == table_name, x, paste0(x, as_sql, alias))
out <- ifelse(has_alias, unname(x), paste0(x, as_sql, alias))
sql_vector(out, parens, collapse, con = con)
}

Expand Down
2 changes: 1 addition & 1 deletion R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ add_temporary_prefix <- function(con, table, temporary = TRUE) {
return(table)
}

pieces <- db_parse_table_name(con, table)
pieces <- table_name_components(table, con)
table_name <- pieces[length(pieces)]

if (substr(table_name, 1, 1) != "#") {
Expand Down
8 changes: 4 additions & 4 deletions tests/testthat/test-verb-joins.R
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ test_that("alias truncates long table names at database limit", {
# Source: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
con <- src_test("postgres")

nm1 <- paste0("a", paste0(0:61 %% 10, collapse = ""))
mf1 <- local_db_table(con, tibble(x = 1:3, y = "a"), nm1)
nm1 <- table_name(paste0("a", paste0(0:61 %% 10, collapse = "")))
mf1 <- local_db_table(con, tibble(x = 1:3, y = "a"), unclass(nm1))

nm2 <- paste0("b", paste0(0:61 %% 10, collapse = ""))
mf2 <- local_db_table(con, tibble(x = 2:3, y = "b"), nm2)
nm2 <- table_name(paste0("b", paste0(0:61 %% 10, collapse = "")))
mf2 <- local_db_table(con, tibble(x = 2:3, y = "b"), unclass(nm2))

# 2 tables
# aliased names are as expected
Expand Down

0 comments on commit 86aeea5

Please sign in to comment.