Skip to main content

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
  • NAME is the query alias, an identifier ([_a-zA-Z][a-zA-Z_0-9]*). Aliases are distinct within a link, across from and to. A leading $, as in $call, marks names the driver adds; rules and checks reject it in aliases they are given.
  • FLAGS is an optional comma-separated subset of optional, call and template.
  • PATH is 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:

FormTarget
NAMEthe host workflow
NAME:the host workflow
NAME:.the host workflow
NAME:./the host workflow
NAME:./a/bthe 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 base field), evaluated before from and to.
  • Link instance: one copy of a link, produced for each match of an expand selector in the base.
  • Reference selector: a selector that anchors to a named base through @ref (same, before, after and their variants).
  • Tag: a string label on a script or workflow in the configuration, matched with the # prefix.

Selectors​

Selector      KindWhere        ResultDescription
firstplainany pathone nodeFirst direct descendant whose id is in the OR-list. A bare id is this selector.
e.g. first(script1)
lastplainany pathone nodeLast direct descendant whose id is in the OR-list.
e.g. last(script1|script2)
allplainnon-basemany nodesEvery direct descendant whose id is in the OR-list; one query, many values.
e.g. all(metric)
expandplainbase onlyone instance per nodeLike all, but every match produces a separate link instance.
e.g. expand(workflow1|workflow2)
samereferencenon-baseone nodeThe node @ref matched at this segment. The id-list is optional and narrows the match.
e.g. same(@base) or same(@base, script1)
beforereferencenon-baseone nodeFirst preceding sibling whose id matches, scanning backward from the base.
e.g. before(@base, prepData)
before*referencenon-basemany nodesEvery preceding sibling whose id matches.
e.g. before*(@base, prepData)
before+referencenon-baseone nodeThe immediately preceding sibling, only when its id matches.
e.g. before+(@base, prepData)
afterreferencenon-baseone nodeFirst following sibling whose id matches, scanning forward from the base.
e.g. after(@base, nextStep)
after*referencenon-basemany nodesEvery following sibling whose id matches.
e.g. after*(@base, nextStep)
after+referencenon-baseone nodeThe immediately following sibling, only when its id matches.
e.g. after+(@base, nextStep)
#SELECTORtag variantany pathas the selectorThe same matching on tags, with AND across tags, descending through nesting.
e.g. #all(metric&primary)
outputs(nqName), inputs(nqName)io wildcardlast segment of from / to, with (template)one query per ioEvery 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 same requires an id or tag list.
  • Id lists use OR (|), tag lists use AND (&).
  • Tag variants exist for first, last, all, expand, same, before, before*, after and after*. There is no #before+ or #after+.
  • Stop ids are a third argument of before and after in every variant; see Modifiers and stop ids.

Flags​

FlagMeaningAllowed in
optionalA query with no match does not prevent the link from being created; the alias reads as absent.Any query.
callMatch 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.
templateExpand 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​

FieldEnds inFlags
from of data, validator, meta, node meta and pipeline validator linksa script io, or a node with calloptional, call with optional, template
to of data, validator and meta linksa script iooptional, template
to of node meta and pipeline validator linksa node, or empty for the host workflowoptional
basea node; first, last, expand and their tag variants onlynone
nota nodeoptional; call accepted without effect
actions of validatorsa node, any selectoroptional
showWhen, hideWhen of actionsa node; no io wildcardsoptional
from / to of funccall actionsa node with call, or a script iooptional, call
from / to of rulesa script iooptional, template
io, check.table and vars values of checksa script ionone; 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:

SelectorCaptures
beforeprep3
before*prep1, prep2, prep3
before+prep3, only when the adjacent sibling is in the list; otherwise no match
afternext1
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:

ExclusionDropsApplied
an io namethat ioonce, when the configuration is processed
$nonscalarevery io that is not a number, string, boolean or date, such as dataframes, columns and listsonce, when the configuration is processed
$linkedevery io that another data link writesafter 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 $linked wildcards do not count, so two links with $linked over 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, through getMatchedOutputs.
  • 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 to only. In from, $linked just 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:

QueryAliases
in:clean/tablein
in_(template):clean/table|statsin_table, in_stats
_(template):clean/table|statstable, 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 $:

NameAdded byHolds
valuechecks and annotation validatorsThe checked io, as in platform validator expressions.
$targetchecks and annotation validatorsThe checked io, as the output that receives the result.
$tablecolumn checksThe dataframe io named in table.
$callrules with validators or choices sources, checks and annotation validators that call platform validatorsThe step's FuncCall, as an optional call input.
$verdictsthe validators option of checks and annotationsThe verdicts of the named validator functions.
$all.<alias>rule expressionsEvery matched value of a from query.
$nonscalar, $linkedio wildcardsExclusion 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:

QuerygetAllgetFirst
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 variantsOne value per matched node, in the order of getMatchedPositions.The value of the first node.
An optional query with no matchThrows.Throws.
A call queryNot readable. Use hasCall.Not readable.
A template queryRead 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​

  • expand is valid only inside base. Anywhere else it is a parse-time error.
  • all is not allowed inside base. Use expand to 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 of before and after support * only.
  • Absolute paths (leading /) and a mid-path . are forbidden.
  • Reference selectors require a leading @ref argument and plain selectors must not take one. Mixing is a parse-time error.
  • Outside funccall actions, call requires optional; the matched FuncCall is not exposed to handlers, only hasCall(name). call on a to outside funccall actions, call inside base, and call with template are rejected at parse time.
  • An io wildcard (outputs(), inputs()) requires the template flag and may only be the last segment.
  • Rule queries reject call; a check's io, table and vars queries carry no alias.