Skip to content

Other Data Types


The type Any covers all possible values, and can be used as a wildcard to match any type.

Type Relation: Any(x)

Any(x) will be true for any x.


// read query
def R = (1, 3) ; (1, "foo")
ic any_ic {subset(R, (Int, Any) )}
def output = R



The Rel language is based on two-valued logic (opens in a new tab) where the constants true and false are relations and not data values.

The relation true is represented by an empty tuple (), which is a relation of arity 0 and cardinality 1. The relation false is the empty relation {}, which has arity 0 and cardinality 0.

Rel does include, however, a separate Boolean data type that is useful for importing data that explicitly depends on Boolean values β€” in particular, JSON data. See the example below.


There are two constructors, one for each Boolean value: boolean_true and boolean_false:

// read query
def output = {boolean_false; boolean_true}

Type Relation: Boolean(x)

Boolean(x) tests whether x has the data type Boolean.

// read query
def R = {(1, boolean_true); (2, true); (3, boolean_false); (4, false)}
def output(x, y) = R(x, y) and Boolean(y)

Noteworthy Operations


In the following example, the JSON true and false values are mapped to the Rel data type Boolean:

// read query
def joe = parse_json["""
      { "address": null, "name" : "JJ" , "person" : true , "company" : false }
ic { Boolean(joe:person) }
ic { boolean_and[joe:person, boolean_not[joe:company]] = boolean_true }
ic { joe:person = boolean_true }
def output = joe

Here is an example showing how and, or, and not operations over the data types are written:

// read query
def a = boolean_true
def b = boolean_false
def output:not_and = boolean_not[boolean_and[a, b]]
def output:or = boolean_or[a, b]

Note that boolean_and, boolean_or, and boolean_not are distinctly different from the Rel key words and, or, and not. The former operate only on boolean data, whereas the latter are part of logic expressions like conjunction, disjunction, and negation.



FilePos types are created when importing CSV files. They are used as keys when joining columns from the same row. Currently, a user can’t directly create this data type themselves.

Type Relation: FilePos(x)

FilePos(x) tests whether x has the data type FilePos:

// read query
def config:data="""
def csv = load_csv[config]
def output(p) = csv(_, p, _)
def csv_ic {
    subset(csv, (RelName, FilePos, String))


// read query
def config:data="""
def output = table[load_csv[config]]

See CSV Import for more details.



Generally, missing or null data are simply represented in Rel by not having these facts in a relation.

Missing is a singleton type, containing only one value, missing.

It is used for data that require an explicit representation of null data. For instance, JSON data require an explicit representation for missing data (see example below). Data representation that is not fully normalized, such as Third Normal Form (opens in a new tab) (3NF), also requires an explicit representation of missing data.

For data that are stored in the fully normalized Graph Normal Form (GNF), missing data points are represented by not stating the missing fact in the relation. GNF is the recommended way to model data and makes best use of the RKGS query optimizer.


A Missing data value is created by writing missing:

// read query
def output = missing

Type Relation: Missing(x)

Missing(x) tests whether x has the data type Missing:

// read query
def R = {("+1", 'πŸ‘'); ("+10", missing); ("+100", 'πŸ’―')}
def output(x, y) = R(x, y) and not Missing(y)


Parsing JSON data that contain explicit null data:

// read query
def json = parse_json[""" { "address": null, "name" : "JJ" } """]
ic missing_ic { Missing(json:address) }
def output = json

Next: Keywords and Symbols

Was this doc helpful?