SnowPro Core study materials
SnowPro Core study resources

The Share That Could Not Reference Two Databases

SnowPro Core · Put your knowledge to work in context.

All case studies

The Share That Could Not Reference Two Databases

A data provider wants to share a curated view, ORDER_ENRICHED, that joins SALES.PUBLIC.ORDERS to CRM.PUBLIC.CUSTOMER_SEGMENT. The two tables live in different databases. ALTER SHARE ... ADD VIEW fails. Separately, a consumer reports that rows vanished from a shared table after the provider ran a corrective DELETE, and asks for the data restored as of yesterday. The provider's legal team also wants to know what stops a consumer from keeping the data after the contract ends, and whether the provider is paying for the consumer's storage in the meantime.

1. Why does the ADD VIEW fail, and how do you ship the joined result?

Read the worked answer

Share objects must be self-contained within a single database. A view placed in a share may only reference objects in the same database as the view (and must itself be a secure view). ORDER_ENRICHED reaches into CRM, so the share refuses it.

Options, in order of preference:

  1. Materialize the CRM side into SALES. Copy or periodically refresh CUSTOMER_SEGMENT into a table in the SALES database, define ORDER_ENRICHED as a secure view over the two SALES objects, grant SELECT on the view to the share, and add the view. This keeps the consumer's interface stable.
  2. Create a dedicated sharing database that holds curated copies of both inputs and all shared views - cleaner long term, and it decouples the consumer's contract from internal schema churn.
  3. Remember that granting the view to the share is what matters; the underlying base tables do not need to be in the share. If you also share the base tables, a consumer can read raw columns the view was meant to hide - share the view instead of the tables, not alongside them.

A side benefit of the curated-view approach: when the internal schema changes, only the view needs updating.

2. The consumer wants yesterday's data back. What can you offer, and what is the consumer unable to do themselves?

Read the worked answer

The consumer cannot help themselves here. Time Travel is unavailable on shared objects - a consumer cannot query a shared table AT or BEFORE an offset, and cannot UNDROP an object they do not own. Recovery is entirely the provider's job.

Provider-side options:

  1. Restore into a new object: CREATE TABLE orders_restored CLONE sales.public.orders AT (OFFSET => -86400) and verify the row count against the consumer's expectation before going further.
  2. UNDROP TABLE if the table itself was dropped rather than the rows deleted - but note the restored object comes back with the same name and the share points at the table, so behaviour depends on whether the share was re-pointed.
  3. Re-point the share at the restored object (REVOKE/GRANT on the share, or ALTER SHARE ... ADD TABLE), which may briefly break the consumer's queries - coordinate the window.
  4. Feasibility depends on retention: standard accounts get 0–1 day of Time Travel, so a 24-hour-old restore is only reliable on Enterprise Edition or above with extended retention configured. Check DATA_RETENTION_TIME_IN_DAYS before promising anything. Fail-safe is not an option - it is not user-accessible and requires Snowflake Support.

3. What stops a consumer from keeping the data after the contract ends, and who pays for storage?

Read the worked answer

Technically, very little - plan around that.

  • A consumer can always CREATE TABLE ... AS SELECT from shared objects into their own database. Those copies live in the consumer's account under their control; revoking the share removes future access but cannot reach data already materialized. Enforcement is contractual and access-log based, which is exactly why sharing curated secure views rather than base tables matters: a view can be altered or the share revoked to change what is visible going forward, and it limits which columns and rows were ever exposed.
  • Storage economics: the provider pays for storage of the shared data; the consumer pays only for the compute used to query it. The moment a consumer copies data into their own table, that copy becomes their storage cost. This is worth stating plainly to both finance and legal, because it also means a large consumer querying heavily costs the provider nothing in compute.
  • Operational hygiene: record what was shared and when, monitor ACCESS_HISTORY/QUERY_HISTORY for direct-table reads if base objects were ever exposed, and prefer revoking shares over deleting shared objects - deleting the underlying object breaks the consumer abruptly and forces the Time Travel conversation above.