- Schema:
ACCESS_HISTORY view¶
This Account Usage view can be used to query the access history of Snowflake objects (e.g. table, view, column) within the last 365 days (1 year).
Columns¶
There are three tables in this section:
The first table provides an example of each column value.
The second table defines the columns in the ACCESS_HISTORY view.
The third table defines the fields in the JSON array for the
base_objects_accessed
,direct_objects_accessed
, andobjects_modified
columns.
Column name |
Example |
---|---|
|
|
|
|
|
|
|
[
{
"objectDomain": "FUNCTION",
"objectName": "GOVERNANCE.FUNCTIONS.RETURN_SUM",
"objectId": "2",
"argumentSignature": "(NUM1 NUMBER, NUM2 NUMBER)",
"dataType": "NUMBER(38,0)"
},
{
"columns": [
{
"columnId": 68610,
"columnName": "CONTENT"
}
],
"objectDomain": "Table",
"objectId": 66564,
"objectName": "GOVERNANCE.TABLES.T1"
}
]
|
|
[
{
"objectDomain": "FUNCTION",
"objectName": "GOVERNANCE.FUNCTIONS.RETURN_SUM",
"objectId": "2",
"argumentSignature": "(NUM1 NUMBER, NUM2 NUMBER)",
"dataType": "NUMBER(38,0)"
},
{
"columns": [
{
"columnId": 68610,
"columnName": "CONTENT"
}
],
"objectDomain": "Table",
"objectId": 66564,
"objectName": "GOVERNANCE.TABLES.T1"
}
]
|
|
[
{
"objectDomain": "STRING",
"objectId": NUMBER,
"objectName": "STRING",
"columns": [
{
"columnId": "NUMBER",
"columnName": "STRING",
"baseSources": [
{
"columnName": STRING,
"objectDomain": "STRING",
"objectId": NUMBER,
"objectName": "STRING"
}
],
"directSources": [
{
"columnName": STRING,
"objectDomain": "STRING",
"objectId": NUMBER,
"objectName": "STRING"
}
]
}
]
},
...
]
|
|
{
"objectDomain": STRING,
"objectName": STRING,
"objectId": NUMBER,
"operationType": STRING,
"properties": ARRAY
}
|
|
[
{
"columns": [
{
"columnId": 68610,
"columnName": "SSN",
"policies": [
{
"policyName": "governance.policies.ssn_mask",
"policyId": 68811,
"policyKind": "MASKING_POLICY"
}
]
}
],
"objectDomain": "VIEW",
"objectId": 66564,
"objectName": "GOVERNANCE.VIEWS.V1",
"policies": [
{
"policyName": "governance.policies.rap1",
"policyId": 68813,
"policyKind": "ROW_ACCESS_POLICY"
}
]
}
]
|
Column Name |
Data Type |
Description |
---|---|---|
|
TEXT |
An internal, system-generated identifier for the SQL statement. This value is also mentioned in the QUERY_HISTORY view. |
|
TIMESTAMP_LTZ |
The statement start time (UTC time zone). |
|
TEXT |
The user who issued the query. |
|
ARRAY |
A JSON array of data objects such as user-defined functions (i.e. UDFs and UDTFs), stored procedures, tables, views, and columns
directly named in the query explicitly or through shortcuts such as using an asterisk (i.e. Virtual columns can be returned in this field. For additional notes about UDFs, see the UDF notes (in this topic). |
|
ARRAY |
A JSON array of all base data objects to execute a query, including columns, external functions, UDFs, and stored procedures. In this example, the fields in the first array specify a UDF. These same fields in the first array also specify a stored procedure, when applicable. Note the following:
|
|
ARRAY |
A JSON array that specifies the objects that were associated with a write operation in the query. The UDF and stored procedure array is the same as what is shown earlier and appears in the arrays for For additional notes about UDFs, see the UDF notes (in this topic). |
|
OBJECT |
Specifies the DDL operation on a database, schema, table, view, and column. These operations also include statements that specify a row access policy on a table or view, a masking policy on a column, and tag updates (e.g. set a tag, change a tag value) on the object or column. |
|
ARRAY |
Specifies information about the enforced masking policy set on the column and the enforced row access policy set on the table, including policies set on intermediate objects or columns. |
|
TEXT |
The query ID of the parent job or NULL if the job does not have a parent. |
|
TEXT |
The query ID of the top most job in the chain or NULL if the job does not have a parent. |
The fields in the JSON array for the direct_objects_accessed
, base_objects_accessed
, objects_modified
, and
policies_referenced
columns are described below.
Field |
Data Type |
Description |
---|---|---|
columnId |
NUMBER |
A column ID that is unique within the account. This value is identical to the columnID in the COLUMNS view. |
columnName |
TEXT |
The name of the accessed column. For policies, specifies the column on which the masking policy is set. |
objectId |
NUMBER |
An identifier for the object, which is unique within a given account and domain. This number will match: |
objectName |
TEXT |
The fully qualified name of the object that was accessed. If a masking policy is set on a column or a row access policy is set on a table or view, the value refers to the fully qualified name of the table or view on which the row access policy is set or the table or view that has a masking policy set on one of its columns. If a stage was accessed, this value will be the:
|
objectDomain |
TEXT |
One of the following: Note that For policies, specifies the domain of the object on which the row access policy is set. |
location |
TEXT |
The URL of the external location when the data access is an external location (e.g. |
stageKind |
TEXT |
When writing to a stage, one of the following: |
baseSources |
TEXT |
The columns that serve as the source columns for the columns specified by |
directSources |
TEXT |
The columns specifically mentioned in the data write portion of the SQL statement that serves as the source columns in the target table to which data is written. These columns facilitate column lineage. |
policyName |
TEXT |
The fully-qualified name of the policy. |
policyId |
NUMBER |
An identifier for the policy, which is unique within a given account and domain. This value matches the identifier for a masking policy in the MASKING_POLICIES view or the identifier for a row access policy in the ROW_ACCESS_POLICIES view |
policyKind |
TEXT |
Either: MASKING_POLICY or ROW_ACCESS_POLICY |
argumentSignature |
TEXT |
The name and data type for each argument in the UDF or stored procedure. |
dataType |
The data type of the return value for a UDF or stored procedure. This value helps to differentiate two or more UDFs that have the same name but different return types. |
The fields for the object_modified_by_ddl
column are described below.
fieldName |
Data type |
Description |
---|---|---|
objectDomain |
TEXT |
The domain of the object defined or modified by the DDL operation, which includes all objects that can be tagged and MASKING POLICY | ROW ACCESS POLICY | TAG. |
objectId |
NUMBER |
The identifier for the object, which is unique within a given account and domain, defined or modified by the DDL operation. |
objectName |
TEXT |
The fully qualified name of the object defined or modified by the DDL operation. |
operationType |
TEXT |
The SQL keyword that specifies the operation on the table, view, or column: ALTER | CREATE | DROP | REPLACE | UNDROP |
properties |
ARRAY |
A JSON array that specifies the object or column properties when you create, modify, drop, or undrop the object or column. There are two types of properties: atomic and compound. |
For the properties
field:
Atomic: one value per property (e.g. a
comment
has a single string value, theenabled
property is a boolean and has one value).Compound: the property is multi-valued (e.g.
allowed_values
for a tag, masking policy).
Compound properties are recorded in a JSON array. For example, if a table contains a single column named EMAIL, the column is recorded as follows:
columns: {
"email": {
objectId: {
"value": 1
},
"subOperationType": "ADD"
}
}
The subOperationType
value can be one of the following:
ADD
specifies adding a compound property (e.g. add a column, set allowed values).DROP
specifies removing a compound property.ALTER
specifies modifying a compound property.
The objectId
specifies the identifier for the column or object, except for allowed tag values which do not have an
identifier.
Usage notes¶
- Latency and historical data:
The view displays data starting from February 22, 2021.
Latency for the view may be up to 180 minutes (3 hours).
- Ancestor queries:
The
parent_query_id
androot_query_id
columns begin to record data starting on January 15-16, 2024, depending on when your Snowflake account was updated based on the2023_08
behavior change bundle transitioning to enabled by default. This date is necessary to distinguish between the following records in the view:Queries that ran before the bundle was enabled by default.
Queries that ran after the feature was enabled by default but do not have a value in the
parent_query_id
.
- General notes:
For increased performance, filter queries on the
query_start_time
column and choose narrower time ranges. For sample queries, see Querying the ACCESS_HISTORY View.Secure Views. The log record contains the underlying base table (i.e.
base_objects_accessed
) to generate the view. Examples include queries on other Account Usage and Organization Usage views and queries on base tables for extract, transform, and load (i.e. ETL) operations.Records in the QUERY_HISTORY view do not always get recorded in the ACCESS_HISTORY view. The structure of the SQL statement determines whether Snowflake records an entry in the ACCESS_HISTORY view.
Specifying the
USING
clause while querying this view might cause non-referenced columns to be recorded indirect_objects_accessed
field. As a workaround, replace theUSING
clause with aJOIN ... ON ...
clause. For details, refer to:JOIN and USING (in the JOIN reference topic)
Tracking Sensitive stage data movement (in the Access History query example)
- Read query notes:
This view supports read queries of the following type:
SELECT, including CREATE TABLE … AS SELECT (i.e. CTAS).
Snowflake records the SELECT subquery in a CTAS operation.
CREATE TABLE … CLONE
Snowflake records the source table in a CLONE operation.
COPY INTO … TABLE
Snowflake logs this query only when the table is specified as the source in a FROM clause.
DML operations that read data (e.g. contains a SELECT subquery, specifies certain columns in WHERE or JOIN): INSERT … SELECT, UPDATE, DELETE, and MERGE.
UDFs and Tabular SQL UDFs (UDTFs) if tables are included in queries inside the functions. This is logged in the
base_objects_accessed
field.For more details on UDFs, see the UDF notes (in this topic).
- Write operation notes:
This view supports write operations of the following type:
GET
<internal_stage>
PUT
<internal_stage>
DELETE
TRUNCATE
INSERT
INSERT INTO … FROM SELECT *
INSERT INTO TABLE … VALUES ()
MERGE INTO … FROM SELECT *
UPDATE
UPDATE TABLE … FROM SELECT * FROM …
UPDATE TABLE … WHERE …
Data loading statements:
COPY INTO TABLE FROM internalStage
COPY INTO TABLE FROM externalStage
COPY INTO TABLE FROM externalLocation
Data unloading statements:
COPY INTO internalStage FROM TABLE
COPY INTO externalStage FROM TABLE
COPY INTO externalLocation FROM TABLE
CREATE:
CREATE DATABASE … CLONE
CREATE SCHEMA … CLONE
CREATE TABLE … CLONE
CREATE TABLE … AS SELECT
For write operations that call the CASE function to determine the columns to access, such as a CTAS statement with the CASE function in the SELECT query, all columns referenced in every CASE branch are recorded in the
base_objects_accessed
column, thedirect_objects_accessed
column, or both columns depending on how the CTAS statement is written.
- Data sharing notes:
If a Data Sharing provider account shares objects to Data Sharing consumer accounts through a share:
Provider accounts: The queries and logs on the shared objects executed in the provider account are not visible to Data Sharing consumer accounts.
Consumer accounts: The queries on the data share executed in the consumer account are logged and only visible to the consumer account, not the Data Sharing provider account.
For example, if the provider shares a table and a view built from the table to the consumer account, and there is a query on the shared view, Snowflake records the shared view access in the
base_objects_accessed
column. This record, which includes thecolumnName
andobjectName
values, allows the consumer to know which object was accessed in their account and also protects the provider because the underlying table (via theobjectId
andcolumnId
) is not revealed to the consumer.For column lineage:
If a data sharing provider makes a view available to the data sharing consumer, the source columns for the view are not visible to the consumer because the columns originate from the data sharing provider.
If the data sharing consumer moves data from the shared view to a table, Snowflake does not record the view columns as
baseSources
for the newly created table.For shared UDFs and UDTFs:
In the consumer account, the local ACCESS_HISTORY view records the UDF/UDTF that was shared by the provider when the shared UDF/UDTF is invoked by the consumer.
In the provider account, the local ACCESS_HISTORY view records provider usage of a shared UDF/UDTF. Users in the consumer account cannot view how the provider account uses the shared UDF/UDTF.
For tracking policy references:
The
policies_referenced
column contains policies that are local to the account that queries the data.If a provider shares a policy-protected table and a consumer accesses this table, the consumer cannot see the policy the provider set on the table or its columns.
If a consumer creates a view (
v1
) from the shared object, sets a policy to the view (v1
) or its columns, and a user in the consumer account accesses the protected view (v1
) or another view (v2
) created from the protected view (v1
), the ACCESS_HISTORY view in the consumer account contains the policy that protects the view (v1
) and its columns. The provider cannot see the record that corresponds tov1
.
- Hybrid tables:
Short-running queries that operate exclusively against hybrid tables will no longer generate a record in the QUERY_HISTORY view, in QUERY_HISTORY, or in the output of the QUERY_HISTORY table function. To monitor such queries, use the AGGREGATE_QUERY_HISTORY.
To monitor Access History for such queries, use the AGGREGATE_ACCESS_HISTORY. This view allows you to more easily monitor high-throughput operational workloads for Access History.
- Snowflake Native App Framework notes:
Some queries related to a Snowflake Native App are redacted. For details, see Information redacted from SQL commands and views.
- Tag-based masking notes:
If a user accesses a table or view protected by a tag-based masking policy, the
policies_referenced
column contains the masking policy applied through the tag when Snowflake enforces the masking policy on the protected column.The ACCESS_HISTORY view does not record any tag information.
- UDFs & Stored Procedure notes:
These notes apply to external functions, UDFs and UDTFs for all languages, including when these functions have the
SECURE
property, and stored procedures with owner’s rights and caller’s rights:Column details:
The
direct_objects_accessed
column records explicit mention of these functions and procedures in a query.Snowflake does not record nested UDFs (i.e. a UDF mentioned in the definition of another UDF) in this column.
The
base_objects_accessed
column records external functions, shared functions, non-SQL UDFs, and stored procedures that are called in a query.The
objects_modified
column records:The UDF/UDTF when the result of calling the function copies the result to another column.
The UDF, UDTF, and an external function can be recorded in the arrays for
baseSources
anddirectSources
depending on how the query is written.
- Not supported:
This view does not log accesses of the following types:
Snowflake-provided table functions, Account Usage views, and Organization Usage views.
RESULT_SCAN to obtain prior results.
Sequences, including generating new values.
Intermediate views accessed between the base table and direct object.
For example, consider a query on View_A with the following object structure: View_A » View_B » View_C » Base_Table.
The ACCESS_HISTORY view records the query on View_A and the Base_Table, not View_B and View_C.
The operations to update streams.
Data movement resulting from replication.
Failed queries, although logged in the QUERY_HISTORY view, will not be logged in the ACCESS_HISTORY view.
Usage Notes: Column Lineage¶
These additional notes pertain to column lineage:
- Supported operations:
Column lineage tracks details for the following SQL operations:
CREATE TABLE … AS SELECT (CTAS)
UPDATE, two possible variations, for example:
Self-update:
UPDATE mydb.s1.t1 SET col_1 = col_1 + 1;
Two table update:
UPDATE mydb.s1.t1 FROM mydb.s2.t2 SET t1.col1 = t2.col1;
ALTER TABLE … RENAME TO
- Query Conditions:
-
The query plan Snowflake writes determines whether the ACCESS_HISTORY view contains column lineage. If a column needs to be evaluated as part of the query plan, Snowflake contains the column in the ACCESS_HISTORY view, even if the end result of the query plan is that the column is not included in the end result.
For example, consider the following INSERT statement with a
WHERE
clause for a particular column value:insert into a(c1) select c2 from b where c3 > 1;
Even if the WHERE clause evaluates to
FALSE
, Snowflake records thec2
column as a source column for thec1
column. Thec3
column is not listed as a source column for eitherbaseSources
ordirectSources
. Masked columns:
The masked column is always listed in the
directSources
field.The record in the
baseSources
field depends on the policy definition. For example:If the masking policy conditions use a CASE function, then all of the columns referenced in each of the CASE branches are recorded in the
baseSources
field.If the masking policy conditions only specify a constant value (e.g.
*****
), then thebaseSources
field is empty.
UDFs:
When passing a column as an argument to a UDF and writing the result to another column, the column that is passed as the argument is recorded in the
directSources
field. For example:insert into A(col1) select f(col2) from B;
In this example, Snowflake records
col2
in thedirectSources
field because the column is an argument for the UDF namedf
.The record in the
baseSources
field depends on the UDF definition.
-
- View columns:
View columns are not considered to be source columns and are not listed in the
baseSources
field when data from a view column is copied to a table column. The view columns in this case are listed in thedirectSources
field.- EXISTS Subquery:
Columns that are referenced in the EXISTS subquery clause are not considered to be source columns.
Usage Notes: object_modified_by_ddl
Column¶
IF [ NOT ] EXISTS
clauses: Theobject_modified_by_ddl
column only recordsCREATE
orREPLACE
when creating or modifying an object.Snowflake supports the following object domains.
Table and external table.
View and materialized view
Schema
Database.
The column records these changes based on the following SQL operations. The DROP and UNDROP operations apply to tables and views, not columns.
CREATE OR REPLACE
ALTER ... { SET | UNSET }
ALTER ... ADD ROW ACCESS POLICY
ALTER ... DROP ROW ACCESS POLICY
ALTER ... DROP ALL ROW ACCESS POLICIES
DROP | UNDROP
The following table summarizes the relationship between DDL operations, supported domains, and the properties Snowflake records.
Operation |
Domain |
Properties |
Notes |
---|---|---|---|
CREATE [ OR REPLACE ] |
TABLE | EXTERNAL TABLE | VIEW | MATERIALIZED VIEW |
Column name, column identifier. |
CREATE DATABASE and CREATE SCHEMA operations do not have properties recorded. |
CREATE |
TABLE … { AS SELECT | USING TEMPLATE | LIKE | CLONE } |
Column name, column identifier. |
Snowflake records the creation source for LIKE and CLONE operations. Snowflake does not record the creation source when the source object is from a share or with USING TEMPLATE. |
ALTER … RENAME TO ALTER TABLE … RENAME COLUMN |
TABLE | VIEW | MATERIALIZED VIEW | DATABASE | SCHEMA |
The new name of the object or column. |
|
ALTER … SWAP WITH |
TABLE | SCHEMA | DATABASE |
objectName, objectId, objectDomain |
There are two records in the view, one for each swap target. Each record contains the same query identifier value. |
ALTER … { ADD | DROP } COLUMN |
TABLE |
Column name, column identifier, and the ADD or DROP subOperationType. |
|
DROP |
TABLE | VIEW | MATERIALIZED VIEW | DATABASE | SCHEMA |
Snowflake does not record properties for these operations. |
|
UNDROP |
TABLE | SCHEMA | DATABASE |
Snowflake does not record properties for these operations. |