Snowflake Context Functions
What is the context function in the Snowflake?
They are system-defined functions that fetch the result about the context in which an SQL statement (like DDL or DML statements & other statements) is executed.
These functions are evaluated at most once per statement.
Example:
- current_database()
- current_schema()
- current_role()
Why do we need to learn and master them?
- Enterprises don’t opt for Snowflake Cloud Data Warehouse for one data project or for a small data processing workload. They plan to onboard different kinds of workloads to solve their business problems.
- Enterprises don’t buy many snowflake instances, and hence many projects, many environment (dev, test, production) and all of them under single instance and that makes their information architecture very complex.
- Hence these context function become so useful and simplify your day to day job when you are building data solutions.
Watch the hands-on video
Context Function Categories & what does it mean?
General Context (8)
- current_client()
- current_date()
- current_ip_address()
- current_region()
- current_time()
- current_timestamp()
- current_version()
- sysdate()
Session Context (10)
- all_user_names()
- current_account()
- current_role()
- current_available_role()
- current_session()
- current_statement()
- current_transaction()
- current_user()
- last_query_id
- last_transaction
Session Object Context (8)
- current_database()
- current_schema()
- current_schemas()
- current_warehouse()
- invoker_role()
- invoker_share()
- is_granted_to_invoker_role()
- is_role_in_session()
Section 01 SQL Script
-- Lets see these functions in action and see what result they bring.
show functions like 'CURRENT%';
-- since they are functions like sum() or avg(), they have to be used within select statement
select
current_region(),
current_version(),
current_user(),
current_role(),
current_database(),
current_schema(),
current_schemas(),
current_warehouse();
-- Now set them and see how to change it via SQL without using the UI features
use role sysadmin;
use database my_db;
use schema my_schema;
use warehouse sap_load_wh;
Section 02 SQL Script - How to use them to set variables
-- they can also be used to set a variable value
-- you don't need to have select keyword in this case.
set my_wh = current_warehouse();
-- Now you can print them using variable name like this
select $my_wh;
-- if you have to set them for multiple variables together, you can also follow this
set (my_db, my_schema, my_wh) = (current_database(), current_schema(), current_warehouse());
select $my_db, $my_schema, $my_wh;
-- what about current_schemas and how to slipt it
set my_search_path = current_schemas();
select $my_search_path;
select * from table(strtok_split_to_table($my_search_path,',')) f;
-- we have a better way to do it
Section 03 SQL Script - Snowflake Role Hierarchy & Context functions
USE ROLE securityadmin;
CREATE ROLE admin01; -- who can create all objects
CREATE ROLE analyst01; -- analyst who can query objects
CREATE ROLE developer01; -- developer role
-- make sure these roles are accessible upward
GRANT ROLE developer01 TO ROLE admin01;
GRANT ROLE analyst01 TO ROLE admin01;
GRANT ROLE admin01 TO ROLE sysadmin;
--make sure role is mapped to user
GRANT ROLE developer01 TO USER ADMIN;
GRANT ROLE analyst01 TO USER ADMIN;
GRANT ROLE admin01 TO USER ADMIN;
--give grants
USE ROLE SYSADMIN;
GRANT CREATE DATABASE ON ACCOUNT TO ROLE admin01;
GRANT CREATE WAREHOUSE ON ACCOUNT TO ROLE admin01;
-- GRANT CREATE DATABASE ON ACCOUNT TO ROLE dev_db_admin WITH GRANT OPTION;
-- now use new role
USE ROLE admin01;
-- create a db and schema
CREATE database db01;
CREATE SCHEMA db01.schema01;
CREATE WAREHOUSE wh01
WITH WAREHOUSE_SIZE = 'XLARGE'
WAREHOUSE_TYPE = 'STANDARD'
AUTO_SUSPEND = 300
AUTO_RESUME = TRUE
MIN_CLUSTER_COUNT = 1
MAX_CLUSTER_COUNT = 1
SCALING_POLICY = 'STANDARD'
COMMENT = 'this is load wh';
-- grant roles to other roles.
GRANT USAGE ON WAREHOUSE wh01 TO ROLE analyst01;
GRANT USAGE ON WAREHOUSE wh01 TO ROLE developer01;
GRANT USAGE ON database db01 TO ROLE analyst01;
GRANT USAGE ON database db01 TO ROLE developer01;
GRANT USAGE ON SCHEMA db01.schema01 TO ROLE analyst01;
GRANT USAGE ON SCHEMA db01.schema01 TO ROLE developer01;
GRANT create table ON SCHEMA db01.schema01 TO ROLE developer01;
GRANT SELECT ON ALL TABLES IN SCHEMA db01.schema01 TO ROLE analyst01;
GRANT SELECT ON FUTURE TABLES IN SCHEMA db01.schema01 TO ROLE analyst01;
use role developer01;
use schema db01.schema01
create OR replace table t01 (c1 string);
insert into t01 (c1) values ('1');
use role analyst01;
use schema db01.schema01
select * from t01;
Section 04 SQL Script - Context Function & Task
use role sysadmin;
use schema my_db.my_schema;
select current_schema(), current_database(), current_role();
create or replace table my_logging_01(
log_id integer AUTOINCREMENT not null,
user_name string,
role_name string,
db_name string,
schema_name string,
wh_name string
);
-- lets check what happens when we insert
insert into my_logging_01 (user_name,role_name,db_name,schema_name,wh_name)
values (
current_user(),
current_role(),
current_database(),
current_schema(),
current_warehouse());
select * from my_logging_01;
-- create a task
create or replace task my_log_task_001
warehouse = 'compute_wh'
schedule = '1 minute'
as
insert into my_logging_01(user_name,role_name,db_name,schema_name,wh_name) values (current_user(),current_role(),current_database(),current_schema(),current_warehouse());
-- start the task
alter task my_log_task_001 resume;
-- check the information schema for
select * from table(information_schema.task_history()) where name ='MY_LOG_TASK_001' order by scheduled_time;
select * from my_logging_01;
Section 05 SQL Script - Stored Procedure with Owner/Caller
-- check your context
use role sysadmin;
use schema my_db.my_schema;
select current_schema(), current_database(), current_role();
-- lets create a table
create or replace table logging_sp(
log_id integer AUTOINCREMENT not null,
user_name string,
role_name string,
db_name string,
schema_name string,
wh_name string
);
-- lets check what happens when we insert
insert into logging_sp (user_name,role_name,db_name,schema_name,wh_name)
values (
current_user(),
current_role(),
current_database(),
current_schema(),
current_warehouse());
select * from logging_sp;
-- define a stored procedure with caller's role
create or replace procedure load_sp_caller()
returns boolean
language javascript
execute as caller
as
$$
sql_insert_command = `insert into logging_sp_01 (user_name,role_name,db_name,schema_name,wh_name) values (current_user(),current_role(),current_database(),current_schema(),current_warehouse());`
result_insert = snowflake.execute(
{
sqlText: sql_insert_command
});
return result_insert;
$$
;
-- define a stored procedure with owner's role
create or replace procedure load_sp_owner()
returns boolean
language javascript
execute as owner
as
$$
sql_insert_command = `insert into logging_sp_01 (user_name,role_name,db_name,schema_name,wh_name) values (current_user(),current_role(),current_database(),current_schema(),current_warehouse());`
result_insert = snowflake.execute(
{
sqlText: sql_insert_command
});
return result_insert;
$$
;
-- create a task and call the stored procedure
create or replace task my_task_with_sp_owner
warehouse = 'compute_wh'
schedule = '1 minute'
as
call load_sp_owner();
-- resume the task
alter task my_task_with_sp_owner resume;
-- create a task with caller stored procedure
create or replace task my_task_with_sp_caller
warehouse = 'compute_wh'
schedule = '1 minute'
as
call load_sp_caller();
--resume the task
alter task my_task_with_sp_caller resume;
select * from table(information_schema.task_history())
where name in ('MY_TASK_WITH_SP_OWNER','MY_TASK_WITH_SP_CALLER')
order by scheduled_time;