# Fiddler Query Language

## Overview

[Custom Metrics](https://docs.fiddler.ai/observability/platform/custom-metrics) and [Segments](https://docs.fiddler.ai/observability/platform/segments) are defined using the **Fiddler Query Language (FQL)**, a flexible set of constants, operators, and functions which can accommodate a large variety of metrics.

## Definitions

| Term               | Definition                                                                             |
| ------------------ | -------------------------------------------------------------------------------------- |
| Row-level function | A function which executes row-wise for a set of data. Returns a value for each row.    |
| Aggregate function | A function which executes across rows. Returns a single value for a given set of rows. |

## FQL Rules

* Column names can be referenced by name either with double quotes ("my\_column") or with no quotes (my\_column).
* Single quotes (') are used to represent string values.

## Data Types

FQL distinguishes between three data types:

| Data type | Supported values                                          | Examples                                                        | Supported Model Schema Data Types                                     |
| --------- | --------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------- |
| Number    | Any numeric value (integers and floats are both included) | <p><code>10</code><br><code>2.34</code></p>                     | <p><code>DataType.INTEGER</code><br><code>DataType.FLOAT</code></p>   |
| Boolean   | Only `true` and `false`                                   | <p><code>true</code><br><code>false</code></p>                  | `DataType.BOOLEAN`                                                    |
| String    | Any value wrapped in single quotes (`'`)                  | <p><code>'This is a string.'</code><br><code>'200.0'</code></p> | <p><code>DataType.CATEGORY</code><br><code>DataType.STRING</code></p> |

## Constants

| Symbol  | Description                            |
| ------- | -------------------------------------- |
| `true`  | Boolean constant for true expressions  |
| `false` | Boolean constant for false expressions |

## Operators

| Symbol | Description              | Syntax                | Returns   | Examples                                                                                                                            |
| ------ | ------------------------ | --------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `^`    | Exponentiation           | `Number ^ Number`     | `Number`  | <p><code>2.5 ^ 4</code><br><code>(column1 - column2)^2</code></p>                                                                   |
| `-`    | Unary negation           | `-Number`             | `Number`  | `-column1`                                                                                                                          |
| `*`    | Multiplication           | `Number * Number`     | `Number`  | <p><code>2 \* 10</code><br><code>2 \* column1</code><br><code>column1 \* column2</code><br><code>sum(column1) \* 10</code></p>      |
| `/`    | Division                 | `Number / Number`     | `Number`  | <p><code>2 / 10</code><br><code>2 / column1</code><br><code>column1 / column2</code><br><code>sum(column1) / 10</code></p>          |
| `%`    | Modulo                   | `Number % Number`     | `Number`  | <p><code>2 % 10</code><br><code>2 % column1</code><br><code>column1 % column2</code><br><code>sum(column1) % 10</code></p>          |
| `+`    | Addition                 | `Number + Number`     | `Number`  | <p><code>2 + 2</code><br><code>2 + column1</code><br><code>column1 + column2</code><br><code>average(column1) + 2</code></p>        |
| `-`    | Subtraction              | `Number - Number`     | `Number`  | <p><code>2 - 2</code><br><code>2 - column1</code><br><code>column1 - column2</code><br><code>average(column1) - 2</code></p>        |
| `<`    | Less than                | `Number < Number`     | `Boolean` | <p><code>10 < 20</code><br><code>column1 < 10</code><br><code>column1 < column2</code><br><code>average(column2) < 5</code></p>     |
| `<=`   | Less than or equal to    | `Number <= Number`    | `Boolean` | <p><code>10 <= 20</code><br><code>column1 <= 10</code><br><code>column1 <= column2</code><br><code>average(column2) <= 5</code></p> |
| `>`    | Greater than             | `Number > Number`     | `Boolean` | <p><code>10 > 20</code><br><code>column1 > 10</code><br><code>column1 > column2</code><br><code>average(column2) > 5</code></p>     |
| `>=`   | Greater than or equal to | `Number >= Number`    | `Boolean` | <p><code>10 >= 20</code><br><code>column1 >= 10</code><br><code>column1 >= column2</code><br><code>average(column2) >= 5</code></p> |
| `==`   | Equals                   | `Number == Number`    | `Boolean` | <p><code>10 == 20</code><br><code>column1 == 10</code><br><code>column1 == column2</code><br><code>average(column2) == 5</code></p> |
| `!=`   | Does not equal           | `Number != Number`    | `Boolean` | <p><code>10 != 20</code><br><code>column1 != 10</code><br><code>column1 != column2</code><br><code>average(column2) != 5</code></p> |
| `not`  | Logical NOT              | `not Boolean`         | `Boolean` | <p><code>not true</code><br><code>not column1</code></p>                                                                            |
| `and`  | Logical AND              | `Boolean and Boolean` | `Boolean` | <p><code>true and false</code><br><code>column1 and column2</code></p>                                                              |
| `or`   | Logical OR               | `Boolean or Boolean`  | `Boolean` | <p><code>true or false</code><br><code>column1 or column2</code></p>                                                                |

## Constant functions

| Symbol | Description                                           | Syntax | Returns  | Examples                    |
| ------ | ----------------------------------------------------- | ------ | -------- | --------------------------- |
| `e()`  | Base of the natural logarithm                         | `e()`  | `Number` | `e() == 2.718281828459045`  |
| `pi()` | The ratio of a circle's circumference to its diameter | `pi()` | `Number` | `pi() == 3.141592653589793` |

## Row-level functions

Row-level functions can be applied either to a single value or to a column/row expression (in which case they are mapped element-wise to each value in the column/row expression).

| Symbol                           | Description                                                                                                                                                                                     | Syntax                              | Returns   | Examples                                                                                         |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | --------- | ------------------------------------------------------------------------------------------------ |
| `if(condition, value1, value2)`  | <p>Evaluates <code>condition</code> and returns <code>value1</code> if true, otherwise returns <code>value2</code>.<br><code>value1</code> and <code>value2</code> must have the same type.</p> | `if(Boolean, Any, Any)`             | `Any`     | <p><code>if(false, 'yes', 'no') == 'no'</code><br><code>if(column1 == 1, 'yes', 'no')</code></p> |
| `length(x)`                      | Returns the length of string `x`.                                                                                                                                                               | `length(String)`                    | `Number`  | `length('Hello world') == 11`                                                                    |
| `to_string(x)`                   | Converts a value `x` to a string.                                                                                                                                                               | `to_string(Any)`                    | `String`  | <p><code>to\_string(42) == '42'</code><br><code>to\_string(true) == 'true'</code></p>            |
| `startswith(str, prefix)`        | Returns `true` if `str` starts with `prefix`.                                                                                                                                                   | `startswith(String, String)`        | `Boolean` | `startswith('abcde', 'abc')`                                                                     |
| `substring(str, offset, length)` | Returns a substring of `str` of length `length` from offset `offset`. The first character has an offset of 1.                                                                                   | `substring(String, Number, Number)` | `String`  | `substring('abcde', 2, 3) == 'bcd'`                                                              |
| `match(str, regex)`              | Returns `true` if `str` matches the pattern `regex` in [re2 regular syntax](https://github.com/google/re2/wiki/Syntax).                                                                         | `match(String, String)`             | `Boolean` | `match('abcde', 'a.c.*e')`                                                                       |
| `is_null(x)`                     | Returns `true` if `x` is null, otherwise returns `false`.                                                                                                                                       | `is_null(Any)`                      | `Boolean` | <p><code>is\_null('') == true</code><br><code>is\_null("column1")</code></p>                     |
| `is_not_null(x)`                 | Returns `true` if `x` is not null, otherwise returns `false`.                                                                                                                                   | `is_null(Any)`                      | `Boolean` | <p><code>is\_not\_null('') == false</code><br><code>\`is\_not\_null("column1")</code></p>        |
| `abs(x)`                         | Returns the absolute value of number `x`.                                                                                                                                                       | `abs(Number)`                       | `Number`  | `abs(-3) == 3`                                                                                   |
| `exp(x)`                         | Returns `e^x`, where `e` is the base of the natural logarithm.                                                                                                                                  | `exp(Number)`                       | `Number`  | `exp(1) == 2.718281828459045`                                                                    |
| `log(x)`                         | Returns the natural logarithm (base `e`) of number `x`.                                                                                                                                         | `log(Number)`                       | `Number`  | `log(e) == 1`                                                                                    |
| `log2(x)`                        | Returns the binary logarithm (base `2`) of number `x`.                                                                                                                                          | `log2(Number)`                      | `Number`  | `log2(16) == 4`                                                                                  |
| `log10(x)`                       | Returns the binary logarithm (base `10`) of number `x`.                                                                                                                                         | `log10(Number)`                     | `Number`  | `log10(1000) == 3`                                                                               |
| `sqrt(x)`                        | Returns the positive square root of number `x`.                                                                                                                                                 | `sqrt(Number)`                      | `Number`  | `sqrt(144) == 12`                                                                                |

## Aggregate functions

Every Custom Metric must be wrapped in an aggregate function or be a combination of aggregate functions.

| Symbol                      | Description                                                                                                                                                                                  | Syntax                           | Returns  | Examples                                                                                                                                               |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sum(x)`                    | Returns the sum of a numeric column or row expression `x`.                                                                                                                                   | `sum(Number)`                    | `Number` | `sum(column1 + column2)`                                                                                                                               |
| `average(x)`                | Returns the arithmetic mean/average value of a numeric column or row expression `x`.                                                                                                         | `average(Number)`                | `Number` | `average(2 * column1)`                                                                                                                                 |
| `count(x)`                  | Returns the number of non-null rows of a column or row expression `x`.                                                                                                                       | `count(Any)`                     | `Number` | `count(column1)`                                                                                                                                       |
| `quantile(x, level)`        | Returns the quantile (percentile) of a numeric column or row expression `x` at the specified `level`. The `level` must be a constant between 0.0 and 1.0 (defaults to 0.5 if not specified). | `quantile(Number, level=Number)` | `Number` | <p><code>quantile(Output, level=0.5)</code><br><code>quantile(latency\_ms, level=0.95)</code><br><code>quantile(response\_time, level=0.99)</code></p> |
| `greatest(agg1, agg2, ...)` | Returns the maximum value between multiple numerical aggregates                                                                                                                              | `greatest(Number, Number, ...)`  | `Number` | `greatest(sum(col1), sum(col2), sum(col3))`                                                                                                            |
| `least(agg1, agg2, ...)`    | Returns the minimum value between multiple numerical aggregates                                                                                                                              | `least(Number, Number, ...)`     | `Number` | `least(sum(col1), sum(col2), sum(col3))`                                                                                                               |

## Built-in metric functions

| Symbol                               | Description                                                                                                                                                                                                       | Syntax                                                             | Returns   | Examples                                                                                                                                                                                            |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `jsd(column, baseline)`              | The Jensen-Shannon distance of column `column` with respect to baseline `baseline`.                                                                                                                               | `jsd(Any, String)`                                                 | `Number`  | `jsd(column1, 'my_baseline')`                                                                                                                                                                       |
| `psi(column, baseline)`              | The population stability index of column `column` with respect to baseline `baseline`.                                                                                                                            | `psi(Any, String)`                                                 | `Number`  | `psi(column1, 'my_baseline')`                                                                                                                                                                       |
| `null_violation_count(column)`       | Number of rows with null values in column `column`.                                                                                                                                                               | `null_violation_count(Any)`                                        | `Number`  | `null_violation_count(column1)`                                                                                                                                                                     |
| `range_violation_count(column)`      | Number of rows with out-of-range values in column `column`.                                                                                                                                                       | `range_violation_count(Any)`                                       | `Number`  | `range_violation_count(column1)`                                                                                                                                                                    |
| `type_violation_count(column)`       | Number of rows with invalid data types in column `column`.                                                                                                                                                        | `type_violation_count(Any)`                                        | `Number`  | `type_violation_count(column1)`                                                                                                                                                                     |
| `any_violation_count(column)`        | Number of rows with at least one Data Integrity violation in `column`.                                                                                                                                            | `any_violation_count(Any)`                                         | `Number`  | `any_violation_count(column1)`                                                                                                                                                                      |
| `traffic()`                          | Total row count. Includes null rows.                                                                                                                                                                              | `traffic()`                                                        | `Number`  | `traffic()`                                                                                                                                                                                         |
| `tp(class)`                          | True positive boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class.                                             | `tp(class=Optional[String])`                                       | `Boolean` | <p><code>tp()</code><br><code>tp(class='class1')</code></p>                                                                                                                                         |
| `tn(class)`                          | True negative boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class.                                             | `tn(class=Optional[String])`                                       | `Boolean` | <p><code>tn()</code><br><code>tn(class='class1')</code></p>                                                                                                                                         |
| `fp(class)`                          | False positive boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class.                                            | `fp(class=Optional[String])`                                       | `Boolean` | <p><code>fp()</code><br><code>fp(class='class1')</code></p>                                                                                                                                         |
| `fn(class)`                          | False negative boolean state. Available for binary classification and multiclass classification models. For multiclass, `class` is used to specify the positive class.                                            | `fn(class=Optional[String])`                                       | `Boolean` | <p><code>fn()</code><br><code>fn(class='class1')</code></p>                                                                                                                                         |
| `precision(target, threshold)`       | <p>Precision between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                       | `precision(target=Optional[Any], threshold=Optional[Number])`      | `Number`  | <p><code>precision()</code><br><code>precision(target=column1)</code><br><code>precision(threshold=0.5)</code><br><code>precision(target=column1, threshold=0.5)</code></p>                         |
| `recall(target, threshold)`          | <p>Recall between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                          | `recall(target=Optional[Any], threshold=Optional[Number])`         | `Number`  | <p><code>recall()</code><br><code>recall(target=column1)</code><br><code>recall(threshold=0.5)</code><br><code>recall(target=column1, threshold=0.5)</code></p>                                     |
| `f1_score(target, threshold)`        | <p>F1 score between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                        | `f1_score(target=Optional[Any], threshold=Optional[Number])`       | `Number`  | <p><code>f1\_score()</code><br><code>f1\_score(target=column1)</code><br><code>f1\_score(threshold=0.5)</code><br><code>f1\_score(target=column1, threshold=0.5)</code></p>                         |
| `fpr(target, threshold)`             | <p>False positive rate between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>             | `fpr(target=Optional[Any], threshold=Optional[Number])`            | `Number`  | <p><code>fpr()</code><br><code>fpr(target=column1)</code><br><code>fpr(threshold=0.5)</code><br><code>fpr(target=column1, threshold=0.5)</code></p>                                                 |
| `auroc(target)`                      | <p>Area under the ROC curve between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>        | `auroc(target=Optional[Any])`                                      | `Number`  | <p><code>auroc()</code><br><code>auroc(target=column1)</code></p>                                                                                                                                   |
| `geometric_mean(target, threshold)`  | <p>Geometric mean score between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>            | `geometric_mean(target=Optional[Any], threshold=Optional[Number])` | `Number`  | <p><code>geometric\_mean()</code><br><code>geometric\_mean(target=column1)</code><br><code>geometric\_mean(threshold=0.5)</code><br><code>geometric\_mean(target=column1, threshold=0.5)</code></p> |
| `expected_calibration_error(target)` | <p>Expected calibration error between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>      | `expected_calibration_error(target=Optional[Any])`                 | `Number`  | <p><code>expected\_calibration\_error()</code><br><code>expected\_calibration\_error(target=column1)</code></p>                                                                                     |
| `log_loss(target)`                   | <p>Log loss (binary cross entropy) between target and output. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p> | `log_loss(target=Optional[Any])`                                   | `Number`  | <p><code>log\_loss()</code><br><code>log\_loss(target=column1)</code></p>                                                                                                                           |
| `calibrated_threshold(target)`       | <p>Optimal threshold value for a high TPR and a low FPR. Available for binary classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>      | `calibrated_threshold(target=Optional[Any])`                       | `Number`  | <p><code>calibrated\_threshold()</code><br><code>calibrated\_threshold(target=column1)</code></p>                                                                                                   |
| `accuracy(target, threshold)`        | <p>Accuracy score between target and outputs. Available for multiclass classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>             | `accuracy(target=Optional[Any], threshold=Optional[Number])`       | `Number`  | <p><code>accuracy()</code><br><code>accuracy(target=column1)</code><br><code>accuracy(threshold=0.5)</code><br><code>accuracy(target=column1, threshold=0.5)</code></p>                             |
| `log_loss(target)`                   | <p>Log loss score between target and outputs. Available for multiclass classification model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>             | `log_loss(target=Optional[Any])`                                   | `Number`  | <p><code>log\_loss()</code><br><code>log\_loss(target=column1)</code></p>                                                                                                                           |
| `r2(target)`                         | <p>R-squared score between target and output. Available for regression model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                            | `r2(target=Optional[Any])`                                         | `Number`  | <p><code>r2()</code><br><code>r2(target=column1)</code></p>                                                                                                                                         |
| `mse(target)`                        | <p>Mean squared error between target and output. Available for regression model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                         | `mse(target=Optional[Any])`                                        | `Number`  | <p><code>mse()</code><br><code>mse(target=column1)</code></p>                                                                                                                                       |
| `mae(target)`                        | <p>Mean absolute error between target and output. Available for regression model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                        | `mae(target=Optional[Any])`                                        | `Number`  | <p><code>mae()</code><br><code>mae(target=column1)</code></p>                                                                                                                                       |
| `mape(target)`                       | <p>Mean absolute percentage error between target and output. Available for regression model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>             | `mape(target=Optional[Any])`                                       | `Number`  | <p><code>mape()</code><br><code>mape(target=column1)</code></p>                                                                                                                                     |
| `wmape(target)`                      | <p>Weighted mean absolute percentage error between target and output. Available for regression model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>    | `wmape(target=Optional[Any])`                                      | `Number`  | <p><code>wmape()</code><br><code>wmape(target=column1)</code></p>                                                                                                                                   |
| `map(target)`                        | <p>Mean average precision score. Available for ranking model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                                            | `map(target=Optional[Any])`                                        | `Number`  | <p><code>map()</code><br><code>map(target=column1)</code></p>                                                                                                                                       |
| `ndcg_mean(target)`                  | <p>Mean normalized discounted cumulative gain score. Available for ranking model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                        | `ndcg_mean(target=Optional[Any])`                                  | `Number`  | <p><code>ndcg\_mean()</code><br><code>ndcg\_mean(target=column1)</code></p>                                                                                                                         |
| `query_count(target)`                | <p>Count of ranking queries. Available for ranking model tasks.<br>If <code>target</code> is specified, it will be used in place of the default target column.</p>                                                | `query_count(target=Optional[Any])`                                | `Number`  | <p><code>query\_count()</code><br><code>query\_count(target=column1)</code></p>                                                                                                                     |
