LQL reference
The catalog of the Link Query Language. It lists every form a query can take and where each is allowed, without explaining the concepts: those are in the tutorial and the advanced page.
Syntax
NAME(FLAGS)?:PATH
NAMEis the query alias, an identifier ([_a-zA-Z][a-zA-Z_0-9]*). Aliases are distinct within a link, acrossfromandto. A leading$, as in$call, marks names the driver adds; rules and checks reject it in aliases they are given.FLAGSis an optional comma-separated subset ofoptional,callandtemplate.PATHis a list of/-separated segments, relative to the link's host workflow. A leading/is not allowed, and.is allowed only as the first segment.
Whitespace is allowed around every token.
A bare identifier in a segment is shorthand for first(identifier). A
query that ends in a script io names the io in its last segment; a query
that targets a node ends in a node segment.
The host workflow, the one that declares the link, is addressed with an empty path. These forms are equivalent:
| Form | Target |
|---|---|
NAME | the host workflow |
NAME: | the host workflow |
NAME:. | the host workflow |
NAME:./ | the host workflow |
NAME:./a/b | the same as NAME:a/b |
Glossary
- Path:
/-separated segments resolved relative to the link's host workflow. - Segment: one selector, bare id or tag selector inside a path.
- Base: the link's anchor query (the
basefield), evaluated beforefromandto. - Link instance: one copy of a link, produced for each match of an
expandselector in the base. - Reference selector: a selector that anchors to a named base through
@ref(same,before,afterand their variants). - Tag: a string label on a script or workflow in the configuration, matched with the
#prefix.
Selectors
| Selector | Kind | Where | Result | Description |
|---|---|---|---|---|
first | plain | any path | one node | First direct descendant whose id is in the OR-list. A bare id is this selector. e.g. first(script1) |
last | plain | any path | one node | Last direct descendant whose id is in the OR-list. e.g. last(script1|script2) |
all | plain | non-base | many nodes | Every direct descendant whose id is in the OR-list; one query, many values. e.g. all(metric) |
expand | plain | base only | one instance per node | Like all, but every match produces a separate link instance.e.g. expand(workflow1|workflow2) |
same | reference | non-base | one node | The node @ref matched at this segment. The id-list is optional and narrows the match.e.g. same(@base) or same(@base, script1) |
before | reference | non-base | one node | First preceding sibling whose id matches, scanning backward from the base. e.g. before(@base, prepData) |
before* | reference | non-base | many nodes | Every preceding sibling whose id matches. e.g. before*(@base, prepData) |
before+ | reference | non-base | one node | The immediately preceding sibling, only when its id matches. e.g. before+(@base, prepData) |
after | reference | non-base | one node | First following sibling whose id matches, scanning forward from the base. e.g. after(@base, nextStep) |
after* | reference | non-base | many nodes | Every following sibling whose id matches. e.g. after*(@base, nextStep) |
after+ | reference | non-base | one node | The immediately following sibling, only when its id matches. e.g. after+(@base, nextStep) |
#SELECTOR | tag variant | any path | as the selector | The same matching on tags, with AND across tags, descending through nesting. e.g. #all(metric&primary) |
outputs(nqName), inputs(nqName) | io wildcard | last segment of from / to, with (template) | one query per io | Every output or input the script nqName declares, minus an optional |-list of exclusions.e.g. inputs(Pkg:Script, debug|verbose), inputs(Pkg:Solver, preset|$nonscalar|$linked) |
- Reference selectors take the base query name as their first argument,
prefixed with
@. Plain selectors must not take one. - Every selector but
samerequires an id or tag list. - Id lists use OR (
|), tag lists use AND (&). - Tag variants exist for
first,last,all,expand,same,before,before*,afterandafter*. There is no#before+or#after+. - Stop ids are a third argument of
beforeandafterin every variant; see Modifiers and stop ids.
Flags
| Flag | Meaning | Allowed in |
|---|---|---|
optional | A query with no match does not prevent the link from being created; the alias reads as absent. | Any query. |
call | Match the node (the FuncCall) itself rather than a script io. In funccall actions it is required for inputs read as DG.FuncCall and for the setFuncCall output. In every other link type it must be combined with optional, and the controller exposes only a hasCall(name) presence check. | from of any link; to of funccall actions only. Not in base, showWhen, hideWhen or rule queries, not with template. Accepted in not without effect. |
template | Expand the last segment into one query per io: a |-list of io names, or an outputs() / inputs() wildcard. The alias is the prefix plus the io name; a _ prefix gives the io names alone. | from of data, validator, meta, node meta and pipeline validator links; to of data, validator and meta links; from and to of rules. |
Where a query appears
| Field | Ends in | Flags |
|---|---|---|
from of data, validator, meta, node meta and pipeline validator links | a script io, or a node with call | optional, call with optional, template |
to of data, validator and meta links | a script io | optional, template |
to of node meta and pipeline validator links | a node, or empty for the host workflow | optional |
base | a node; first, last, expand and their tag variants only | none |
not | a node | optional; call accepted without effect |
actions of validators | a node, any selector | optional |
showWhen, hideWhen of actions | a node; no io wildcards | optional |
from / to of funccall actions | a node with call, or a script io | optional, call |
from / to of rules | a script io | optional, template |
io, check.table and vars values of checks | a script io | none; written without an alias |
Two rules hold across the table. base is evaluated first and must
resolve on its own, so it takes no reference selector, and every other
field may anchor to it. And except in base and actions, the last
segment is a bare id (or first(...)), a tag selector, or an io
wildcard: it names the io or the node, and the selectors that pick among
siblings go before it.
Modifiers and stop ids
The * and + suffixes on before and after are part of the selector
name, not separate operators. Against the sequence
[prep1, prep2, prep3, base, next1, next2, next3] with an id list that
covers every prep and next:
| Selector | Captures |
|---|---|
before | prep3 |
before* | prep1, prep2, prep3 |
before+ | prep3, only when the adjacent sibling is in the list; otherwise no match |
after | next1 |
after* | next1, next2, next3 |
after+ | next1, same rule as before+ |
before and after accept an optional third argument, a |-list of
stop ids. The scan halts as soon as a node whose id is in the list is
met, even if a matching id lies further along:
before(@base, prepData, resetStep)
matches the nearest preceding prepData, but gives up when a
resetStep comes first.
Wildcard exclusions
The second argument of inputs() and outputs() is a |-list of
exclusions. Each entry is an io name or an exclusion kind:
| Exclusion | Drops | Applied |
|---|---|---|
| an io name | that io | once, when the configuration is processed |
$nonscalar | every io that is not a number, string, boolean or date, such as dataframes, columns and lists | once, when the configuration is processed |
$linked | every io that another data link writes | after matching, on every tree change |
$linked follows these rules:
- Only data links take an io away: plain data links and the data part of rules. Validators, meta links and checks writing the same io do not.
- Outputs of other
$linkedwildcards do not count, so two links with$linkedover the same ios both keep them. - Every entry the wildcard expands to is
optional, so a dropped io never prevents the link from being created. The handler sees only the ios that are left, throughgetMatchedOutputs. - The exclusion follows the tree. A step added with a data link that writes one of the ios drops it, and removing that step gives it back.
- It acts in
toonly. Infrom,$linkedjust makes the entries optional.
Aliases
Every query has an alias, unique within the link across from and to.
A template query produces one alias per io:
| Query | Aliases |
|---|---|
in:clean/table | in |
in_(template):clean/table|stats | in_table, in_stats |
_(template):clean/table|stats | table, stats |
_(template):fit/inputs(Pkg:Fit) | one per input of Pkg:Fit, named after it |
Two template queries on the same side of a link need distinct
prefixes. Anonymous _ templates are the exception: their slots are
numbered.
The driver adds its own names to the links it builds from rules, checks
and annotations. All of them but value start with $:
| Name | Added by | Holds |
|---|---|---|
value | checks and annotation validators | The checked io, as in platform validator expressions. |
$target | checks and annotation validators | The checked io, as the output that receives the result. |
$table | column checks | The dataframe io named in table. |
$call | rules with validators or choices sources, checks and annotation validators that call platform validators | The step's FuncCall, as an optional call input. |
$verdicts | the validators option of checks and annotations | The verdicts of the named validator functions. |
$all.<alias> | rule expressions | Every matched value of a from query. |
$nonscalar, $linked | io wildcards | Exclusion kinds, not aliases. |
Rules and checks reject a leading $ in aliases, vars names and
source names.
Reading matches
What a handler gets for an alias depends on how many nodes the query matched:
| Query | getAll | getFirst |
|---|---|---|
One-node selectors: a bare id, first, last, same, before, after, before+ and after+ | An array with one value. | The value. |
Many-node selectors: all, before*, after* and their tag variants | One value per matched node, in the order of getMatchedPositions. | The value of the first node. |
An optional query with no match | Throws. | Throws. |
A call query | Not readable. Use hasCall. | Not readable. |
A template query | Read each expanded alias on its own, or pair them with getInputTemplates. |
An unmatched optional alias is missing from
getMatchedInputs and
getMatchedOutputs. Check those sets
before reading or writing an optional alias.
Gotchas
expandis valid only insidebase. Anywhere else it is a parse-time error.allis not allowed insidebase. Useexpandto give every match its own instance.- Reference selectors are not allowed inside
base, which must resolve without depending on another query. - Tag lists combine with AND (
&), id lists with OR (|). - Tag matches descend through nesting and never travel upward past the link's host workflow.
#before+and#after+do not exist; tag variants ofbeforeandaftersupport*only.- Absolute paths (leading
/) and a mid-path.are forbidden. - Reference selectors require a leading
@refargument and plain selectors must not take one. Mixing is a parse-time error. - Outside
funccallactions,callrequiresoptional; the matched FuncCall is not exposed to handlers, onlyhasCall(name).callon atooutsidefunccallactions,callinsidebase, andcallwithtemplateare rejected at parse time. - An io wildcard (
outputs(),inputs()) requires thetemplateflag and may only be the last segment. - Rule queries reject
call; a check'sio,tableandvarsqueries carry no alias.