Optimizing Snowflake (4): monitoring and debugging stored procedures using query tagging

Johan
3 min readJun 4, 2024

--

When you run Snowflake stored procedures, debugging is not the easiest thing. This is my example stored procedure, dynamically dropping tables:

create or replace procedure groupby.public.droptables(message VARCHAR)
RETURNS VARCHAR NOT NULL
LANGUAGE SQL
AS
$$
DECLARE
v_sql_query VARCHAR;
c_table CURSOR FOR SELECT TABLE_NAME FROM groupby.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC';

BEGIN
v_sql_query := '';

FOR record IN c_table DO
v_sql_query := 'DROP TABLE GROUPBY.PUBLIC.' || record.TABLE_NAME;
EXECUTE IMMEDIATE v_sql_query;
END FOR;

RETURN 'completed';
END;
$$;

call groupby.public.droptables('');

Looking at the query history, the call to the stored procedure is only the call itself:

The statements that are executed from the stored procedure are also visible in the query history. In my example — an isolated trial account with only one user — it is pretty easy to find:

But what happens when you run inside a production environment, with thousands of queries executed, how can we then trace & debug this stored procedure from the query history. One approach is to use query tagging.

We are going to add a line to the stored procedure:

ALTER SESSION SET QUERY_TAG = 'droptables';

When we now run the create procedure statement, we will get an error:

“Uncaught exception of type ‘STATEMENT_ERROR’ on line 7 at position 0 : Stored procedure execution error: Unsupported statement type ‘ALTER_SESSION’.”

The reason for this: the default “EXECUTE AS” setting for a stored procedure is EXECUTE AS OWNER. This setting will cause the above error, when we change the procedure to EXECUTE AS CALLER this will be fixed.

For a good explanation of the difference between EXECUTE AS CALLER/OWNER, I recommend this article: link.

The code for the stored procedure will now become:

create or replace procedure groupby.public.droptables(message VARCHAR)
RETURNS VARCHAR NOT NULL
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
v_sql_query VARCHAR;
c_table CURSOR FOR SELECT TABLE_NAME FROM groupby.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC';

BEGIN
ALTER SESSION SET QUERY_TAG = 'droptables';
v_sql_query := '';

FOR record IN c_table DO
v_sql_query := 'DROP TABLE GROUPBY.PUBLIC.' || record.TABLE_NAME;
EXECUTE IMMEDIATE v_sql_query;
END FOR;

RETURN 'completed';
END;
$$;

When executing the stored procedure, this will be the result in the query history:

The SET QUERY_TAG itself will not have a tag, but all commands executed with the call, which resembles a Snowflake session, have the tag. We can then use the filter option in the query history screen to see all statements:

P.S. do you see the dark screen mode in Snowflake. Just stumbled upon it today:

--

--

Johan

I am a freelance data engineer. My main focus is Snowflake, but I am always eager to learn new things. Python and AWS are my main side interests