Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Expressions

Expressions are the means the carry out calculations and utilize familiar query-language elements like literal values, function calls, subqueries, and so forth.

Within pipe operators, expressions may reference input values either via the special value this or implied field references to this, while within SQL clauses, input is referenced with table and column references.

For example, values, where, cut, put, sort and so forth all utilize various expressions as part of their semantics.

Likewise, the projected columns of a SELECT from the very same expression syntax used by pipe operators.

While SQL expressions and pipe expressions share an identical syntax, their semantics diverges in some key ways:

  • SQL expressions that reference this have semantics that depend on the SQL clause that expression appears in,
  • relational tables and/or columns cannot be referenced using aliases in pipe scoping,
  • double-quoted string literals may be used in pipe expressions but are interpreted as identifiers in SQL expressions.

Expression Syntax

Expressions are composed from operands and operators over operands.

Operands include

Operators include

  • arithmetic to add, subtract, multiply, divide, etc,
  • cast to convert values from one type to another,
  • comparisons to compare two values resulting in a Boolean,
  • concatenation of strings,
  • conditionals including C-style ?-: operator and SQL CASE expressions,
  • containment to test for the existing value inside an array or set,
  • dot to access a field of a record (or a SQL column of a table),
  • exists for SQL compatibility to test for non-empty subqueries,
  • indexing to select and slice elements from an array, record, map, string, or bytes,
  • logic to combine predicates using Boolean logic, and
  • slices to extract subsequences from arrays, sets, strings, and bytes.

Identifier Resolution

An identifier that appears as an operand in an expression is resolved to the entity that it represents using lexical scoping.

For identifiers that appear in the context of call syntax, i.e., having the form

<func> ( <args> )

then <func> is one of:

Identifiers that correspond to an in-scope function may also be referenced with the syntax

& <name>

as a function reference and must appear as an argument to an operator or function; otherwise, such expressions are errors.

For identifiers that resolve to in-scope declarations, the resolution is as follows:

For other instances of identifiers, then identifier is presumed to be an input reference and is resolved as such.

Precedence

When multiple operators appear in an unparenthesized sequence, ambiguity may arise by the order of evaluation as expressions are not always evaluated in a strict left-to-right order. Precedence rules determine the operator order when such ambiguity exists where higher precedence operators are evaluated before lower precedence operators.

For example,

1 + 2 * 3

is 7 not 9 because multiplication has higher precedence than addition and the above expression is equivalent to \

1 + ( 2 * 3 )

Operators have the following precedence from highest to lowest:

Some operators like case expressions do not have any such ambiguity as keywords delineate their sub-expressions and thus do not have any inherent precedence.

Coercion

Note

A forthcoming version of this documentation will describe the coercion rules for automatically casting of values for type compatibility in expressions.