Page tree
Skip to end of metadata
Go to start of metadata

A function calculates a value based on its arguments and, sometimes, some external aspect. A function call 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()

Function names are case-insensitive. You can write TODAY() or Today().

There are 100+ standard functions available with Structure – see Expr Function Reference for a complete list.

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.

 Chained Function Calls

The chained notation allows you to easily apply a sequence of functions to a value, simply by listing each function one after the other, separated by a ( . ) dot.
  • Standard notation: F3(F2(F1(x)))
  • Chain notation: x.F1().F2().F3()

When you use the chain notation, the value that comes before the dot becomes the first argument for the function. If the function takes multiple arguments, the rest of the arguments must be written in parentheses.

For example:

created.FORMAT_DATETIME("yyyy").CONCAT(" year issue")

In this example, FORMAT_DATETIME takes the date value in "created" and formats it based on the argument in parenthesis ("yyyy"). CONCAT takes the result from FORMAT_DATETIME and joins it with " year issue".

 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. Aggregate functions are written very similar to standard functions, except they use curly braces: SUM{x}.

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.

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.

Any local variables used inside an aggregate function must also be declared inside the function - within the { } . 

 User Functions

A user function allows you to define a locally-used function within a formula. User functions can be defined in a similar manner as local variables:
WITH square(x) = x * x : 
  square(impactField) / square(storyPoints)

In this example, the user function is given a name ("square") and then used to perform the same calculation on multiple fields. To learn more, see the language reference.

User Functions for Arrays - using the "$" character

When you need to perform an operation on each element in an array, you can use a user function such as the one above, or simplify it using “$” to indicate each element in the array.

worklogs.FILTER($.author = ME())

In this example, the "$" tells Structure to apply "author = ME()" to each element in worklogs - if the author is the current user, it returns true and that worklog will be included in the FILTER results.

This method becomes very powerful when you combine multiple user functions together. To learn more, see the language reference.


Embedded Queries (JQL and S-JQL)
You can embed JQL and Structured JQL queries inside an Expr formula, using a construct similar to Aggregate Functions. The result will be a boolean value:

  • 1 (true) if the current row matches the query
  • 0 (false) otherwise

For example:

// Collect total story points from all sub-issues assigned to members of Team2 group, unless the stories are under folder "Special"
SUM { 
    IF JQL { assignee in membersOf("Team2") } :
    IF NOT SJQL { descendant of folder("Special") } : 
      storyPoints
}

Since JQL is a Jira-based query, it will work only on issues; the result will be 0 on other types of items. S-JQL can be used for more complex queries applicable to the whole structure.