SnowConvert: BigQuery Functional Differences¶
Note
Conversion Scope
SnowConvert for Google BigQuery currently supports assessment and translation for TABLES and VIEWS. Although SnowConvert can recognize other types of statements, they are not fully supported.
SSC-FDM-BQ0001¶
Accessing arrays produces NULL instead of an error for positive out of bounds indexes in Snowflake.
Description¶
When accessing an ARRAY object by index in Snowflake, specifying an index greater than the size of the array will result in a NULL value, this differs with the behavior of BigQuery, where accessing an ARRAY with an index that is out of bounds will produce an error, unless the functions SAFE_OFFSET
or SAFE_ORDINAL
are used.
This warning will be added to any ARRAY access that is not safe.
Code Example¶
Input Code:¶
BigQuery¶
SELECT ([40, 12, 30])[8];
SELECT ([40, 12, 30])[SAFE_OFFSET(8)];
Generated Code:¶
Snowflake¶
SELECT
--** SSC-FDM-BQ0001 - ACCESSING ARRAYS PRODUCES NULL INSTEAD OF AN ERROR FOR POSITIVE OUT OF BOUNDS INDEXES IN SNOWFLAKE **
([40, 12, 30])[8];
SELECT
PUBLIC.SAFE_OFFSET_UDF( ([40, 12, 30]), 8);
Best Practices¶
Analyze the uses of array access in the code, if there was never the risk of getting an out of bounds error in the original code then no difference will be observed and this warning can be safely ignored.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-FDM-BQ0002¶
Exception system variables are not supported in Snowflake.
Description¶
This FDM is added when a statement references exception variables in BigQuery because they are not supported in Snowflake, and the content of these variables is quite different from the exception variables allowed in Snowflake. For more information, please refer to Handling Exceptions in Snowflake.
Code Example¶
Input Code:¶
BigQuery¶
CREATE OR REPLACE PROCEDURE test.proc1()
BEGIN
SELECT 1/0;
EXCEPTION WHEN ERROR THEN
SELECT
@@error.message as message,
@@error.stack_trace as stack_trace,
@@error.statement_text as statement_text,
@@error.formatted_stack_trace as formatted_stack_trace;
END;
Result¶
[{
"message": "Query error: division by zero: 1 / 0 at [snowflake-snowconvert-team.test.proc1:2:3]",
"stack_trace": [{
"line": "2",
"column": "3",
"filename": null,
"location": "snowflake-snowconvert-team.test.proc1"
}, {
"line": "1",
"column": "1",
"filename": null,
"location": null
}],
"statement_text": "SELECT 1/0",
"formatted_stack_trace": "At snowflake-snowconvert-team.test.proc1[2:3]\nAt [1:1]\n"
}]
Generated Code:¶
Snowflake¶
CREATE OR REPLACE PROCEDURE test.proc1 ()
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "bigquery", "convertedOn": "04/09/2025", "domain": "test" }}'
AS
$$
BEGIN
SELECT 1/0;
EXCEPTION WHEN OTHER THEN
-- --** SSC-FDM-BQ0002 - EXCEPTION SYSTEM VARIABLES ARE NOT SUPPORTED IN SNOWFLAKE. **
-- SELECT
-- @@error.message as message,
-- @@error.stack_trace as stack_trace,
-- @@error.statement_text as statement_text,
-- @@error.formatted_stack_trace as formatted_stack_trace;
RETURN OBJECT_CONSTRUCT('SQLERRM', SQLERRM, 'SQLCODE', SQLCODE, 'SQLSTATE', SQLSTATE);
END;
$$;
Result¶
{
"SQLCODE": 100051,
"SQLERRM": "Division by zero",
"SQLSTATE": "22012"
}
Best Practices¶
Snowflake has three built-in variables that provide information about the exception:
SQLSTATE: This is a 5-character code modeled on the ANSI SQL standard SQLSTATE .
SQLERRM: This is an error message.
SQLCODE: This is a 5-digit signed integer.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-FDM-BQ0003¶
Unable to generate correct return table clause due to missing dependent object information.
Description¶
Snowflake requires a valid RETURNS TABLE clause for CREATE TABLE FUNCTION statements.
SnowConvert may encounter scenarios where the original BigQuery source code does not have a RETURNS TABLE clause, and has to build a new one from the ground up. To do this, an analysis is made to the CREATE TABLE FUNCTION query in order to properly infer the types of the columns of the resulting table. When SnowConvert cannot gather the required information, this EWI is added.
Code Example¶
Input Code:¶
BigQuery¶
CREATE OR REPLACE TABLE FUNCTION function_name_noreturns_asterisk_join (parameter_name INTEGER)
AS
SELECT *
FROM unknownTable1 t1
JOIN unknownTable2 t2 ON t1.col1 = t2.fk_col1;
Generated Code:¶
Snowflake¶
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECTS "unknownTable1", "unknownTable2" **
CREATE OR REPLACE FUNCTION function_name_noreturns_asterisk_join (parameter_name INTEGER)
----** SSC-FDM-BQ0003 - UNABLE TO GENERATE CORRECT RETURNS TABLE CLAUSE DUE TO MISSING DEPENDENT OBJECT INFORMATION. **
--RETURNS TABLE (
--)
AS
$$
SELECT *
FROM
unknownTable1 t1
JOIN
unknownTable2 t2 ON t1.col1 = t2.fk_col1
$$;
Best Practices¶
Always try to include any dependent object definitions in the input code, so that SnowConvert has access to important information.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-FDM-BQ0004¶
The INFER_SCHEMA function requires a file path without wildcards to generate the table template, replace the FILE_PATH placeholder with it
Warning
This FDM is deprecated; please refer to SSC-FDM-0035 for the latest version of this FDM.
Description¶
The INFER_SCHEMA function is used in Snowflake to generate the columns definition of a table based on the structure of a file, it requires a LOCATION parameter that specifies the path to a file or folder that will be used to construct the table columns, however, this path does not support regex, meaning that the wildcard *
character is not supported.
When the table has no columns, SnowConvert will check all URIS in order to find one that does not use wildcards and use it in the INFER_SCHEMA function, when no URI meets such criteria this FDM and a FILE_PATH placeholder will be generated, the placeholder has to be replaced with the path of one of the files referenced by the external table in order to generate the table columns.
Code Example¶
Input Code:¶
BigQuery¶
CREATE OR REPLACE EXTERNAL TABLE test.my_external_table_json2
OPTIONS(
FORMAT='JSON',
URIS=['gs://sc_external_table_bucket/folder_with_json/*']
);
Generated Code:¶
Snowflake¶
CREATE OR REPLACE TEMPORARY FILE FORMAT SC_TEST_MY_EXTERNAL_TABLE_JSON2_FORMAT
TYPE = JSON;
CREATE OR REPLACE EXTERNAL TABLE test.my_external_table_json2 USING TEMPLATE (
SELECT
ARRAY_AGG(OBJECT_CONSTRUCT('COLUMN_NAME', COLUMN_NAME, 'TYPE', TYPE, 'NULLABLE', NULLABLE, 'EXPRESSION', EXPRESSION))
FROM
--** SSC-FDM-BQ0004 - THE INFER_SCHEMA FUNCTION REQUIRES A FILE PATH WITHOUT WILDCARDS TO GENERATE THE TABLE TEMPLATE, REPLACE THE FILE_PATH PLACEHOLDER WITH IT **
TABLE(INFER_SCHEMA(LOCATION => '@EXTERNAL_STAGE/FILE_PATH', FILE_FORMAT => 'SC_TEST_MY_EXTERNAL_TABLE_JSON2_FORMAT'))
)
!!!RESOLVE EWI!!! /*** SSC-EWI-BQ0015 - EXTERNAL TABLE REQUIRES AN EXTERNAL STAGE TO ACCESS gs://sc_external_table_bucket, DEFINE AND REPLACE THE EXTERNAL_STAGE PLACEHOLDER ***/!!!
LOCATION = @EXTERNAL_STAGE
AUTO_REFRESH = false
PATTERN = 'folder_with_json/.*'
FILE_FORMAT = (TYPE = JSON);
Best Practices¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-FDM-BQ0005¶
Parsing the CSV header is not supported in external tables, columns must be renamed to match the original names
Description¶
Currently, Snowflake external tables do not support parsing the header of CSV files. When a external table with no explicit column list and CSV file format is found, SnowConvert will produce the SKIP_HEADER file format option to avoid runtime errors, however, this will cause the table column names to have the autogenerated names c1, c2, …, cN.
This FDM is generated to notify that the header can not be parsed and that manually renaming the columns is necessary to preserve the original column names.
Code Example¶
Input Code:¶
BigQuery¶
CREATE OR REPLACE EXTERNAL TABLE test.my_external_table_csv
OPTIONS(
FORMAT='CSV',
URIS=['gs://sc_external_table_bucket/folder_with_csv/Employees.csv']
);
Generated Code:¶
Snowflake¶
CREATE OR REPLACE TEMPORARY FILE FORMAT SC_TEST_MY_EXTERNAL_TABLE_CSV_FORMAT
TYPE = CSV
SKIP_HEADER = 1;
CREATE OR REPLACE EXTERNAL TABLE test.my_external_table_csv
--** SSC-FDM-BQ0005 - PARSING THE CSV HEADER IS NOT SUPPORTED IN EXTERNAL TABLES, COLUMNS MUST BE RENAMED TO MATCH THE ORIGINAL NAMES **
USING TEMPLATE (
SELECT
ARRAY_AGG(OBJECT_CONSTRUCT('COLUMN_NAME', COLUMN_NAME, 'TYPE', TYPE, 'NULLABLE', NULLABLE, 'EXPRESSION', EXPRESSION))
FROM
TABLE(INFER_SCHEMA(LOCATION => '@EXTERNAL_STAGE/folder_with_csv/Employees.csv', FILE_FORMAT => 'SC_TEST_MY_EXTERNAL_TABLE_CSV_FORMAT'))
)
!!!RESOLVE EWI!!! /*** SSC-EWI-0032 - EXTERNAL TABLE REQUIRES AN EXTERNAL STAGE TO ACCESS gs://sc_external_table_bucket, DEFINE AND REPLACE THE EXTERNAL_STAGE PLACEHOLDER ***/!!!
LOCATION = @EXTERNAL_STAGE
AUTO_REFRESH = false
PATTERN = 'folder_with_csv/Employees.csv'
FILE_FORMAT = (TYPE = CSV SKIP_HEADER = 1);
Best Practices¶
Please rename the table columns to their original names from the file to complete the transformation
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-FDM-BQ0006¶
Reading from Google Drive is not supported in Snowflake, upload the files to the external location and replace the FILE_PATH placeholders
Description¶
Snowflake does not support reading data from files hosted in Google Drive, this FDM is generated to notify it, please upload the Google Drive files to the external location so they can be accessed through the external stage.
The PATTERN clause will hold autogenerated placeholders FILE_PATH0, FILE_PATH1, …, FILE_PATHN that should be replaced with the file/folder path after the files were moved to the external location.
Code Example¶
Input Code:¶
BigQuery¶
CREATE OR REPLACE EXTERNAL TABLE test.my_external_table_drive_test
OPTIONS(
FORMAT='JSON',
URIS=['https://drive.google.com/open?id=someFileId']
);
Generated Code:¶
Snowflake¶
CREATE OR REPLACE TEMPORARY FILE FORMAT SC_TEST_MY_EXTERNAL_TABLE_DRIVE_TEST_FORMAT
TYPE = JSON;
CREATE OR REPLACE EXTERNAL TABLE test.my_external_table_drive_test USING TEMPLATE (
SELECT
ARRAY_AGG(OBJECT_CONSTRUCT('COLUMN_NAME', COLUMN_NAME, 'TYPE', TYPE, 'NULLABLE', NULLABLE, 'EXPRESSION', EXPRESSION))
FROM
--** SSC-FDM-0035 - THE INFER_SCHEMA FUNCTION REQUIRES A FILE PATH WITHOUT WILDCARDS TO GENERATE THE TABLE TEMPLATE, REPLACE THE FILE_PATH PLACEHOLDER WITH IT **
TABLE(INFER_SCHEMA(LOCATION => '@EXTERNAL_STAGE/FILE_PATH', FILE_FORMAT => 'SC_TEST_MY_EXTERNAL_TABLE_DRIVE_TEST_FORMAT'))
)
!!!RESOLVE EWI!!! /*** SSC-EWI-0032 - EXTERNAL TABLE REQUIRES AN EXTERNAL STAGE TO ACCESS AN EXTERNAL LOCATION, DEFINE AND REPLACE THE EXTERNAL_STAGE PLACEHOLDER ***/!!!
LOCATION = @EXTERNAL_STAGE
AUTO_REFRESH = false
--** SSC-FDM-BQ0006 - READING FROM GOOGLE DRIVE IS NOT SUPPORTED IN SNOWFLAKE, UPLOAD THE FILES TO THE EXTERNAL LOCATION AND REPLACE THE FILE_PATH PLACEHOLDERS **
PATTERN = 'FILE_PATH0'
FILE_FORMAT = (TYPE = JSON);
Best Practices¶
Complete the transformation by uploading the files hosted in Google Drive to the external location referenced by the external stage and replace the FILE_PATH placeholders
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-FDM-BQ0007¶
Reading from spreadsheets is not supported in snowflake, use the CSV file type instead
Description¶
Snowflake does not support Google Sheets as a file format, however, its structure is similar to CSV files, which are supported by Snowflake.
When SnowConvert detects a external table using the GOOGLE_SHEETS format, it will produce a external table with the CSV file format instead.
This FDM is generated to notify the user that the transformation now expects a CSV file instead of Google Sheets.
Code Example¶
Input Code:¶
BigQuery¶
CREATE OR REPLACE EXTERNAL TABLE test.spreadsheetTable
(
Name STRING,
Code INTEGER,
Price INTEGER,
Expiration_date DATE
)
OPTIONS(
format="GOOGLE_SHEETS",
skip_leading_rows = 1,
uris=['https://docs.google.com/spreadsheets/d/someFileId/edit?usp=sharing']
);
Generated Code:¶
Snowflake¶
--** SSC-FDM-BQ0007 - READING FROM SPREADSHEETS IS NOT SUPPORTED IN SNOWFLAKE, USE THE CSV FILE TYPE INSTEAD **
CREATE OR REPLACE EXTERNAL TABLE test.spreadsheetTable
(
Name STRING AS CAST(GET_IGNORE_CASE($1, 'c1') AS STRING),
Code INTEGER AS CAST(GET_IGNORE_CASE($1, 'c2') AS INTEGER),
Price INTEGER AS CAST(GET_IGNORE_CASE($1, 'c3') AS INTEGER),
Expiration_date DATE AS CAST(GET_IGNORE_CASE($1, 'c4') AS DATE)
)
!!!RESOLVE EWI!!! /*** SSC-EWI-BQ0015 - EXTERNAL TABLE REQUIRES AN EXTERNAL STAGE TO ACCESS A EXTERNAL LOCATION, DEFINE AND REPLACE THE EXTERNAL_STAGE PLACEHOLDER ***/!!!
LOCATION = @EXTERNAL_STAGE
AUTO_REFRESH = false
--** SSC-FDM-BQ0006 - READING FROM GOOGLE DRIVE IS NOT SUPPORTED IN SNOWFLAKE, UPLOAD THE FILES TO THE EXTERNAL LOCATION AND REPLACE THE FILE_PATH PLACEHOLDERS **
PATTERN = 'FILE_PATH0'
FILE_FORMAT = (TYPE = CSV SKIP_HEADER = 1);
Best Practices¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-FDM-BQ0008¶
Where clause references a column of STRUCT type.
Description¶
If an Snowflake Object has a key value format, when a comparison is made with another Object, Snowflake compares both key and value. On the other hand, when BigQuery compares between Structs, it compares only values, regardless if the Struct has keys or not.
This difference between comparisons may cause that the results are not the same in SnowConvert and BigQuery for the same comparison. This FDM is added when a comparison is made on a Snowflake Object created from a BigQuery Struct.
Code Example¶
Input:¶
BigQuery¶
CREATE OR REPLACE TABLE test.compExprTable
(
COL1 STRUCT<sc1 INT64>,
COL2 STRUCT<sc2 INT64>
);
SELECT * FROM test.compExprTable WHERE COL1 <> (COL2);
Output:¶
Snowflake¶
CREATE OR REPLACE TABLE test.compExprTable
(
COL1 VARIANT /*** SSC-FDM-0034 - STRUCT<INT64> CONVERTED TO VARIANT. SOME OF ITS USAGES MIGHT HAVE FUNCTIONAL DIFFERENCES. ***/,
COL2 VARIANT /*** SSC-FDM-0034 - STRUCT<INT64> CONVERTED TO VARIANT. SOME OF ITS USAGES MIGHT HAVE FUNCTIONAL DIFFERENCES. ***/
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "bigquery", "convertedOn": "07/02/2025", "domain": "no-domain-provided" }}';
SELECT * FROM
test.compExprTable
--** SSC-FDM-BQ0008 - WHERE CLAUSE REFERENCES A COLUMN OF STRUCT TYPE. COMPARISON OPERATIONS MAY PRODUCE DIFFERENT RESULTS IN SNOWFLAKE. **
WHERE COL1 <> (COL2);
Best Practices¶
If you need more support, you can email us at snowconvert-support@snowflake.com