Basic Constructs
The basic building blocks of the OSQL query language are described here.
The Read-Eval-Print-Loop
OSQL statements can be evaluated immediately by SA Engine through its
OSQL Read-Eval-Print-Loop, REPL. When using the SA Engine Console
REPL in Unix/Windows shells, OSQL statements must be terminated by a
semicolon (;). The ; is not needed when evaluating a single
statement to the REPL in your browser or in SA Studio.
Example:
1+2+3
You can enter more than one statement to the REPL by separating them
with a ;.
Examples:
"Hello" + " world";
sin(4) + sqrt(9) * 2;
rand(100)+1
Constants
Constants can be integers, reals, strings, time stamps, booleans, or null. The value of a constant is the constant itself.
Examples: of constant numbers:
123
1.2
2.3E2
-2.4e-21
Examples of constant strings:
"A string"
'A string'
'A string with "'
"A string with \" and '"
The enclosing string separators (' or ") for a string constant
must be the same. If the string separator is " then \ is the
escape character inside the string, replacing the succeeding
character. For example the string 'ab"\' can also be written as
"ab\"\\", and the string a'"b must be written as "a'\"b".
Example of a constant time stamp:
|2025-11-18T12:27:43.985Z|
Boolean constants represent logical values. The constant false
is equivalent to null casted to type Boolean. The only legal
boolean value that can be stored in the database is true.
There are two boolean constants:
true
false
A boolean value is regarded as false if it is null or not in the
database (so called close world assumption).
null
Identifiers
Identifiers represent names of OSQL variables, functions, arrays,
etc. For exampe, MySalary, sin, Integer, x, x1234, or
x1234_b. Notice that OSQL identifiers are not case sensitive;
i.e. they are always internally capitalized.
Comments
A comment enclosed with /* and */can be placed anywhere in an
OSQL statement outside identifiers, constants, strings, or
variables. You can also use SQL's single line comments:
-- This is a comment
Variables
Variables are of two kinds: local variables and session variables.
Local variables are identifiers for data values inside OSQL queries and functions. Variables are not case sensitive and internally capitalized.
Example: the following query uses a local variable named I:
select i
from Number i
where I = 3
Local variables must be declared in from clauses of
queries or
function signatures (see
Functions).
Session variables are prefixed with :, e.g.:x, :my_stream, etc.
They hold only temporary results during interactive
sessions. Session variables cannot be referenced in function bodies
and they are not stored in the database. Their lifespan is the
current session only. Their purpose is to hold temporary values in
scripts and database interactions.
Session variables can be assigned by the variable assignment statement
set.
Examples: these statements assign values to the session variables
:x, :i, and :v:
set :x = sqrt(2) -- set session variable :x3
set :i = round(3.5) -- set session variable :i
set :v = [1,2,3] -- set session variavle :v
These expresson gets the values of the assignments:
:x3 -- get value of :x3
:i -- get value of :i
:V -- get value of :v
You can inspect the type signature of the value to which a variable is
assigned by the function typesig(Object).
Examples:
typesig(:x3)
typesig(:i)
typesig(:v)
Expressions
Expressions are formulas expressed with the OSQL syntax that can be evaluated by the REPL to produce a value. Complex expressions can be built up in terms of other expression. Expressions are basic building blocks in all kinds of OSQL statements.
Examples:
1+2+3
[1,2,3]+1
1+array([[1,2],[3,4]])
Entering simple expressions is the simplest form of OSQL queries.
Tuples
Tuples group several comma separated values using the notation .
Examples:
('a',1);
('a',1.1,2)
A tuple with a single element, a singelton, is the same as the element itself:
('a')
Collections
Collections represent sets of objects. OSQL supports five kinds of collections: bags, vectors, arrays, streams, and key-value associations (records):
- A bag is a set where duplicates are allowed.
- A vector is an ordered sequence of objects of any kind.
- A record is an associative array of key-value pairs.
- An array is a multi-dimensional collection of numbers.
- A stream is a possibly infinite sequence of objects that is continuously extended with new elements at the end.
Collections are constructed by collection constructor expressions.
Examples:
Construct a bag of numbers:
values 1,2,3
Construct a vector of numbers:
[1,2,3]
Construct a vector of vectors of numbers:
[[1,2],[3,4]]
Construct a bag of vectors:
values ['a',1],['b',2],['c',3]
Construct a record (JSON object):
{"id":1,"name":"Kalle","age":32}
Construct an array of integers:
array([1,2,3])
Bags
A common kind of collection is bags, which are unordered sets of objects with duplicates allowed. The value of a query is usually a bag. When a query to an SA Engine REPL returns a bag as result the elements of the bag are printed on separate lines.
Bags can be explicitly created using the values v1,v2,.. notation.
Example:
values 1,2,2,3
A bag containing a single values is equivalent to the single value itself.
Example:
values 1
Tuples in values expressions construct bags of tuples. Nameless
constant tables are represented as a bag of tuples having the same
lengths and types. This bag represents a table with two columns typed
`Charstring and Integer.
values ('a',1),('b',2),('c',3)
typesig(values ('a',1),('b',2),('c',3))
A bag of singeltons represents a nameless table with one column:
values ('a'),('b'),('c')
typesig(values ('a'),('b'),('c'))
The (values v1,v2....) notation can be used to represent bags inside
other expressions.
Example:
select i+1
from Integer i
where i in (values 3,4,2)
Vectors
Vectors are sequences of elements of the same type. Square brackets []
enclose vector elements. Vectors are represented as objects of type Vector.
Example:
[1,2,3]
typesig([1,2,3])
Vector element can be accessed with the notation v[i], where the
indexing i is from 1 and up.
Example:
set :v = [1,2,3]
:v[3]
Section Vectors documents vector functions and queries.
Arrays
Multi-dimensional arrays represent collections of numbers. 1D arrays represent numerical vectors, 2D arrays represent numerical matrices, and higher dimensionality arrays represent tensors.
Arrays are represented as objects of type Array. The difference
between objects of type Array and type Vector is that vectors
represent 1D sequences of objects of any kind, while 1D arrays
very efficiently represent numerical vectors.
Arrays create created with the function array():
Examples:
A numerical vector of integers:
array([1,2,3])
A numerical vector of reals:
array([1.1,2.2,3.3])
A 3x2 matrix of integers with 3 columns and 2 rows:
array([[1,2,3],[3,4,5]])
A 3x2 matrix of reals:
array([[1.1,2.2,3.3],[3,4,5]])
Section Arrays and tensors documents array functions and queries.
Records
Records represent dynamic associations between keys and values. A record is a dynamic and associative array. Other commonly used terms for associative arrays are JSON objects, property lists, key-value pairs, dictionaries, or hash links. OSQL uses JSON notation to construct records.
Example: the following expression assigns the session variable :r
to a record where the key (property) 'Greeting' field has the value
'Hello, I am Tore' and the key 'Email' has the value
'Tore.Andersson@it.uu.se':
set :r= {'Greeting':'Hello, I am Tore','Email':'Tore.Andersson@it.uu.se'};
A field f of a record bound to a variable r can be access with the notation r[f].
Example:
:r['Greeting' ]
The type of records is named Record. The type Json represents
JSON data. It is above both types Record and Vector in the type
hierarchy, since JSON representations include both JSON objects and
vectors.
Streams
Streams represent possibly infinite and growing sequences of elements, such as measurements produced by a sensor. Streams can also be generated (simulated) by functions.
Example: The function heartbeat(p) returns an infinite stream of
number elements produced every p seconds:
heartbeat(0.5)
Streams are documented in section Streams.
