Oracle - Create Type¶
This is a translation reference to convert Oracle Create Type Statements (UDTs) to snowflake
General Description¶
Many Oracle CREATE TYPE statements are translated to Snowflake native user-defined types where the shape is supported—for example object types with attributes, VARRAY mapped to Snowflake ARRAY, and nested table types mapped to ARRAY of the element type. Unsupported options (subtype inheritance, member bodies, incomplete types, and others) are flagged with Oracle-specific EWIs; see Related EWIs and the issues reference.
One of the most important features the Oracle database engine offers is an Object-Oriented approach. PL/SQL offers capabilities beyond other relational databases in the form of OOP by using Java-like statements in the form of packages, functions, tables and types. This document will cover the last one and how it is solved, remaining compliant to functionality.
Oracle supports the following specifications:
- Abstract Data Type (ADT) (including an SQLJ object type).
- Standalone varying array (varray) type.
- Standalone nested table type.
- Incomplete object type.
All this according to the information found in Oracle Create Type Statement Documentation
Limitations¶
Native user-defined types (CREATE TYPE … AS OBJECT, ARRAY, etc.) are supported as documented in the SQL data types overview. Many Oracle type definitions are mapped to those native types. Patterns that still have no or partial mapping—such as subtype inheritance (UNDER), member methods and type bodies, table types, and incomplete forward declarations—may require manual redesign or are reported via EWIs (for example SSC-EWI-OR0139 through SSC-EWI-OR0142). Semi-structured Data Types remain relevant for legacy scenarios that still use VARIANT in converted code.
Following are the User Defined Types features for which NO workaround is proposed:
Subtypes: Type Hierarchy¶
These statements aren’t supported in Snowflake. They are only recognized, but no translation is offered.
Type properties¶
These refer to the options that are normally used when using OOP in PL/SQL: Persistable, Instantiable and Final.
Nested Table Type¶
These statements aren’t supported in Snowflake. They are only recognized, but no translation is offered.
Type Source Creation Options¶
These options stand for custom options regarding access and querying the type.
Proposed workarounds¶
About types definition¶
For the definition, the proposed workaround is to create semi-structure data type to mimic Oracle’s data type.
About types member function¶
For the member functions containing logic and DML, the proposed workaround relies on helpers to translate this into stored procedures.
Current Translation Support¶
The next table shows a summary of the current translation support. Please keep in mind that translations may still not be final, and more work may be needed.
| Type Statement Element | Current recognition status | Current translation status | Has Known Workarounds |
|---|---|---|---|
| Object Type Definitions | Recognized. | Translated to Snowflake CREATE TYPE … AS OBJECT where supported. | Yes. |
| Subtype Definitions | Recognized. | Not Translated. | No. |
| Array Type Definitions | Recognized. | Translated to Snowflake CREATE TYPE … AS ARRAY (see SSC-FDM-0043). | Yes. |
| Nested Table Definitions | Recognized. | Translated to Snowflake ARRAY of element type where supported. | Limited. |
| Member Function Definitions | Recognized. | Not Translated. | Yes. |
Known Issues¶
1. DML usages for Object Types — partial support¶
DDL definitions for User-Defined Types are translated to native Snowflake CREATE TYPE … AS OBJECT / … AS ARRAY where the shape is supported. Constructor calls (for example address_type('123 Main St', …) for object types and VARRAY_TYPE('a', 'b', 'c') for VARRAY / nested-table types) are now also translated to OBJECT_CONSTRUCT(…) :: <type> and ARRAY_CONSTRUCT(…) :: <type> respectively, in INSERT … VALUES, INSERT … SELECT, UPDATE … SET, top-level SELECT, and PL/SQL variable initialization. DML that relies on object-type member functions or other Oracle-specific UDT operations may still require manual review; an SSC-EWI-0073 is emitted in those cases.
2. 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.
Related EWIs¶
Deprecation and replacement messaging for legacy “not supported” issues: SSC-EWI-0056, SSC-EWI-0095, SSC-EWI-OR0007.
Unsupported or incomplete CREATE TYPE shapes: SSC-EWI-OR0139, SSC-EWI-OR0140, SSC-EWI-OR0141, SSC-EWI-OR0142.
Functional differences: SSC-FDM-0043 (array size limit removed; replaces deprecated SSC-FDM-OR0051), SSC-FDM-OR0052–SSC-FDM-OR0054.
Array Type Definition¶
This is a translation reference to convert the Array Variant of the Oracle Create Type Statements (UDTs) to Snowflake
Note
Oracle VARRAY types are translated to Snowflake CREATE TYPE … AS ARRAY ( element_type ). Fixed varray capacity is not preserved; see SSC-FDM-0043. Column usages may still be migrated to VARIANT in older or mixed scenarios—verify generated DDL for your workload.
VARRAY and nested-table constructor calls (for example phone_list_typ_demo('2000-0000', '4000-0000')) used in INSERT, UPDATE and top-level SELECT are translated to ARRAY_CONSTRUCT(...) :: <type_name>. See VARRAY constructor calls in DML below.
Note
Some parts in the output code are omitted for clarity reasons.
Description¶
Array Types define an array structure of a previously existing datatype (including other Custom Types).
For many workloads, the type definition is emitted as a Snowflake native ARRAY type. Usages in tables and PL/SQL may still involve Semi-structured Data Types or OBJECT depending on context.
Sample Source Patterns¶
Inserts for the array usage¶
VARRAY and nested-table constructor calls used in INSERT … VALUES, INSERT … SELECT, UPDATE and top-level SELECT are translated to ARRAY_CONSTRUCT(...) and explicitly cast to the original UDT name with :: <type>, so column type checks against the UDT continue to succeed.
Oracle¶
Snowflake¶
VARRAY constructor calls in DML¶
The translator handles standalone constructor calls in INSERT … VALUES, INSERT … SELECT, UPDATE … SET, and top-level SELECT statements. For nested-table types defined with CREATE TYPE … AS TABLE OF … the same ARRAY_CONSTRUCT(...) :: <type> shape is produced.
Oracle¶
Snowflake¶
Oracle (top-level SELECT)¶
Snowflake¶
Array Type usage¶
Oracle¶
Results¶
| CUSTOMER_TABLE_ID | CUSTOMER_DATA |
|---|---|
| 1 | [[’2000-0000’,’4000-0000’,’0000-0000’]] |
| 1 | [[’8000-2000’,’0000-0000’,’5000-0000’]] |
Snowflake¶
Results¶
| CUSTOMER_TABLE_ID | CUSTOMER_DATA |
|---|---|
| 1 | [[’2000-0000’, ’4000-0000’, ’0000-0000’]] |
| 1 | [[’8000-2000’, ’0000-0000’, ’5000-0000’]] |
Known Issues¶
1. 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.
2. Migrated code output is not functional¶
The statements are being changed unnecessarily, which makes them no longer be functional on the output code. This will be addressed when a proper transformation for them is in place.
Related EWIs¶
- SSC-EWI-0062: Custom type usage changed to variant.
- SSC-EWI-0073: Pending Functional Equivalence Review.
Member Function Definitions¶
This is a translation reference to convert the Member Functions of the Oracle Create Type Statements (UDTs) to Snowflake
Danger
Type member functions and type body definitions are still not recognized. This page is only used as a future reference for translation.
Note
Some parts in the output code are omitted for clarity reasons.
Description¶
Like other Class definitions, Oracle’s TYPE can implement methods to expose behaviors based on its attributes. MEMBER FUCTION will be transformed to Snowflake’s Stored Procedures, to maintain functional equivalence due to limitations.
Since functions are being transformed into procedures, the transformation reference for PL/SQL also applies here.
Sample Source Patterns¶
Inserts for Simple square() member function¶
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¶
Snowflake¶
Simple square() member function¶
Oracle¶
Results¶
| T.COLUMN1.GET_SQUARE() |
|---|
| 25 |
Snowflake¶
Results¶
| GET_SQUARE() |
|---|
| 25 |
Known Issues¶
No Known issues.
Related EWIs¶
- SSC-EWI-0056: Create Type Not Supported.
- SSC-EWI-0062: Custom type usage changed to variant.
- SSC-EWI-0073: Pending Functional Equivalence Review.
- SSC-EWI-OR0007: Create Type Not Supported in Snowflake
Nested Table Type Definition¶
This is a translation reference to convert the Nested Table Variant of the Oracle Create Type Statements (UDTs) to Snowflake
Note
Standalone CREATE TYPE … AS TABLE OF element_type is translated to Snowflake CREATE TYPE … AS ARRAY ( element_type ) when the element type is supported. Nested tables used as table columns may still require manual review depending on DML and PL/SQL usage.
Description¶
Nested Table Types define an embedded table structure of a previously existing datatype (including other Custom Types). They are closely related to Array Type definitions; many patterns are mapped to Snowflake ARRAY.
Sample Source Patterns¶
Nested Table Type usage¶
Oracle¶
Snowflake¶
Known Issues¶
1. 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.
Related EWIs¶
- SSC-EWI-0073: Pending Functional Equivalence Review
- SSC-EWI-0056: Create Type Not Supported.
Object Type Definition¶
This is a translation reference to convert the Object Variant of the Oracle Create Type Statements (UDTs) to Snowflake
Note
A translation is supported for Object Type Definitions itself. However, their usages are still a work in progress.
Note
Some parts in the output code are omitted for clarity reasons.
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 mapped to Snowflake’s native CREATE TYPE … AS OBJECT (…) where the attribute list is supported, and constructor calls to the type are translated to OBJECT_CONSTRUCT(<field>, <value>, …) :: <type_name>. The symbol table is used to recover the field names from the original CREATE TYPE, so positional constructor arguments are mapped to the correct field names in upper-case. When the type symbol cannot be resolved (for example, because the CREATE TYPE is not part of the migrated source set), the constructor call is preserved and an SSC-EWI-0073 is emitted for manual review.
For legacy or partially-supported scenarios where the object type cannot be expressed natively, the column in dependent tables may still be migrated to VARIANT and an auxiliary view is added so that downstream SELECTs and views to the original table continue to work.
Sample Source Patterns¶
Object Type constructor calls¶
Object-type constructor calls are translated to OBJECT_CONSTRUCT('FIELD1', value1, 'FIELD2', value2, …) :: <type_name>. The cast to the original UDT name is preserved so column type checks and downstream OBJECT_INSERT / member access continue to work without changes. The transformation applies to constructor calls inside variable initialization, INSERT … VALUES, INSERT … SELECT, UPDATE … SET, and top-level SELECT expressions.
Note
Field names in the generated OBJECT_CONSTRUCT keys are always upper-case (for example 'NAME', 'AGE'). Snowflake object key lookups are case-sensitive, so downstream references using lowercase or mixed-case semi-structured path syntax (for example obj:name) will return NULL. Use the exact upper-case key or quote it consistently throughout the migrated code.
Oracle¶
Snowflake¶
Oracle (constructor in INSERT … VALUES and UPDATE … SET)¶
Snowflake¶
Oracle (constructor when the type symbol is not in the migrated source)¶
Snowflake¶
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¶
Snowflake¶
Simple Type usage¶
Oracle¶
Results¶
| CUSTOMER_TABLE_ID | CUSTOMER_DATA |
|---|---|
| 1 | [1, First Name 1, Last Name 1] |
| 2 | [2, First Name 2, Last Name 2] |
Snowflake¶
Results¶
| 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¶
Snowflake¶
Nested Type Usage¶
Oracle¶
Results¶
| CUSTOMER_ID | CUSTOMER_DATA |
|---|---|
| 1 | [Customer 1, [email@domain.com]] |
| 2 | [Customer 2, [email2@domain.com]] |
Snowflake¶
Results¶
| CUSTOMER_ID | CUST_NAME | CUST_EMAIL |
|---|---|---|
| 1 | Customer 1 | email@domain.com |
| 2 | Customer 2 | email2@domain.com |
Known Issues¶
1. Migrated code output is not the same¶
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 — partial support¶
Constructor calls to object types (for example address_type('123 Main St', …)) and to collection types (VARRAY and nested-table) are now translated automatically when they appear in INSERT … VALUES, INSERT … SELECT, UPDATE … SET, and top-level SELECT expressions, as well as in PL/SQL variable initialization. See Object Type constructor calls above. Other DML shapes that depend on object-type member functions or implicit type promotion may still require manual review.
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.
Related EWIs¶
- SSC-EWI-0056: Create Type Not Supported.
- SSC-EWI-0062: Custom type usage changed to variant.
- SSC-EWI-0073: Pending Functional Equivalence Review.
Subtype Definition¶
This is a translation reference to convert the Subtype Variant of the Oracle Create Type Statements (UDTs) to Snowflake
Danger
Since there are no known workarounds, these definitions are only recognized and no translation is supported for them.
Description¶
Subtypes 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. Unlike Object Types, Subtypes are built as an extension to another existing type.
Regarding subtype definitions, there is still no translation, but there might be a way to reimplement them using Object Type Definitions and then using their respective translation.
Sample Source Patterns¶
Subtypes under an Object Type¶
Oracle¶
Snowflake¶
Known Issues¶
1. 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.
Related EWIs¶
- SSC-EWI-0056: Create Type Not Supported.
- SSC-EWI-OR0007: Create Type Not Supported in Snowflake.