# PantherFlow Functions

{% hint style="info" %}
PantherFlow is in open beta starting with Panther version 1.110, and is available to all customers. Please share any bug reports and feature requests with your Panther support team.
{% endhint %}

## Aggregations

### `agg.avg()`

`agg.avg(column: T) -> float`

Returns the average of the values in the aggregation.

### `agg.count()`

`agg.count([column: T]) -> int`

Returns the number of values in the aggregation.

### `agg.count_distinct()`

`agg.count_distinct(column: T) -> int`

Returns the number of unique values in the aggregation.

### `agg.make_set()`

`agg.make_set(column: T) -> [T]`

Returns a set of unique values from the column.

### `agg.max()`

`agg.max(column: T) -> float`

Returns the maximum value in the aggregation.

### `agg.min()`

`agg.min(column: T) -> float`

Returns the minimum value in the aggregation.

### `agg.sum()`

`agg.sum(column: T) -> float`

Returns the sum of the values in the aggregation.

### `agg.take_any()`

`agg.take_any(column: T) -> T`

Returns any value from the aggregation.

## Date/time

### `time.ago()`

`time.ago(span: timespan) -> timestamp`

Returns the timestamp that is `span` ago.

### `time.date_trunc()`

`time.date_trunc(unit: string, timestamp: timestamp) -> timestamp`

Returns the timestamp truncated to the specified unit.

### `time.diff()`

`time.diff(unit: string, timestamp1: timestamp, timestamp2: timestamp) -> integer`

Calculates the difference between two timestamp expressions based on the date or time unitrequested. The function returns the result of subtracting timestamp1 from timestamp2 (i.e. timestamp2 - timestamp1).

### `time.now()`

`time.now() -> timestamp`

Returns the current timestamp.

### `time.parse_date()`

`time.parse_date(str: string) -> timestamp`

Returns the timestamp representation of the date string.

### `time.parse_timespan()`

`time.parse_timespan(str: string) -> timespan`

Returns the timespan representation of the duration string.

### `time.parse_timestamp()`

`time.parse_timestamp(str: string) -> timestamp`

Returns the timestamp representation of the timestamp string.

### `time.slice()`

`time.slice(time: timestamp, slice_length: int, slice_unit: string) -> timestamp`

Returns the timestamp that `time` resides in, given chunks of `slice_unit` and `slice_length`. For example, if `slice_length` is 1 and `slice_unit` is "hour", the time is truncated to the hour it belongs to. Slices are calculated relative to midnight January 1, 1970. `slice_unit` can be "second", "minute", "hour", "day", "week", "month", "quarter", or "year".

## Strings

### `strings.cat()`

`strings.cat(str: string, ...str: string) -> string`

Concatenates strings.

### `strings.contains()`

`strings.contains(thing: T, substr: string) -> bool`

Returns true if `thing` contains `substr`. If `thing` is not a string, it is stringified first.

### `strings.ilike()`

`strings.ilike(str: T, substr: string) -> bool`

Returns true if `str` contains `substr` with [SQL LIKE](https://www.w3schools.com/sql/sql_like.asp) semantics, ignoring case.

### `strings.len()`

`strings.len(thing: T) -> int`

Returns the length of `thing`. If `thing` is not a string, it is stringified first.

### `strings.like()`

`strings.like(str: T, substr: string) -> bool`

Returns true if `str` contains `substr` with [SQL LIKE](https://www.w3schools.com/sql/sql_like.asp) semantics.

### `strings.lower()`

`strings.lower(str: string) -> string`

Returns `str` converted to lower case.

### `strings.split()`

`strings.split(str: T, sep: string) -> [string]`

Returns a list of substrings of `str` separated by `sep`.

### `strings.starts_with()`

`strings.starts_with(str: T, prefix: string) -> bool`

Returns true if `str` starts with `prefix`.

### `strings.upper()`

`strings.upper(str: string) -> string`

Returns `str` converted to upper case.

## Arrays

### `arrays.len()`

`arrays.len(arr: [T]) -> int`

Returns the length of `arr`. If `arr` is not an array it is jsonified first.

### `arrays.overlap()`

`arrays.overlap(arr1: [T], arr2: [T]) -> bool`

Returns true if `arr1` and `arr2` have any elements in common.

## Math

### `math.round()`

`math.round(value: float, precision: int) -> float`

Returns the value rounded to the specified precision.

## Control flow

### `case()`

`case(condition1: bool, value1: any, condition2: bool, value2: any, ...valueN: any) -> any`

Returns the first value for which the corresponding condition is true. If no condition is true, returns null.

## Regular expressions

### `re.count()`

`re.count(stringable: T, regex: string) -> int`

Returns the number of times that `regex` occurs in `stringable`, or `null` if any value is `null`.

### `re.matches()`

`re.matches(stringable: T, regex: string) -> bool`

Returns true if `stringable` matches the regular expression `regex`.

### `re.replace()`

`re.replace(stringable: T, regex: string, replacement: string) -> string`

Returns `stringable` with the specified pattern `regex` (or all occurrences of the pattern) either removed or replaced by `replacement`, or `null` if any value is `null`.

### `re.substr()`

`re.substr(stringable: T, regex: string) -> string`

Returns the first substring that matches `regex` within `stringable`, or `null` if any value is `null`.

## Data types

### `array()`

`array(value1: any, value2: any, ...valueN: any) -> array`

Returns an array with the given values.

### `datetime()`

`datetime(value: timestamp) -> timestamp`

Returns the timestamp representation of the value.

### `object()`

`object(key1: string, value1: any, key2: string, value2: any, ...valueN: any) -> object`

Returns an object with the given key-value pairs.

## Other

### `coalesce()`

`coalesce(value1: any, value2: any, ...valueN: any) -> any`

Returns the first non-null value in the list of arguments.

### `toscalar()`

`toscalar(query: T) -> scalar`

Converts a query to a scalar value. If the row contains more than one value it randomly selects one of the values. If the query returns more than one row, it selects the first row.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.panther.com/~/changes/Cd1BxbxeaFl8dlynhNpt/pantherflow/functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
