This is a translation reference to convert Oracle functions to snowflake.
General Description
Most Oracle UDFs and UDFs inside packages, are being transformed to Snowflake Stored Procedures, to maintain functional equivalence, due to Snowflake UDFs having some limitations executing DML (Data Manipulation Language) statements.
CREATE OR REPLACEFUNCTIONFUN1(PAR1 VARCHAR)RETURNVARCHARIS VAR1 VARCHAR(20); VAR2 VARCHAR(20);BEGINSELECT COL1 INTO VAR1 FROM TABLE1 where col1 =1; VAR2 := PAR1 || VAR1;RETURN VAR2 ;END;
Snowflake
SnowConvert helpers Code removed from the example. You can find them here.
/*** MSC-WARNING - MSCEWI3053 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/CREATEORREPLACEPROCEDURE PUBLIC.FUN1 (PAR1 STRING)RETURNS STRINGLANGUAGE JAVASCRIPTEXECUTEASCALLERAS$$// REGION SnowConvert Helpers Code let VAR1; let VAR2; [VAR1] =EXEC(`SELECT COL1 FROM PUBLIC.TABLE1 where col1 = 1`); VAR2 =`${PAR1}${VAR1}`;return VAR2;$$;
Function inside Package
Oracle
CREATEORREPLACE PACKAGE BODY pkg1 ASFUNCTION f1(PAR1 VARCHAR) RETURNVARCHARIS VAR1 VARCHAR(20); VAR2 VARCHAR(20);BEGINSELECT COL1 INTO VAR1 FROM TABLE1 where col1 =1; VAR2 := PAR1 || VAR1;RETURN VAR2 ;END f1;END pkg1;
Snowflake
/*** MSC-WARNING - MSCEWI3053 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/CREATEORREPLACEPROCEDURE pkg1.f1 (PAR1 STRING)RETURNS STRINGLANGUAGE JAVASCRIPTEXECUTEASCALLERAS$$// REGION SnowConvert Helpers Code let VAR1; let VAR2; [VAR1] =EXEC(`SELECT COL1 FROM PUBLIC.TABLE1 where col1 = 1`); VAR2 =`${PAR1}${VAR1}`;return VAR2;$$;
Return data type mapping
Oracle PL SQL type
Snowflake equivalent
NUMBER
FLOAT
LONG
VARCHAR
VARCHAR2
STRING
BLOB
BINARY
BFILE
BINARY
Call
Inside queries
Calls of functions that were transformed to procedures inside queries are converted into a an empty Snowflake JavaScript UDF. This Snowflake UDF is generated in the STUB_UDF.sql file inside the UDF Helpers directory.
Oracle
CREATEVIEWVIEW1ASSELECT FUN1(COL2) FROM TABLE1;CREATEVIEWVIEW2ASSELECT PKG1.F1(COL1) FROM TABLE1;
Snowflake
CREATE OR REPLACEVIEWPUBLIC.VIEW1 ASSELECT/*** MSC-ERROR - MSCEWI3050 - UDF WAS TRASFORMED TO SNOWFLAKE PROCEDURE, CALLING PROCEDURES INSIDE A QUERY IS NOT SUPPORTED ***/
PUBLIC.FUN1_UDF('FUN1(COL2)') FROM PUBLIC.TABLE1;CREATE OR REPLACEVIEWPUBLIC.VIEW2 ASSELECT/*** MSC-ERROR - MSCEWI3050 - UDF WAS TRASFORMED TO SNOWFLAKE PROCEDURE, CALLING PROCEDURES INSIDE A QUERY IS NOT SUPPORTED ***/
PUBLIC.PKG1.F1_UDF('PKG1.F1(COL1)') FROM PUBLIC.TABLE1;
Inside other functions or stored procedures
Oracle
The functions that are converted to procedures are called using the EXEC Snowflake helper.
CREATE OR REPLACEFUNCTIONFUN1(x NUMBER) RETURNNUMBERIS VAR1 NUMBER;BEGIN-- FUN2 is another UDF VAR1 := FUN2(X);RETURN VAR1;END f1;
Snowflake
SnowConvert helpers Code removed from the example. You can find them here.
/*** MSC-WARNING - MSCEWI3053 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/CREATEORREPLACEPROCEDURE PUBLIC.FUN1 (x FLOAT)RETURNSFLOATLANGUAGE JAVASCRIPTEXECUTEASCALLERAS$$ // REGION SnowConvert Helpers Code let VAR1; VAR1 = (EXEC(`CALL PUBLIC.FUN2(?)`,[X]))[0];return VAR1;$$;
Different cases and limitations
Functions with DMLs
These functions cannot be executed in queries in Oracle, so their usage wont be limited when transforming them to Snowflake Procedures.
Oracle
CREATE OR REPLACEFUNCTIONFUN1(x NUMBER)RETURNNUMBERISVAR1 NUMBER;BEGIN VAR1 := VAR1 +1;INSERT INTO TABLE1(col1, col2) VALUES(X, VAR1);UPDATE TABLE2 SET COL1 = VAR1 WHERE ID = X;RETURN VAR1;END FUN1;
Snowflake
SnowConvert helpers Code removed from the example. You can find them here.
/*** MSC-WARNING - MSCEWI3053 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/CREATEORREPLACEPROCEDURE FUN1 ()RETURNSFLOATLANGUAGE JAVASCRIPTEXECUTEASCALLERAS$$// REGION SnowConvert Helpers Code let VAR1; VAR1 = VAR1 +1; // ** MSC-WARNING - MSCEWI1022 - ONE OR MORE IDENTIFIERS IN THIS STATEMENT WERE CONSIDERED PARAMETERS BY DEFAULT. REFERENCED TABLE NOT FOUND. **
EXEC(`INSERT INTO PUBLIC.TABLE1(col1, col2) VALUES(?, ?)`,[X,VAR1]); // ** MSC-WARNING - MSCEWI1022 - ONE OR MORE IDENTIFIERS IN THIS STATEMENT WERE CONSIDERED PARAMETERS BY DEFAULT. REFERENCED TABLE NOT FOUND. **
EXEC(`UPDATE TABLE2 SET COL1 = ? WHERE ID = ?`,[VAR1,X]);return VAR1;$$;
Functions with only one SELECT INTO
These functions are transformed to Snowflake SQL functions by removing the INTO part of the select.
Oracle
CREATE OR REPLACEFUNCTIONFUN1(PAR1 VARCHAR)RETURNVARCHARIS VAR1 VARCHAR(20);BEGINSELECT COL1 INTO VAR1 FROM TABLE1 where col1 = PAR1;RETURN VAR1;END;
Snowflake
CREATE OR REPLACEFUNCTIONPUBLIC.FUN1 (PAR1 STRING)RETURNS STRINGAS$$SELECT COL1 FROM PUBLIC.TABLE1 where col1 = PAR1 $$;
Functions with only logic
UDFs that do not use any SQL statement are converted into Snowflake JavaScript UDFs.
When SQL built-in functions are included in the logic the user defined function is converted to a Snowflake procedure. Translation for built in functions to a JavaScript equivalent is planned to be delivered in the future.
Examples for built-in functions: UPPER(), TRIM(), ABS().
Oracle
CREATE OR REPLACEFUNCTIONFUN1(x NUMBER)RETURNNUMBERISVAR1 NUMBER;BEGINIF x <5THEN VAR1 :=1; ELSE VAR1 :=0;ENDIF;RETURN VAR1;END FUNC01;
Snowflake
SnowConvert helpers Code removed from the example. You can find them here.
CREATE OR REPLACEFUNCTIONPUBLIC.FUN1(x FLOAT)RETURNSFLOATLANGUAGE JAVASCRIPTAS$$// REGION SnowConvert Helpers Code let VAR1;if (X <5) { VAR1 =1; } else { VAR1 =0; }return VAR1;$$;
Functions with more than one SQL statement
UDFs transformed into procedures cannot be called from a query.
Oracle
CREATE OR REPLACEFUNCTIONFUN1(x NUMBER)RETURNNUMBERISVAR1 NUMBER;BEGINSELECT COL1 INTO VAR1 FROM TABLE1 WHERE ID = X;IF VAR1 <5THEN VAR1 :=1; ELSE VAR1 :=0;ENDIF;UPDATE TABLE1 SET COL1 = VAR1 WHERE ID = X;RETURN VAR1;END FUN1;
Snowflake
SnowConvert helpers Code removed from the example. You can find them here.
CREATEORREPLACEPROCEDURE FUN1 (x FLOAT)RETURNSFLOATLANGUAGE JAVASCRIPTEXECUTEASCALLERAS$$// REGION SnowConvert Helpers Code let VAR1; // ** MSC-WARNING - MSCEWI1022 - ONE OR MORE IDENTIFIERS IN THIS STATEMENT WERE CONSIDERED PARAMETERS BY DEFAULT. REFERENCED TABLE NOT FOUND. **
[VAR1] =EXEC(`SELECT COL1 FROM PUBLIC.TABLE1 WHERE ID = ?`,[X]);if (VAR1 <5) { VAR1 =1; } else { VAR1 =0; } // ** MSC-WARNING - MSCEWI1022 - ONE OR MORE IDENTIFIERS IN THIS STATEMENT WERE CONSIDERED PARAMETERS BY DEFAULT. REFERENCED TABLE NOT FOUND. **
EXEC(`UPDATE TABLE1 SET COL1 = ? WHERE ID = ?`,[VAR1,X]);return VAR1;$$;
Functions with only logic and built-in SQL functions
This transformation is planned to be delivery in the future, currently all functions are being transformed to stored procedures.
Transformation planned to be delivered in the future
CREATE OR REPLACEFUNCTIONFUN1(x FLOAT)RETURNSNUMBERLANGUAGE JAVASCRIPTAS$$ let VAR1;if (TRUNC_EQUIVALENT(X) <5) { VAR1 =1; } else { VAR1 =0; }return VAR1;$$;
RETURN CASE
The transformation is the same transformation when the CASE is use to assign a variable. You can check the transformation of CASE in the PL/SQL section.
Oracle
CREATE OR REPLACEFUNCTIONFUN1 (flag FLOAT)RETURNNUMBERISBEGINreturnCASE flagWHEN1THEN'one'WHEN2THEN'two'WHEN3THEN'three'WHEN4THEN'four'ELSE'unknown'END;END FUN1;
SnowFlake
owConvert helpers Code removed from the example. You can find them here.
CREATE OR REPLACEFUNCTIONFUN1 (flag FLOAT)RETURNSFLOATLANGUAGE JAVASCRIPTAS$$// REGION SnowConvert Helpers Codereturn FLAG ==1 && `one`|| (FLAG ==2 && `two`|| (FLAG ==3 && `three`|| (FLAG ==4 && `four`||`unknown`)));$$;