
SQL ARRAY/VARRAY Data Type
This feature was introduced in Teradata Database 14.00.
Description
ARRAY is a type of user-defined data type (UDT) that can represent up to five dimensions, each with a user-defined maximum number of individual elements. All of the elements of an ARRAY must be of the same data type.
The one-dimensional ARRAY type is largely compatible with the VARRAY type provided by Oracle Database. You can create a one-dimensional ARRAY data type using the Teradata database ARRAY keyword, or by using the VARRAY keyword and syntax for Oracle compatibility.
Benefits
- The ARRAY/VARRAY data types permit many values of the same data type to be stored sequentially or in a matrix-like format, extending the number of values of the same data type that can be stored in a row.
- The values of an ARRAY/VARRAY column are stored within the row itself, not in a Large Object (LOB). Although this limits the size of ARRAY data types to 64K bytes, it provides major performance benefits because you can access and modify individual elements without having to create and write a new LOB each time.
- Teradata Database provides many built-in functions and operators, and a constructor expression, to support the ARRAY and VARRAY data types. The elements of an ARRAY/VARRAY data type can be accessed individually or by using one of the built-in functions provided to support these data types as a sequential subset. Because these built in functions are provided as Teradata Database embedded services, the performance is much better than if you were to create your own UDFs for array manipulations.
Considerations
- You can update only one element of the array at a time to a unique value, or all elements of the array to the same value. You cannot update several elements to different unique values in a single operation.
- You cannot specify an ARRAY column in the ORDER BY, GROUP BY, or HAVING clauses of a SELECT request.
- You cannot specify an ARRAY column in an index.
- Casting functionality is provided to cast an ARRAY data type to a VARCHAR formatted string, and to cast a VARCHAR formatted string to an ARRAY data type. You can create your own user-defined function (UDF) to perform additional casting functionality.
- The one-dimensional ARRAY data type is partially compliant with the ANSI SQL:2008 standard. There is no current ANSI SQL:2008 standard for multidimensional ARRAY data types.
- ARRAY data types are stored in the SYSUDTLIB database together with their respective automatically generated constructors. In order to create an ARRAY data type, a user must have appropriate UDT access rights on the SYSUDTLIB database.
Scenario: Managing a Clothing Inventory
This scenario creates a simple three-dimensional array to represent aspects of a clothing vendor inventory. A table for Clothing has rows for different types of clothing. The inventory information for all the different styles, sizes, and colors of each clothing type is stored in a single field, the array type column for the row.
The scenario demonstrates how to:
- Create the ARRAY UDT
- Create a table with a column defined to contain ARRAY values
- Insert rows containing ARRAY data into the table
- Display ARRAY data from the table
- Update a value stored in an ARRAY
- Use an ARRAY system function to find the inventory of all colors of a given style and size of one type of clothing
For More Information About the ARRAY and VARRAY Data Types
For more information about the ARRAY and VARRAY data types, and about the SQL used in these examples see:
Document | Description |
---|---|
SQL Data Definition Language - Detailed Topics, B035-1184 | Provides information on creating ARRAY and VARRAY objects, and discusses creating and using arrays. |
SQL Data Definition Language - Syntax and Examples, B035-1144 | Shows SQL syntax for creating and altering UDT objects. |
SQL Data Types and Literals, B035-1143 | Describes the ARRAY and VARRAY data types. |
SQL Functions, Operators, Expressions, and Predicates, B035-1145 | Describes functions that operate on ARRAY and VARRAY data. |
SQL External Routine Programming, B035-1147 | Describes how to define C and C++ functions that use ARRAY and VARRAY data types. |
Orange Book: Working with User Defined Types: Creation, Usage and Potential Pitfalls, Document #: 541-0005614 | Detailed discussion and application examples of using UDTs. |
Example: Define a Three-Dimensional Array
The following CREATE TYPE statement defines an ARRAY data type as a distinct UDT:
CREATE TYPE clothing_inv_ARY AS INTEGER ARRAY [2][4][3];
Note the following:
- This array consists of three dimensions of sizes 2, 4, and 3, which represent styles, sizes, and colors of clothing items, respectively.
- An ARRAY must contain data of a single data type. In this case the array contains INTEGER data, the inventory quantifies.
- The data stored in an array should be of the same kind. For example, our array has three dimensions, representing style, size, and color, but the values stored in the individual array elements will all be inventory quantities for the different combinations of style, size, and color. Mixing different kinds of data in the array, such as values for style, size, and color is not the recommended use of arrays.
- The maximum number of values the array can hold is the product of the sizes of all dimensions. In this example, our clothing_inv_ARY array can hold up to (2x4x3)=24 values.
- To identify and address any single piece of data (element) of the array, you specify its position within each dimension. Because this is a three-dimensional array, every element is specified by a three number address, each address corresponds to a specific combination of style, size, and color for the clothing item. The first number can be 1 or 2 (two possible styles), the second 1 through 4 (four possible sizes), and the third 1 through 3 (three possible colors). The elements of the array would have addresses like [1][1][1], [1][1][2],[1][1][3],[1][2][1],[1][2][2],[1][2][3],[1][3][1], [1][3][2] and so forth through [2][4][3].
CREATE TYPE clothing_inv_ARY AS INTEGER ARRAY [1:2][1:4][1:3];The parameters with [n:m] represent the minimum and maximum bounds of each dimension which are used to identify and address the individual array elements. This two-number specification allows you to specify negative numbers to be used when addressing a particular array element. For example, we could create an analogous 24-element array using this syntax:
CREATE TYPE clothing_inv_ARY AS INTEGER ARRAY [-1:0][-4:-1][1:3];
The individual dimensions would have the same sizes as our array above, however to address the elements you would use the following sequence of locations: [-1][-4][1], [-1][-4][2],[-1][-4][3],[-1][-3][1],[-1][-3][2],[-1][-3][3], and so forth through [0][-1][3].
Example: Create a Table Referencing an Array UDT
The following example creates a table that includes an array column. The Clothing_Inventory column is defined to be of type clothing_inv_ARY, our ARRAY UDT. For each row, which represents a type of clothing, the Clothing_Inventory column stores the entire inventory for all styles, sizes, and colors of that clothing type.
CREATE TABLE Clothing ( Clothing_Type VARCHAR(10), Clothing_Inventory clothing_inv_ARY);
Example: Insert to a Table That has an ARRAY Column
The following example demonstrates how to add array data to a table that has a column defined to hold ARRAY type data.
Assume the table was defined to have two columns: Clothing_Type and Clothing_Inventory, where Clothing_Inventory is an ARRAY UDT that defines a three-dimensional array to hold inventory quantities of the clothing items. The array addresses are indexed by the style, size, and color of the clothing type represented by each row. The following example populates the table, and demonstrates inserting data into the ARRAY values:
INSERT INTO Clothing VALUES ('T-Shirt', NEW clothing_inv_ARY(20, 8, 4) ); INSERT INTO Clothing VALUES ('Sweatpants', NEW clothing_inv_ARY( 11, 2, 23, 0, 10, 25, 130, 62, 17, 77, 142, 22, 81, 0, 215, 30, 27, 31, 12, 23, 0, 4, 55, 11) );
The data in an ARRAY must all be of the same data type. In this example, the data is all INTEGERs. Each ARRAY has 24 elements (2x4x3). The two rows inserted into the table each represent a different type of clothing.
The three dimensions of the array correspond to:
- Styles:
- For shirts: long sleeve or short sleeve, represented by addresses 1 and 2, respectively, in the first dimension
- For sweatpants: elastic waist or drawstring waist, represented by addresses 1 and 2, respectively, in the first dimension
- Sizes: small, medium, large, or extra large, represented by addresses 1, 2, 3, and 4, respectively, in the second dimension for both shirts and sweatpants
- Colors: blue, gray, or white, represented by addresses 1, 2, and 3, respectively, in the third dimension for both shirts and sweatpants
The assignment of array dimension address values to specific dimension values maps the array and allows us to associate a specific three-number array address with a specific style, size, and color of the clothing item represented by each row of the table.
Data is added to the array in row-major order. Row-major order means that the first dimension (leftmost in the array specification) is the most major dimension, and as we move toward the last dimension, they become less and less major. Our array values in this example would fill the clothing_inv_ARY array addresses for sweatpants in this way:
Array Address Quantity Stored |Array address Quantity Stored ===============================|============================== [1][1][1] 11 |[1][3][1] 130 [1][1][2] 2 |[1][3][2] 62 [1][1][3] 23 |[1][3][3] 17 [1][2][1] 0 |[1][4][1] 77 [1][2][2] 10 |[1][4][2] 142 [1][2][3] 25 |[1][4][3] 22 ... and so forth.
Although the array can hold quantities for up to 24 different kinds of each type of clothing, each a unique combination of style, size, and color, neither the shirts array nor the sweatpants arrays are fully populated.
Example: Display Array Contents
This example displays the entire contents of the array for each type of clothing.
SELECT clothing_type, clothing_inventory FROM clothing;
Result:
Clothing_Type Clothing_inventory ------------- ------------------------------------------------------------- Sweatpants (11,2,23,0,10,25,130,62,17,77,142,22,81,0,215,30,27,31,12,23, T-Shirt (20,8,4)
To display the inventory quantity for a particular clothing item, use the array address that corresponds to the combination of style, size, and color of the item of interest. For example, the following query returns the inventory quantity of sweatpants having a drawstring waist (address 2 in the first dimension), medium size (address 2 in the second dimension), and white color (address 3 in the third dimension).
SELECT clothing_inventory [2][2][3] FROM clothing WHERE clothing_type = 'Sweatpants';
Result:
Clothing_inventory[2][2][3] --------------------------- 31
Example: Update the Quantity for One Item in the Array
Here is our array showing the corresponding array addresses for every value:
The following queries update the quantity of drawstring waist, medium, white sweatpants, then return the new value:
UPDATE clothing SET clothing_inventory [2][2][3] = 999 WHERE clothing_type = 'Sweatpants';
To verify the change, we can display the new contents of the array at th [2][2][3] address:
SELECT clothing_inventory [2][2][3] FROM clothing WHERE clothing_type = 'Sweatpants';
Result:
Clothing_inventory[2][2][3] --------------------------- 999
Example: Display the Sum of a Subset of Array Contents Using ARRAY_SUM
The ARRAY data type feature includes several embedded service system functions for manipulating arrays. This example uses the ARRAY_SUM function returns the sum of values in the array for a given subset of array addresses.
To query the inventory for elastic waist, small size sweatpants, summing the quantities for all colors, you would use the following query, which specifies the addresses for elastic and small, and the minimum and maximum bounds of the color dimension:
SELECT ARRAY_SUM(clothing_inventory, NEW arrayVec(1,1,1), NEW arrayVec(1,1,3)) FROM clothing WHERE clothing_type = 'Sweatpants';
Result:
ARRAY_SUM(clothing_inventory, NEW ARRAYVEC(1, 1, 1), NEW ARR ------------------------------------------------------------ 36