Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Named Types

A named type provides a means to bind a symbolic name to a type and conforms to the named type in the super-structured data model. The named type syntax follows that of SUP format, i.e., a named type has the form

(<name>=<type>)

where <name> is an identifier or string and <type> is any type.

Named types may be defined in four ways:

  • with a type declaration,
  • with a cast,
  • with a definition inside of another type, or
  • by the input data itself.

For example, this expression

80::(port=uint16)

casts the integer 80 to a named type called port whose type is uint16.

Alternatively, named types can be declared with a type statement, e.g.,

type port = int16
values 80::port

produces the value 80::(port=uint16) as above.

Type name definitions can be embedded in another type, e.g.,

type socket = {addr:ip,port:(port=uint16)}

defines a named type socket that is a record with field addr of type ip and field port of type port, where type port is a named type for type uint16 .

Named types may also be defined by the input data itself, as super-structured data is comprehensively self describing. When named types are defined in the input data, there is no need to declare their type in a query. In this case, a SuperSQL expression may refer to the type by the name that simply appears to the runtime as a side effect of operating upon the data.

When the same name is bound to different types, a reference to that name is undefined except for the definitions within a single nested value, in which case, the most recent binding in depth-first order is used to resolve a reference to a type name.

Examples


Filter on a type name defined in the input data

# spq
where typeof(this)==<foo>
# input
1::=foo
2::=bar
3::=foo
# expected output
1::=foo
3::=foo

Emit a type name defined in the input data

# spq
values <foo>
# input
1::=foo
# expected output
<foo=int64>

Emit a missing value for an unknown type name

# spq
values <foo>
# input
1
# expected output
error("missing")

Conflicting named types appear as distinct type values

# spq
count() by typeof(this) | sort this
# input
1::=foo
2::=bar
"hello"::=foo
3::=foo
# expected output
{typeof:<bar=int64>,count:1::uint64}
{typeof:<foo=int64>,count:2::uint64}
{typeof:<foo=string>,count:1::uint64}