Data Type Hierarchy

The Oracle NoSQL Database data model also defines a subtype-supertype relationship among the types presented above. The relationship can be expressed as an is_subtype(T, S) function that returns true if type T is a subtype of type S and false otherwise. is_subtype(T, S) returns true in the following cases:

  • T and S are the same type. So, every type is a subtype of itself. We say that a type T is a proper subtype of another type S if T is a subtype of S and T is not equal to S.
  • S is the ANY type. So, every type is a subtype of ANY.
  • S is the ANYATOMIC type and T is an atomic type.
  • S is ANYJSONATOMIC and T is one of the numeric types or the STRING type, or the BOOLEAN type.
  • S is NUMBER and T is one of the other numeric types.
  • S is LONG and T is INTEGER.
  • S is DOUBLE and T is FLOAT.
  • S IS STRING and T is UUID.
  • S is TIMESTAMP(p2), T is TIMESTAMP(p1) and p1 <= p2.
  • S is BINARY and T is FIXED_BINARY.
  • S is ARRAY(T2), T is ARRAY(T1) and T1 is a subtype of T2.
  • S is MAP(T2), T is MAP(T1) and T1 is a subtype of T2.
  • S and T are both record types and (a) both types contain the same field names and in the same order, (b) for each field, its type in T is a subtype of its type in S, and (c) if the field is nullable in T, it is also nullable in S.
  • S is JSON and T is (a) an array whose element type is a subtype of JSON, or (b) a map whose value type is a subtype of JSON, or (c) ANYJSONATOMIC or any of its subtypes.

Note:

The is_subtype relationship is transitive, that is, if type A is a subtype of type B and B is a subtype of C, then A is a subtype of C.
The is_subtype relationship is important because the usual subtype-substitution rule is supported by SQL for Oracle NoSQL Database: if an operation expects input items of type T then it can also operate on items of type S, where S is a subtype of T. However, there are two exceptions to this rule:
  1. DOUBLE and FLOAT are subtypes of NUMBER. However, DOUBLE and FLOAT include three special values in their domain:
    1. NaN (not a number)
    2. Positive infinity
    3. Negative infinity

    These three values are not in the domain of NUMBER. You can provide DOUBLE/FLOAT types to NUMBER type as long as these are not one of the three special values; otherwise, an error will be raised.

  2. Items whose type is a proper subtype of ARRAY (JSON) or MAP (JSON) cannot be used as:
    1. RECORD/MAP field values if the field type is JSON, ARRAY (JSON) or MAP (JSON)
    2. Elements of ARRAY whose element type is JSON, ARRAY (JSON) or MAP (JSON)

    This is in order to disallow strongly typed data to be inserted into JSON data.

    For example, consider a JSON document M, i.e., a MAP value whose associated type is a MAP (JSON). M may contain an ARRAY value A that contains only INTEGERs. However, the type associated with A cannot be ARRAY (INTEGER), it must be ARRAY (JSON). If A had type ARRAY (INTEGER), the user would not be able to add any non-INTEGER values to A, i.e., the user would not be able to update the JSON document in a way that would still keep it a JSON document.