Data types
FQL supports both primitive data types consisting of exactly one value and compound data types comprised of multiple values. The following types are available:
Data type | Description |
---|---|
none | An empty value, also: the absence of a value |
boolean | Boolean truth value with possible values false and true |
integer | Signed whole number |
float | Signed floating point number |
string | UTF-8 encoded text value |
array | Sequence of values, referred to by their positions |
object | Sequence of values, referred to by their names |
binary | Sequence of binary values |
custom | User defined types |
Primitive types
None value
A none value can be used to represent an empty or absent value. It is different from a numerical value of zero (null != 0) and other falsy values (false, zero-length string, empty array or object). It is also known as nil or null in other languages.
Boolean data type
The Boolean data type has two possible values,true
and false
. They represent the two truth values in logic and mathematics.
Numeric literals
Numeric literals can be integers or floating-point numbers. They can optionally be signed with the + or - symbols. A decimal point . is used as separator for the optional fractional part.
String literals
String literals must be enclosed in single or double quotes. If the used quote character is to be used itself within the string literal, it must be escaped using the backslash symbol. A literal backslash also needs to be escaped with a backslash.
Compound types
FQL supports two compound types:- array: A composition of unnamed values, each accessible by their positions.
- object: A composition of named values, each accessible by their names.
- binary: An array of binary values.
Arrays
The first supported compound type is the array type. Arrays are effectively sequences of (unnamed / anonymous) values. Individual array elements can be accessed by their positions. The order of elements in an array is important.An array declaration starts with a left square bracket [
and ends with a right square bracket ]
. The declaration contains zero, one or more expressions, separated from each other with the comma ,
symbol. Whitespace around elements is ignored in the declaration, thus line breaks, tab stops and blanks can be used for formatting.
In the easiest case, an array is empty and thus looks like:
Array elements can be any legal expression values. Nesting of arrays is supported.
Individual array values can later be accessed by their positions using the [] accessor. The position of the accessed element must be a numeric value. Positions start at 0.
Objects
The other supported compound type is the object type. Objects are a composition of zero to many attributes. Each attribute is a name/value pair. Object attributes can be accessed individually by their names. This data type is also known as dictionary, map, associative array and other names.Object declarations start with a left curly bracket {
and end with a right curly bracket }
. An object contains zero to many attribute declarations, separated from each other with the ,
symbol. Whitespace around elements is ignored in the declaration, thus line breaks, tab stops and blanks can be used for formatting.
In the simplest case, an object is empty. Its declaration would then be:
Each attribute in an object is a name/value pair. Name and value of an attribute are separated using the colon :
symbol. The name is always a string, whereas the value can be of any type including sub-objects.
The attribute name is mandatory - there can’t be anonymous values in an object. It can be specified as a quoted or unquoted string:
It must be quoted if it contains whitespace, escape sequences or characters other than ASCII letters (a-z, A-Z), digits (0-9), underscores (_) and dollar signs ($). The first character has to be a letter, underscore or dollar sign.
If a keyword is used as an attribute name then the attribute name must be quoted or escaped by backticks:
Attribute names can be computed using dynamic expressions, too. To disambiguate regular attribute names from attribute name expressions, computed attribute names must be enclosed in square brackets [ … ]
:
There is also shorthand notation for attributes which is handy for returning existing variables easily:
The above is the shorthand equivalent for the generic form:
Any valid expression can be used as an attribute value. That also means nested objects can be used as attribute values:
Individual object attributes can later be accessed by their names using the dot .
accessor:
Attributes can also be accessed using the square bracket []
accessor:
In contrast to the dot accessor, the square brackets allow for expressions:
Binary value
Binary value is an array of bytes that represent binary data like files, images, audio or video.
Custom types
Custom types are the values defined by a user or author of a 3rd party library that extends FQL functionality. The values can represent either specific primitives or compound types. For example, tt could be http cookies, database records, images and etc.In order to define a custom value, it needs to have 2 Go types.
One should implement core.Type
and another core.Value
.
For simplicity, there is a helper function in core
package, that allows to create a type:
core.Value
interface provides a basic set of functionality which allows the FQL runtime to use a custom value.
Reading data
By default, implementingcore.Value
gives the FQL runtime just a basic set of functionality to work with values. This means that a type which implemented only core.Value
interfaces is treated as a primitive data type.
If the underlying data type is compound and there is a need for providing access to underlying data, the type should implement core.Getter
interface:
After that, it will be possible to use .
or []
accessors:
Iterations
In order to use a custom type as source forFOR IN
statement, it must implement core.Iterable
interface:
Clean up
If a custom type needs to do some clean up after a query execution, it needs to implement Go’sio.Closer
interface.