Skip to content

Full Grammar for TQL and TQLFlow

Legend:

Name Description
< > Item within brackets is required
[ ] Item within the brackets is optional
? 0 or 1
+ 1 or many
* 0 or many; except within brackets it is a literal
attribute The name of an attribute from the dictionary; which can be aliased. t.attribute AS attr
literal Any literal value, must be aliased. 'string literal' AS attr
select-function Any SELECT function, must be aliased
aggregator-function Any Aggregator function, must be aliased
dictionary name The name of the dictionary (in the metadata)
alias Any identifier type name for referring to another attribute or function
predicate Reference next section below
integer A positive number

TQL

SELECT <attribute, literal, select-function, predicate, aggregator-function, root-selection, re-root ALL, *>+
FROM <dictionary name> [AS alias]?
[<JOIN | INNER JOIN> [ONCE]? <dictionary name> [AS alias]? ON <condition>]*
[LEFT OUTER JOIN [ONCE]? <dictionary name> [AS alias]? ON <condition>]*
[WHERE <condition>]?
[GROUP BY <identifier | ALL | *>*]?
[ORDER BY <identifier [ASC | DESC]+>*]:
[SKIP <integer>]?
[LIMIT <integer>]?

TQLFlow coming soon…

TQLFlow

TQLFlow and TQL share a lot of similar grammar between clauses, but TQLFlow does allow for more flexibility when creating a query.

[
    (SELECT <attribute, literal, select-function, predicate, root-selection, re-root, ALL, *>) |
    (SUBFLOW {<tqlflow-clases> } [AS alias]?) |
    (JOIN | INNER JOIN> [ONCE]? <dictionary name> [AS alias]? ON <condition>) |
    (LEFT OUTER JOIN [ONCE]? <dictionary name> [AS alias]? ON <condition>) |
    (WHERE <condition>) |
    (GROUP BY <identifier | ALL | *> [COMBINE <aggegator-function>*]?) |
    (ORDER  BY <identifier [ASC | DESC]+>*) |
    (SKIP <integer>) |
    (LIMIT <integer>)
]*
[FINALIZE function(<inputRecord>) {<javascript>}]?

Re-root

If you have a record that has a document, you can move all attributes inside the document into the root of the record using the re-root operator. To use it, simply append .* to the document’s name inside a SELECT statement.

So if you have the following record:

{
    "doc": {
        "k1": "v1",
        "k2": "v2"
    },
    "k": "v"
}

You can do

SELECT doc.*

To get back

{
    "k1": "v1",
    "k2": "v2"
}

Note that you cannot alias a re-root selection.

You can also use re-roots along with SELECT *, so for the above record doing

SELECT *, doc.*

Would return

{
    {
    "doc": {
        "k1": "v1",
        "k2": "v2"
    },
    "k": "v",
    "k1": "v1",
    "k2": "v2"
}

Root Selections

When using SELECT, you can move the contents of the record into an attribute by doing * AS <alias>. For example, for the record:

{
    "doc": {
        "k1": "v1",
        "k2": "v2"
    },
    "k": "v"
}

Doing

SELECT * AS root

Would return

{
    "root": {
        "doc": {
            "k1": "v1",
            "k2": "v2"
        },
        "k": "v"
    }
}

You can use it with SELECT * if you want it to copy the root instead:

SELECT *, * AS root

Would return

{
    "root": {
        "doc": {
            "k1": "v1",
            "k2": "v2"
        },
        "k": "v"
    },
    "doc": {
        "k1": "v1",
        "k2": "v2"
    },
    "k": "v"
}

Predicate selections

You can select predicate expressions as boolean values in a SELECT clause, though they must be inside parenthesis. For example, for the record

{
    "amount": 30
}

You can do

SELECT (amount GT 20) AS has_enough

Which would return

{
    "has_enough": true
}