Skip to content

Commit 0524d53

Browse files
dpprdankrlmlr
authored andcommitted
Support for system catalogs
Full history: 699813b refactor `dbListTables()` with `list_tables()`, now orders result by `table_type` and `table_name` refactor `dbExistsTable()` with `list_tables()` refactor `dbListObjects()` with `list_tables()` merge `find_table()` code into `list_fields()` `find_table()` isn't used anywhere else anymore (e.g. `exists_table()`) simplify the "get current_schemas() as table" code pass full `id` to `list_fields()` align `dbExistsTable()` with `dbListFields()` add some comments and whitespace simplify `where_schema` in `list_tables()` align `where_table` with `where_schema` in `list_tables()` add `system_catalogs` argument to `dbConnect()` add materialized view tests `list_tables()`: query system catalogs if available `list_fields()`: query system catalogs if available
1 parent d689f88 commit 0524d53

14 files changed

+315
-52
lines changed

R/PqConnection.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ setClass("PqConnection",
1010
slots = list(
1111
ptr = "externalptr",
1212
bigint = "character",
13+
system_catalogs = "logical",
1314
timezone = "character",
1415
timezone_out = "character",
1516
typnames = "data.frame"

R/dbConnect_PqDriver.R

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343
#' @param check_interrupts Should user interrupts be checked during the query execution (before
4444
#' first row of data is available)? Setting to `TRUE` allows interruption of queries
4545
#' running too long.
46+
#' @param system_catalogs Should `dbList*()` functions query the [`system
47+
#' catalogs`](https://www.postgresql.org/docs/current/catalogs.html) (`TRUE`)
48+
#' or the
49+
#' [`information_schema`](https://www.postgresql.org/docs/current/information-schema.html)?
50+
#' The `information_schema` does not contain PostgreSQL-specific information,
51+
#' in particular [Materialized
52+
#' Views](https://www.postgresql.org/docs/current/sql-creatematerializedview.html).
4653
#' @param timezone Sets the timezone for the connection. The default is `"UTC"`.
4754
#' If `NULL` then no timezone is set, which defaults to the server's time zone.
4855
#' @param timezone_out The time zone returned to R, defaults to `timezone`.
@@ -60,7 +67,8 @@
6067
dbConnect_PqDriver <- function(drv, dbname = NULL,
6168
host = NULL, port = NULL, password = NULL, user = NULL, service = NULL, ...,
6269
bigint = c("integer64", "integer", "numeric", "character"),
63-
check_interrupts = FALSE, timezone = "UTC", timezone_out = NULL) {
70+
check_interrupts = FALSE, system_catalogs = TRUE,
71+
timezone = "UTC", timezone_out = NULL) {
6472
opts <- unlist(list(
6573
dbname = dbname, user = user, password = password,
6674
host = host, port = as.character(port), service = service, client_encoding = "utf8", ...
@@ -70,6 +78,7 @@ dbConnect_PqDriver <- function(drv, dbname = NULL,
7078
}
7179
bigint <- match.arg(bigint)
7280
stopifnot(is.logical(check_interrupts), all(!is.na(check_interrupts)), length(check_interrupts) == 1)
81+
stopifnot(is.logical(system_catalogs))
7382
if (!is.null(timezone)) {
7483
stopifnot(is.character(timezone), all(!is.na(timezone)), length(timezone) == 1)
7584
}
@@ -85,7 +94,8 @@ dbConnect_PqDriver <- function(drv, dbname = NULL,
8594

8695
# timezone is set later
8796
conn <- new("PqConnection",
88-
ptr = ptr, bigint = bigint, timezone = character(), typnames = data.frame()
97+
ptr = ptr, bigint = bigint, system_catalogs = system_catalogs,
98+
timezone = character(), typnames = data.frame()
8999
)
90100
on.exit(dbDisconnect(conn))
91101

R/dbConnect_RedshiftDriver.R

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,22 @@ dbConnect_RedshiftDriver <- function(drv, dbname = NULL,
44
host = NULL, port = NULL, password = NULL, user = NULL, service = NULL, ...,
55
bigint = c("integer64", "integer", "numeric", "character"),
66
check_interrupts = FALSE, timezone = "UTC") {
7-
new("RedshiftConnection", callNextMethod())
7+
new("RedshiftConnection",
8+
callNextMethod(
9+
drv = drv,
10+
dbname = dbname,
11+
host = host,
12+
port = port,
13+
password = password,
14+
user = user,
15+
service = service,
16+
...,
17+
bigint = bigint,
18+
check_interrupts = check_interrupts,
19+
system_catalogs = FALSE,
20+
timezone = timezone
21+
)
22+
)
823
}
924

1025
#' @rdname Redshift

R/dbExistsTable_PqConnection_Id.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#' @rdname postgres-tables
22
#' @usage NULL
33
dbExistsTable_PqConnection_Id <- function(conn, name, ...) {
4-
exists_table(conn, id = name@name)
4+
exists_table(conn, id = name)
55
}
66

77
#' @rdname postgres-tables

R/dbExistsTable_PqConnection_character.R

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
#' @usage NULL
33
dbExistsTable_PqConnection_character <- function(conn, name, ...) {
44
stopifnot(length(name) == 1L)
5-
name <- dbQuoteIdentifier(conn, name)
6-
7-
# Convert to identifier
8-
id <- dbUnquoteIdentifier(conn, name)[[1]]@name
5+
# use (Un)QuoteIdentifier roundtrip instead of Id(table = name)
6+
# so that quoted names (possibly incl. schema) can be passed to `name` e.g.
7+
# name = dbQuoteIdentifier(conn, Id(schema = "sname", table = "tname"))
8+
quoted <- dbQuoteIdentifier(conn, name)
9+
id <- dbUnquoteIdentifier(conn, quoted)[[1]]
910
exists_table(conn, id)
1011
}
1112

R/dbListFields_PqConnection_Id.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#' @rdname postgres-tables
22
#' @usage NULL
33
dbListFields_PqConnection_Id <- function(conn, name, ...) {
4-
list_fields(conn, name@name)
4+
list_fields(conn, id = name)
55
}
66

77
#' @rdname postgres-tables

R/dbListFields_PqConnection_character.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#' @usage NULL
33
dbListFields_PqConnection_character <- function(conn, name, ...) {
44
quoted <- dbQuoteIdentifier(conn, name)
5-
id <- dbUnquoteIdentifier(conn, quoted)[[1]]@name
5+
id <- dbUnquoteIdentifier(conn, quoted)[[1]]
66

77
list_fields(conn, id)
88
}

R/dbListObjects_PqConnection_ANY.R

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ dbListObjects_PqConnection_ANY <- function(conn, prefix = NULL, ...) {
1313
null_varchar <- "NULL::text"
1414
}
1515
query <- paste0(
16-
"SELECT ", null_varchar, " AS schema, table_name AS table FROM INFORMATION_SCHEMA.tables\n",
17-
"WHERE (table_schema = ANY(current_schemas(true))) AND (table_schema <> 'pg_catalog')\n",
16+
"SELECT ", null_varchar, " AS schema, table_name AS table FROM ( \n",
17+
list_tables(conn = conn, order_by = "table_type, table_name"),
18+
") as table_query \n",
1819
"UNION ALL\n",
19-
"SELECT DISTINCT table_schema AS schema, ", null_varchar, " AS table FROM INFORMATION_SCHEMA.tables"
20+
"SELECT DISTINCT table_schema AS schema, ", null_varchar, " AS table FROM ( \n",
21+
list_tables(conn = conn, where_schema = "true"),
22+
") as schema_query;"
2023
)
2124
} else {
2225
if (!is.list(prefix)) prefix <- list(prefix)
@@ -27,10 +30,20 @@ dbListObjects_PqConnection_ANY <- function(conn, prefix = NULL, ...) {
2730
schemas <- vcapply(prefix[is_prefix], function(x) x@name[["schema"]])
2831
if (length(schemas) > 0) {
2932
schema_strings <- dbQuoteString(conn, schemas)
33+
where_schema <-
34+
paste0(
35+
"table_schema IN (",
36+
paste(schema_strings, collapse = ", "),
37+
") \n"
38+
)
3039
query <- paste0(
31-
"SELECT table_schema AS schema, table_name AS table FROM INFORMATION_SCHEMA.tables\n",
32-
"WHERE ",
33-
"(table_schema IN (", paste(schema_strings, collapse = ", "), "))"
40+
"SELECT table_schema AS schema, table_name AS table FROM ( \n",
41+
list_tables(
42+
conn = conn,
43+
where_schema = where_schema,
44+
order_by = "table_type, table_name"
45+
),
46+
") as table_query"
3447
)
3548
}
3649
}

R/dbListTables_PqConnection.R

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
#' @rdname postgres-tables
22
#' @usage NULL
33
dbListTables_PqConnection <- function(conn, ...) {
4-
query <- paste0(
5-
"SELECT table_name FROM INFORMATION_SCHEMA.tables ",
6-
"WHERE ",
7-
"(table_schema = ANY(current_schemas(true))) AND (table_schema <> 'pg_catalog')"
8-
)
9-
dbGetQuery(conn, query)[[1]]
4+
query <- list_tables(conn = conn, order_by = "table_type, table_name")
5+
6+
dbGetQuery(conn, query)[["table_name"]]
107
}
118

129
#' @rdname postgres-tables

0 commit comments

Comments
 (0)