Page tree

You are viewing documentation for Structure Server and Data Center version 5.4 and patch releases. For other versions, see Version Index or Structure Cloud.

Skip to end of metadata
Go to start of metadata

Expr Language (pronounced like "expert" without the "t") is a simple language that lets you specify an "expression", or a formula, which is calculated for an issue or another item. When used in a Formula Column, the expression is calculated for each visible row in the displayed structure or query result.

Expr is an easy language to learn, and yet it is powerful enough to create very complex formulas. The following guide will cover the basic requirements of the Expr language.

For a more in-depth study, see our Expr Reference Guides.

You can view examples of Expr formulas by adding bundled formulas to your structure. To see the formula, simply open the  column options panel.

Language Components

An expression may contain one or more of the following:

  • Variables, which are mapped to attributes, including issue fields, progress, user properties, another column or even another formula.
  • Functions, which may take some arguments, and which produce the result at the moment of calculation.
  • Numbers and text strings.
  • Arithmetic, logical operations and parentheses.

There are also more advanced constructs:

  • Aggregate Functions, which calculate some aggregate (like sum or average) of an expression's values calculated for multiple items in the structure.
  • Local Variables, which let you introduce a value and reuse it multiple times in the formula.
  • Comments, which allow you document larger formulas.

Basic Constructs 

Variables

Variables are user-defined names, which represent attributes, such as:

Variables can contain letters (English only), numbers, dot (".") or underscore ("_") characters. Variables cannot contain spaces, and the first character must be a letter or an underscore.

Examples:

  • Priority
  • remaining_estimate
  • abc11
  • sprint.name

As you write your formula, Structure attempts to map your variables to well-known attributes. For example, the "remaining_estimate" variable above will automatically be mapped to the Remaining Estimate field. For this reason, it's best to choose meaningful names for your variables, rather than "x" or "VeryComplicatedCustomFieldName".

See Formula Columns for more information about creating and mapping variables.

Variable names are case-insensitive, meaning that Priority, priority and pRiOrItY will all refer to the same variable.

Functions

A function calculates a value based on its arguments and, sometimes, some external aspect. A function is written as the function name, followed by parentheses, which may or may not contain arguments.

Examples:

  • SUM(-original_estimate; remaining_estimate; time_spent)
  • CASE(priority, 'High*', 5, 1)
  • TODAY()

There are a number of standard functions available with Structure – see Expr Function Reference for details.

A function may take zero, one or more arguments. Some functions take variable number of arguments. Additionally, each argument can be another Expr expression and include calls to other functions.

Function arguments may be separated by comma (,) or semicolon (;). But in every function call within a formula, you need to use either all commas or all semicolons.

Function names are case-insensitive, like the variables. You can write TODAY() or Today().

Numbers and Text Strings

Numbers

You can use numbers in your formula. Formulas support whole numbers, decimals, or fraction.  Commas, spaces, locale-specific, percentage, currency or scientific formats are not supported.

Recognized as a numberNot recognized as a number
00,0
10001,000

1234567890123456

1 100 025
11.251.234e+04
.111($100)

You can write a number that is written with a locale-specific decimal and thousands separator as a text value, and it will be automatically converted to a number if needed. For example:

  • "1 122,25" * 2 → 2244.5

Text Strings

Text strings are a sequence of characters enclosed either in single (') or double quotes ("). Examples:

  • 'a text in single quotes may contain " (a double quote)'
  • "a text in double quotes may contain ' (a single quote)"
  • ""

Everything within a text string is retained verbatim to participate in the expression evaluation, except for the following:

  • A sequence of two backslashes (\\) is converted to a single backslash (\).
  • A sequence of a backslash and a single quote (\') is converted to a single quote character (') for text values enclosed in single quotes.
  • A sequence of a backslash and a double quote (\") is converted to a double quote character (") for the text values enclosed in double quotes.

Operations

Expr provides basic arithmetic operations, comparisons and logical operations.

The operations follow the general precedence rules for arithmetic, so A + B * C is calculated correctly. Comparison operations are done after the arithmetic operations and logical operations are done after comparisons. For detailed specification, see Expr Language Reference.

OperationsComments
+ - * /Basic operators. When used, the value is converted to a number.
= !=

Equality and non-equality: if either part of the comparison is a number, the other part is also converted into a number. If both values are strings, then string comparison is used.

String comparison ignores leading and trailing whitespace and is case-insensitive (according to JIRA's system locale).

< <= > >=Numerical comparisons. When used, both values are converted to numbers.
AND, OR, NOTLogical operations.
( )Parentheses can be used to group the results of operations prior to passing them to other operations. 

Advanced Constructs

Aggregate Functions

An aggregate function calculates some aggregate value (like sum or minimum) based on the values in a number of rows, typically for all sub-issues. 

Examples:

  • SUM{ remaining_estimate + time_spent } – calculates the total effort (estimated and actual) for the issue and all its sub-issues.
  • MAX{ resolved_date - created_date } – calculates the maximum time it took to resolve an issue, among the issue and its sub-issues.

Aggregate functions contain exactly one expression that is being aggregated, written in curly braces ({}) after the function name. 

They can also contain modifiers, which influence how the aggregation works:

  • SUM#all{ business_value } – this will force the function to include values from all duplicate items in the total. (By default, duplicates are ignored.)

See Aggregate Function Reference for a complete list of available aggregate functions and modifiers.

Note that there is a SUM() function and a SUM{} aggregate function. You can always tell aggregate functions from the usual functions by the use of curly braces: SUM{x}.

Local Variables

Local variables are helpful when an expression needs to be used in the same formula several times. For example:

  • IF(time_spent + remaining_estimate > 0;
       time_spent / (time_spent + remaining_estimate))

You can see that in this formula we are using "time_spent + remaining_estimate" twice – once when we check that it's not zero (so we don't divide by zero) and again when we divide by it.

Instead of repeating the expression every time, we can rewrite this formula using the WITH  construct:

  • WITH total_time = time_spent + remaining_estimate :
    IF(total_time > 0; time_spent / total_time)

You can define multiple local variables in succession. You can also use previously defined local variables when defining additional local variables. For example:

  • WITH total_time = time_spent + remaining_estimate :
    WITH progress = IF(total_time > 0; time_spent / total_time) :
    IF(progress > 0.5; "Great Progress!"; progress > 0.2; "Good Progress"; "Needs Progress")

Note the position of the colon (":") – it must be present where each local variable definition ends.

Comments

Comments are helpful when you have a large formula or when a reader might need explanations of what is being calculated. It's a good idea to add comments wherever the formula is not trivial.

  • To add multiple lines of comment, start the comment with /* and end the comment with */
  • To add a single line of comment, begin the comment with //

Example:

/* This formula calculates the verbal assessment of issue's progress.
   And this explanation is a comment that spans multiple lines. */

WITH total_time = time_spent + remaining_estimate :

// Progress is calculated based on time tracking. (This is a one-line comment.)
WITH progress = IF(total_time > 0; time_spent / total_time) :

IF(progress > 0.5; "Great Progress!"; progress > 0.2; "Good Progress"; "Needs Progress")

  • No labels