PolarDB-O supports user-defined PL/SQL subtypes and subtype aliases. A subtype is a data type with an optional set of constraints that restrict the values that can be stored in a column of that type. The rules that apply to the type on which the subtype is based are still enforced. However, you can use additional constraints to limit the precision or scale of values that match the type.

You can define a subtype in the declaration of a PL function, stored procedure, anonymous block, or package. Syntax:
SUBTYPE subtype_name IS type_name[(constraint)] [NOT NULL] 
Where constraint is:
{precision [, scale]} | length
Where:
  • subtype_name specifies the name of the subtype.
  • type_name specifies the name of the original type on which the subtype is based.
    Note Valid values of type_name are as follows:
    • The name of a type supported by PolarDB-O.
    • The name of a composite type.
    • A column anchored by a %TYPE operator.
    • The name of another subtype.
You can include the constraint clause to define restrictions for types that support precision or scale.
  • precision specifies the total number of digits permitted in a value of the subtype.
  • scale specifies the number of fractional digits permitted in a value of the subtype.
  • length specifies the total length permitted in a value of CHARACTER, VARCHAR, or TEXT base types.
You can include the NOT NULL clause to specify that NULL values may not be stored in a column of the specified subtype.
Note A subtype that is based on a column will inherit the column size constraints, but the subtype will not inherit NOT NULL or CHECK constraints.

Unconstrained subtypes

To create an unconstrained subtype, use the SUBTYPE command to specify the new subtype name and the name of the type on which the subtype is based. For example, the following command creates a subtype named address that has all the attributes of the CHAR type:
SUBTYPE address IS CHAR;
You can also create a subtype (constrained or unconstrained) that is a subtype of another subtype:
SUBTYPE cust_address IS address NOT NULL;

This command creates a subtype named cust_address that shares all the attributes of the address subtype. You can include the NOT NULL clause to specify that a value of the cust_address may not be NULL.

Constrained subtypes

You can include a length value when creating a subtype that is based on a character type to define the maximum length of the subtype. Example:
SUBTYPE acct_name IS VARCHAR (15);

This example creates a subtype named acct_name that is based on a VARCHAR data type, but is limited to 15 characters in length.

You can include values for precision to specify the maximum number of digits in a value of the subtype. You can also include scale to specify the number of digits to the right of the decimal point when constraining a numeric base type. Example:
SUBTYPE acct_balance IS NUMBER (5, 2);

This example creates a subtype named acct_balance that shares all the attributes of a NUMBER type. The subtype cannot exceed 3 digits to the left of the decimal point and 2 digits to the right of the decimal.

An argument declaration in a function or procedure header is a formal argument. The value passed to a function or stored procedure is an actual argument. When calling a function or stored procedure, the caller provides zero or more actual arguments. Each actual argument is assigned to a formal argument that holds the value within the body of the function or stored procedure.

If a formal argument is declared as a constrained subtype, then:
  • PolarDB-O does not enforce subtype constraints when assigning an actual argument to a formal argument in a function call.
  • PolarDB-O enforces subtype constraints when assigning an actual argument to a formal argument in a call of a stored procedure.

Use the %TYPE operator

You can use the %TYPE notation to declare a subtype anchored to a column. Example:
SUBTYPE emp_type IS emp.empno%TYPE

This command creates a subtype named emp_type with a base type that matches the type of the empno column in the emp table. A subtype that is based on a column will share the column size constraints. The NOT NULL and CHECK constraints are not inherited.

Subtype conversion

Unconstrained subtypes are aliases for the type on which they are based. Any variable of type or subtype (unconstrained) is interchangeable with a variable of the base type without conversion, and vice versa.

A variable of a constrained subtype can be interchanged with a variable of the base type without conversion. However, a variable of the base type can only be interchanged with a constrained subtype if it complies with the constraints of the subtype. A variable of a constrained subtype can be implicitly converted to another subtype. This happens if the variable is based on the same subtype, and the constraint values are within the values of the subtype to which it is being converted.