Snowflake SQL translation guide
This document details the similarities and differences in SQL syntax between Snowflake and BigQuery to help accelerate the planning and execution of moving your EDW (Enterprise Data Warehouse) to BigQuery. Snowflake data warehousing is designed to work with Snowflake-specific SQL syntax. Scripts written for Snowflake might need to be altered before you can use them in BigQuery, because the SQL dialects vary between the services. Use batch SQL translation to migrate your SQL scripts in bulk, or interactive SQL translation to translate ad hoc queries. Snowflake SQL is supported by both tools in preview.
Data types
This section shows equivalents between data types in Snowflake and in BigQuery.
| Snowflake | BigQuery | Notes |
|---|---|---|
NUMBER/
DECIMAL/NUMERIC |
NUMERIC/BIGNUMERIC |
Can be mapped to NUMERIC or BIGNUMERIC, depending on precision and scale.The NUMBER data type in Snowflake supports 38 digits of precision and 37 digits of scale. Precision and scale can be specified according to the user.BigQuery supports NUMERIC and BIGNUMERIC with optionally specified precision and scale within certain bounds. |
INT/INTEGER |
BIGNUMERIC |
INT/INTEGER and all other INT-like datatypes, such as BIGINT, TINYINT, SMALLINT, BYTEINT represent an alias for the NUMBER datatype where the precision and scale cannot be specified and is always NUMBER(38, 0)BigQuery converts INTEGER to INT64 by default. To configure the SQL translation to convert it to other data types, you can use the REWRITE_ZERO_SCALE_NUMERIC_AS_INTEGER configuration option |
BIGINT |
BIGNUMERIC |
|
SMALLINT |
BIGNUMERIC |
|
TINYINT |
BIGNUMERIC |
|
BYTEINT |
BIGNUMERIC |
|
FLOAT/ |
FLOAT64 |
The FLOAT data type in Snowflake establishes 'NaN' as > X, where X is any FLOAT value (other than 'NaN' itself).The FLOAT data type in BigQuery establishes 'NaN' as < X, where X is any FLOAT value (other than 'NaN' itself). |
DOUBLE/REAL |
FLOAT64 |
The DOUBLE data type in Snowflake is synonymous with the FLOAT data type in Snowflake, but is commonly incorrectly displayed as FLOAT. It is properly stored as DOUBLE. |
VARCHAR |
STRING |
The VARCHAR data type in Snowflake has a maximum length of 128 MB (uncompressed). If length is not specified, the default is the maximum length.The STRING data type in BigQuery is stored as variable length UTF-8 encoded Unicode. For more information about column and row limits, see Query jobs. |
CHAR/CHARACTER |
STRING |
|
STRING/TEXT |
STRING |
The STRING data type in Snowflake is synonymous with Snowflake's VARCHAR. |
BINARY |
BYTES |
|
VARBINARY |
BYTES |
|
BOOLEAN |
BOOL |
The BOOL data type in BigQuery can only accept TRUE/FALSE, unlike the BOOL data type in Snowflake, which can accept TRUE/FALSE/NULL. |
DATE |
DATE |
The DATE type in Snowflake accepts most common date formats, unlike the DATE type in BigQuery, which only accepts dates in the format, 'YYYY-[M]M-[D]D'. |
TIME |
TIME |
The TIME type in Snowflake supports 0 to 9 nanoseconds of precision, whereas the TIME type in BigQuery supports 0 to 6 nanoseconds of precision. |
TIMESTAMP |
DATETIME |
TIMESTAMP is a user-configurable alias which defaults to TIMESTAMP_NTZ which maps to DATETIME in BigQuery. |
TIMESTAMP_LTZ |
TIMESTAMP |
|
TIMESTAMP_NTZ/DATETIME | DATETIME |
|
TIMESTAMP_TZ |
TIMESTAMP |
|
OBJECT |
JSON |
|
VARIANT |
JSON |
|
ARRAY |
ARRAY<JSON> |
The SQL translation service preserves the data type for typed arrays. For untyped arrays, such as ARRAY<VARIANT>, BigQuery converts these to ARRAY<JSON> |
BigQuery also has the following data types which do not have a direct Snowflake analogue:
CREATE FUNCTION syntax
The following table addresses differences in SQL UDF creation syntax between Snowflake and BigQuery.
| Snowflake | BigQuery |
|---|---|
|
Note: In BigQuery SQL UDF, return data type is optional. BigQuery infers the result type of the function from the SQL function body when a query calls the function. |
|
Note:In BigQuery SQL UDF, returning table type is not supported but is on the product roadmap and will be available soon. However, BigQuery supports returning ARRAY of type STRUCT. |
|
Note: Snowflake provides secure option to restrict UDF definition and details only to authorized users (that is, users who are granted the role that owns the view). |
Note: Function security is not a configurable parameter in BigQuery. BigQuery supports creating IAM roles and permissions to restrict access to underlying data and function definition. |
|
Note: Function behaviour for null inputs is implicitly handled in BigQuery and need not be specified as a separate option. |
|
Note:Function volatility is not a configurable parameter in BigQuery. All BigQuery UDF volatility is equivalent to Snowflake's IMMUTABLE volatility (that is, it does not do database lookups or otherwise use information not directly present in its argument list). |
|
CREATE [OR REPLACE] FUNCTION
Note: Using single quotes or a character sequence like dollar quoting ($$) is not required or supported in BigQuery. BigQuery implicitly interprets the SQL expression. |
|
Note: Adding comments or descriptions in UDFs is not supported in BigQuery. |
Note: Snowflake does not support ANY TYPE for SQL UDFs. However, it supports using VARIANT data types. |
Note: BigQuery supports using ANY TYPE as argument type. The function will accept an input of any type for this argument. For more information, see templated parameter in BigQuery. |
BigQuery also supports the CREATE FUNCTION IF NOT EXISTSstatement
which treats the query as successful and takes no action if a function with the
same name already exists.
BigQuery's CREATE FUNCTIONstatement also supports creating
TEMPORARY or TEMP functions, which do
not have a Snowflake equivalent. See
calling UDFs
for details on executing a BigQuery persistent UDF.
DROP FUNCTION syntax
The following table addresses differences in DROP FUNCTION syntax between Snowflake and BigQuery.
| Snowflake | BigQuery |
|---|---|
|
Note: BigQuery does not require using the function's signature (argument data type) for deleting the function. |
BigQuery requires that you specify the project_name if the function
is not located in the current project.
Additional function commands
This section covers additional UDF commands supported by Snowflake that are not directly available in BigQuery.
ALTER FUNCTION syntax
Snowflake supports the following operations using
ALTER FUNCTION
syntax.
- Renaming a UDF
- Converting to (or reverting from) a secure UDF
- Adding, overwriting, removing a comment for a UDF
As configuring function security and adding function comments is not available
in BigQuery, ALTER FUNCTION syntax is not supported. However,
the CREATE FUNCTION
statement can be used to create a UDF with the same function definition but a
different name.
DESCRIBE FUNCTION syntax
Snowflake supports describing a UDF using DESC[RIBE] FUNCTION syntax. This is not supported in BigQuery. However, querying UDF metadata via INFORMATION SCHEMA will be available soon as part of the product roadmap.
SHOW USER FUNCTIONS syntax
In Snowflake, SHOW USER FUNCTIONS syntax can be used to list all UDFs for which users have access privileges. This is not supported in BigQuery. However, querying UDF metadata via INFORMATION SCHEMA will be available soon as part of the product roadmap.
Stored procedures
Snowflake stored procedures are written in JavaScript, which can execute SQL statements by calling a JavaScript API. In BigQuery, stored procedures are defined using a block of SQL statements.
CREATE PROCEDURE syntax
In Snowflake, a stored procedure is executed with a CALL command while in BigQuery, stored procedures are executed like any other BigQuery function.
The following table addresses differences in stored procedure creation syntax between Snowflake and BigQuery.
| Snowflake | BigQuery |
|---|---|
|
Note: Snowflake requires that stored procedures return a single value. Hence, return data type is a required option. |
CREATE [OR REPLACE] PROCEDURE
Note: BigQuery doesn't support a return type for stored procedures. Also, it requires specifying argument mode for each argument passed. |
|
|
|
CREATE [OR REPLACE] PROCEDURE
Note: Procedure behavior for null inputs is implicitly handled in BigQuery and need not be specified as a separate option. |
CREATE [OR REPLACE] PROCEDURE
|
Note:Procedure volatility is not a configurable parameter in BigQuery. It's equivalent to Snowflake's IMMUTABLE volatility. |
CREATE [OR REPLACE] PROCEDURE
|
Note: Adding comments or descriptions in procedure definitions is not supported in BigQuery. |
CREATE [OR REPLACE] PROCEDURE
Note: Snowflake supports specifying the caller or owner of the procedure for execution |
Note: BigQuery stored procedures are always executed as the caller |
BigQuery also supports the CREATE PROCEDURE IF NOT EXISTS statement
which treats the query as successful and takes no action if a function with the
same name already exists.
DROP PROCEDURE syntax
The following table addresses differences in DROP FUNCTION syntax between Snowflake and BigQuery.
| Snowflake | BigQuery |
|---|---|
|
Note: BigQuery does not require using procedure's signature (argument data type) for deleting the procedure. |
BigQuery requires that you specify the project_name if the procedure
is not located in the current project.
Additional procedure commands
Snowflake provides additional commands like
ALTER PROCEDURE,
DESC[RIBE] PROCEDURE,
and
SHOW PROCEDURES
to manage the stored procedures. These are not supported in
BigQuery.
Metadata and transaction SQL statements
| Snowflake | BigQuery |
|---|---|
|
BigQuery always uses Snapshot Isolation. For details, see Consistency guarantees elsewhere in this document. |
|
Not used in BigQuery. |
|
Not used in BigQuery |
|
Not used in BigQuery. |
Multi-statement and multi-line SQL statements
Both Snowflake and BigQuery support transactions (sessions) and therefore support statements separated by semicolons that are consistently executed together. For more information, see Multi-statement transactions.
Metadata columns for staged files
Snowflake automatically generates metadata for files in internal and external stages. This metadata can be queried and loaded into a table alongside regular data columns. The following metadata columns can be utilized:
Consistency guarantees and transaction isolation
Both Snowflake and BigQuery are atomic—that is, ACID-compliant on a per-mutation level across many rows.
Transactions
Each Snowflake transaction is assigned a unique start time (includes
milliseconds) that is set as the transaction ID. Snowflake only supports the
READ COMMITTED
isolation level. However, a statement can see changes made by another statement
if they are both in the same transaction - even though those changes are not
committed yet. Snowflake transactions acquire locks on resources (tables) when
that resource is being modified. Users can adjust the maximum time a blocked
statement will wait until the statement times out. DML statements are
autocommitted if the
AUTOCOMMIT
parameter is turned on.
BigQuery also supports transactions. BigQuery helps ensure optimistic concurrency control (first to commit wins) with snapshot isolation, in which a query reads the last committed data before the query starts. This approach guarantees the same level of consistency on a per-row, per-mutation basis and across rows within the same DML statement, yet avoids deadlocks. In the case of multiple DML updates against the same table, BigQuery switches to pessimistic concurrency control. Load jobs can run completely independently and append to tables. However, BigQuery does not provide an explicit transaction boundary or session.
Rollback
If a Snowflake transaction's session is unexpectedly terminated before the transaction is committed or rolled back, the transaction is left in a detached state. The user should run SYSTEM$ABORT_TRANSACTION to abort the detached transaction or Snowflake will roll back the detached transaction after four idle hours. If a deadlock occurs, Snowflake detects the deadlock and selects the more recent statement to roll back. If the DML statement in an explicitly opened transaction fails, the changes are rolled back, but the transaction is kept open until it is committed or rolled back. DDL statements in Snowflake cannot be rolled back as they are autocommitted.
BigQuery supports the
ROLLBACK TRANSACTION statement.
There is no
ABORT statement
in BigQuery.
Database limits
Always check the BigQuery public documentation for the latest quotas and limits. Many quotas for large-volume users can be raised by contacting the Cloud Support team.
All Snowflake accounts have soft-limits set by default. Soft-limits are set during account creation and can vary. Many Snowflake soft-limits can be raised through the Snowflake account team or a support ticket.
The following table shows a comparison of the Snowflake and BigQuery database limits.
| Limit | Snowflake | BigQuery |
|---|---|---|
| Size of query text | 1 MB | 1 MB |
| Maximum number of concurrent queries | XS Warehouse - 8 S Warehouse - 16 M Warehouse - 32 L Warehouse - 64 XL Warehouse - 128 |
100 |