This is a translation reference to convert the Object Variant of the Oracle Create Type Statements (UDT's) to Snowflake
SnowConvert supports a translation for Object Type Definitions itself. However their usages are still a work in progress.
Description
Object Types define a structure of data similar to a record, with the added advantages of the member function definitions. Meaning that their data may be used along some behavior within the type.
For the translation of object types, the type definition is replaced by a Semi-structured Data Type and then it is expanded on any usages across the code. For tables this means replacing the column for a Variant, adding a View so that selects (and also Views) to the original table can still function.
CREATE TYPE <type name> AS OBJECT
( [{<type column definition> | type method definition } , ...]);
Sample Source Patterns
Inserts for Simple Type usage
The next data will be inserted inside the table before querying the select. Please note these Inserts currently need to be manually migrated into Snowflake.
Oracle
INSERT INTO customer_table_demo(customer_table_id, customer_data) values(1, customer_typ_demo(1, 'First Name 1', 'Last Name 1'));INSERT INTO customer_table_demo(customer_table_id, customer_data) values(2, customer_typ_demo(2, 'First Name 2', 'Last Name 2'));
Snowflake
INSERT INTO customer_table_demo(customer_table_id, customer_data)SELECT1, OBJECT_CONSTRUCT('customer_id', 1,'cust_first_name', 'First Name 1','cust_last_name', 'Last Name 1');INSERT INTO customer_table_demo(customer_table_id, customer_data)SELECT2, OBJECT_CONSTRUCT('customer_id', 2,'cust_first_name', 'First Name 2','cust_last_name', 'Last Name 2');
CUSTOMER_TABLE_ID|CUSTOMER_DATA |
-----------------+------------------------------+
1|[1, First Name 1, Last Name 1]|
2|[2, First Name 2, Last Name 2]|
Snowflake
-- ** MSC-WARNING - MSCEWI1056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO A VARIANT **
---- TYPE DEFINITION--CREATE TYPE customer_typ_demo AS OBJECT-- ( customer_id INTEGER-- , cust_first_name VARCHAR(20)--, cust_last_name VARCHAR(20)--) ;CREATE OR REPLACETABLEPUBLIC.customer_table_demo ( customer_table_id INTEGER,customer_data VARIANT /*** MSC-WARNING - MSCEWI1062 - CUSTOM TYPE 'customer_typ_demo' USAGE CHANGED TO VARIANT ***/);--** MSC-WARNING - MSCEWI1063 - ADDED STATEMENTS BECAUSE 'customer_table_demo' USED A CUSTOM TYPE **CREATE OR REPLACEVIEWPUBLIC.customer_table_demo_view ASSELECTcustomer_table_id,customer_data:customer_id :: INTEGERAS customer_id,customer_data:cust_first_name :: VARCHARAS cust_first_name,customer_data:cust_last_name :: VARCHARAS cust_last_nameFROM PUBLIC.customer_table_demo;SELECT*FROM PUBLIC.customer_table_demo_view;
CUSTOMER_TABLE_ID|CUST_ID|CUST_FIRST_NAME|CUST_LAST_NAME|
-----------------+-------+---------------+--------------+
1|1 |First Name 1 |Last Name 1 |
2|2 |First Name 2 |Last Name 2 |
Inserts for Nested Type Usage
These statements need to be placed between the table creation and the select statement to test the output.
Oracle
INSERT INTO customer_table_demo(customer_id, customer_data) values(1, customer_typ_demo('Customer 1', email_typ_demo('email@domain.com')));INSERT INTO customer_table_demo(customer_id, customer_data) values(2, customer_typ_demo('Customer 2', email_typ_demo('email2@domain.com')));
Snowflake
INSERT INTO customer_table_demo(customer_table_id, customer_data)SELECT1, OBJECT_CONSTRUCT('cust_name', 'Customer 1','cust_email', OBJECT_CONSTRUCT('email', 'email@domain.com');INSERT INTO customer_table_demo(customer_table_id, customer_data)SELECT1, OBJECT_CONSTRUCT('cust_name', 'Customer 2','cust_email', OBJECT_CONSTRUCT('email', 'email2@domain.com');
-- ** MSC-WARNING - MSCEWI1056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO A VARIANT **
---- TYPE DEFINITIONS--CREATE TYPE email_typ_demo AS OBJECT-- ( email VARCHAR(20) ) ;-- ** MSC-WARNING - MSCEWI1056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO A VARIANT **
--CREATE TYPE customer_typ_demo AS OBJECT-- ( cust_name VARCHAR(20)--, cust_email VARIANT /*** MSC-WARNING - MSCEWI1062 - CUSTOM TYPE 'email_typ_demo' USAGE CHANGED TO VARIANT ***/--) ;CREATE OR REPLACETABLEPUBLIC.customer_table_demo ( customer_id INTEGER,customer_data VARIANT /*** MSC-WARNING - MSCEWI1062 - CUSTOM TYPE 'customer_typ_demo' USAGE CHANGED TO VARIANT ***/);--** MSC-WARNING - MSCEWI1063 - ADDED STATEMENTS BECAUSE 'customer_table_demo' USED A CUSTOM TYPE **CREATE OR REPLACEVIEWPUBLIC.customer_table_demo_view ASSELECTcustomer_id,customer_data:cust_name :: VARCHARAS cust_name,customer_data:cust_email:email :: VARCHARAS emailFROM PUBLIC.customer_table_demo;SELECT*FROM PUBLIC.customer_table_demo_view;
The view statement is being changed unnecessarily, which makes the table no longer have the same behavior in the output code. There is a work item to fix this issue.
2. DML for User-defined Types is not being transformed
DML that interacts with elements that have User-defined types within them (like a table) are not being transformed. There is a work item to implement this in the future.
3. Create Type creation options are not supported
Currently, there is no known workaround for any of the creation options, for these reasons they are not taken into account when defining the type.