Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions pkg-r/R/catalog-snowflake.R
Original file line number Diff line number Diff line change
Expand Up @@ -680,9 +680,11 @@ snowflake_semantic_dependencies <- function(id, specification) {
complete <- TRUE
for (table in semantic_spec_entries(specification$tables)) {
base <- table$base_table %||% list()
table_name <- base$table
catalog <- base$database %||% base$catalog %||% model[["catalog"]]
schema <- base$schema %||% model[["schema"]]
# If base_table has no database or schema, use the view's as-is.
table_name <- snowflake_yaml_identifier(base$table)
catalog <- snowflake_yaml_identifier(base$database %||% base$catalog) %||%
model[["catalog"]]
schema <- snowflake_yaml_identifier(base$schema) %||% model[["schema"]]
if (
!rlang::is_string(catalog) ||
!rlang::is_string(schema) ||
Expand All @@ -706,6 +708,17 @@ snowflake_semantic_dependencies <- function(id, specification) {
list(ids = ids[!duplicated(keys)], complete = complete && length(ids) > 0L)
}

# Strip quotes from a quoted name ("" is one quote); upper-case others (see #446).
snowflake_yaml_identifier <- function(name) {
if (!rlang::is_string(name)) {
return(NULL)
}
if (grepl('^".*"$', name)) {
return(gsub('""', '"', substr(name, 2L, nchar(name) - 1L), fixed = TRUE))
}
toupper(name)
}

snowflake_semantic_context <- function(
specification,
dimensions,
Expand Down
29 changes: 29 additions & 0 deletions pkg-r/tests/testthat/test-catalog-snowflake.R
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,35 @@ test_that("Snowflake semantic YAML imports only public dimensions and metrics",
expect_equal(model$metrics[[1]]$parent, "orders")
})

test_that("Snowflake semantic dependencies read base tables as SQL identifiers", {
# The YAML gives each name as written in SQL, quotes and all.
specification <- list(tables = list(
list(base_table = list(
database = '"Commons"',
schema = "live",
table = '"order ""lines"""'
))
))
id <- DBI::Id(catalog = "COMMONS", schema = "LIVE", table = "MODEL")

model <- snowflake_semantic_model_from_spec(id, specification)

expect_identical(
model$dependencies[[1]],
DBI::Id(catalog = "Commons", schema = "LIVE", table = 'order "lines"')
)

# A namespace the YAML leaves out is the view's own, which is exact.
inherited <- snowflake_semantic_model_from_spec(
DBI::Id(catalog = "MyDb", schema = "MySchema", table = "MODEL"),
list(tables = list(list(base_table = list(table = "orders"))))
)
expect_identical(
inherited$dependencies[[1]],
DBI::Id(catalog = "MyDb", schema = "MySchema", table = "ORDERS")
)
})

test_that("Snowflake semantic scope retains dependencies and public context", {
specification <- list(
custom_instructions = "Use booked revenue for finance questions.",
Expand Down
Loading