# How to use DataPrime to build conditional logic into your queries

## Goal

By the end of this guide you should be able to build conditional expressions using functions like `if`, `case`, `case_equals`, and `case_contains` to enrich, categorize, or branch your data within a single query.

## Why it matters

Logs and traces often need dynamic treatment: flag errors, group by environment, tag suspicious IPs, or label users by behavior. Conditional logic lets you make smart, data-driven decisions—on the fly—without needing multiple queries or transformations.

______________________________________________________________________

## Using conditional logic in DataPrime

Conditional logic in DataPrime allows you to transform, enrich, and classify logs dynamically based on rules you define. Whether you’re tagging internal IPs, labeling request types, or adapting behavior by environment, these functions help you make smarter queries without post-processing.

You can express conditional logic in a few different ways, depending on your use case:

______________________________________________________________________

## `if` — Return one value if a condition is true, another if false

The `if` function evaluates a boolean condition and returns one value if the condition is `true`, and another if it's `false`.

### Syntax

```dataprime
if(condition: bool, then: any, else: any?): any
```

### Example — Flag internal IP addresses

Use `if` to tag whether a request originates from an internal IP subnet.

#### Input data

```json
{ "ip": "10.8.0.8" }
{ "ip": "192.168.4.9" }
{ "ip": "8.8.8.8" }
```

#### Query

```dataprime
create is_internal_ip from if(ipInSubnet(ip, '10.0.0.0/8'), true, false)
```

#### Result

```text
{ ip: 10.8.0.8, is_internal_ip: true }
{ ip: 192.168.4.9, is_internal_ip: false }
{ ip: 8.8.8.8, is_internal_ip: false }
```

______________________________________________________________________

## `case` — Multiple conditional checks with fallback

The `case` function evaluates a list of boolean conditions and returns the first matching result. If no condition matches, it returns a default.

### Syntax

```dataprime
case {
  condition1 -> result1,
  condition2 -> result2,
  ...
  _ -> default
}
```

### Example — Assign owner based on server IP subnet

Use `case` to tag server owners by IP subnet.

#### Input data

```json
{ "server_ip": "10.8.0.8" }
{ "server_ip": "165.4.2.1" }
{ "server_ip": "192.168.0.9" }
{ "server_ip": "8.8.8.8" }
```

#### Query

```dataprime
create server_owner from 
  case {
    ipInSubnet(server_ip, '10.0.0.0/8')   -> 'Chris',
    ipInSubnet(server_ip, '165.0.0.0/8')  -> 'George',
    ipInSubnet(server_ip, '192.168.0.0/16') -> 'Lloyd',
    _ -> 'Unknown'
  }
```

#### Result

```text
{ server_ip: 10.8.0.8, server_owner: Chris }
{ server_ip: 165.4.2.1, server_owner: George }
{ server_ip: 192.168.0.9, server_owner: Lloyd }
{ server_ip: 8.8.8.8, server_owner: Unknown }
```

______________________________________________________________________

## `case_equals` — Match exact values

The `case_equals` function matches a value against a list of exact candidates and returns the corresponding result. Ideal for enumerated inputs.

### Syntax

```dataprime
case_equals {
  e: any,
  value1 -> result1,
  value2 -> result2,
  ...
  _ -> default
}
```

### Example — Control alert logic by cluster

Use `case_equals` to define whether alerts should be enabled by cluster name.

#### Input data

```json
{ "cluster_name": "acme-prod-cluster" }
{ "cluster_name": "acme-dev-cluster" }
{ "cluster_name": "acme-stg-cluster" }
{ "cluster_name": "acme-test-cluster" }
```

#### Query

```dataprime
create should_alert from 
  case_equals {
    cluster_name,
    'acme-prod-cluster' -> true,
    'acme-dev-cluster'  -> false,
    'acme-stg-cluster'  -> true,
    _ -> false
  }
```

#### Result

```text
{ cluster_name: acme-prod-cluster, should_alert: true }
{ cluster_name: acme-dev-cluster, should_alert: false }
{ cluster_name: acme-stg-cluster, should_alert: true }
{ cluster_name: acme-test-cluster, should_alert: false }
```

______________________________________________________________________

## `case_contains` — Match substrings in strings

The `case_contains` function checks whether a given string contains one of several substrings and returns the corresponding result.

### Syntax

```dataprime
case_contains {
  s: string,
  substring1 -> result1,
  substring2 -> result2,
  ...
  _ -> default
}
```

### Example — Normalize environment names

Use `case_contains` to map cluster name fragments to environment labels.

#### Input data

```json
{ "cluster_name": "acme-prod-cluster" }
{ "cluster_name": "acme-dev-cluster" }
{ "cluster_name": "acme-stg-cluster" }
{ "cluster_name": "acme-temp-cluster" }
```

#### Query

```dataprime
create environment from 
  case_contains {
    cluster_name,
    '-prod-' -> 'production',
    '-dev-'  -> 'development',
    '-stg-'  -> 'staging',
    _        -> 'test'
  }
```

#### Result

```text
{ cluster_name: acme-prod-cluster, environment: production }
{ cluster_name: acme-dev-cluster, environment: development }
{ cluster_name: acme-stg-cluster, environment: staging }
{ cluster_name: acme-temp-cluster, environment: test }
```

______________________________________________________________________

## `case_lessthan` — Return result for first value less than input

The `case_lessthan` function returns a result based on whether the input is less than the listed values, evaluated in ascending order.

### Syntax

```dataprime
case_lessthan {
  n: number,
  threshold1 -> result1,
  threshold2 -> result2,
  ...
  _ -> default
}
```

### Example — Categorize temperatures

Use `case_lessthan` to assign a label based on temperature ranges.

#### Input data

```json
{ "temperature_celsius": 5 }
{ "temperature_celsius": 15 }
{ "temperature_celsius": 25 }
{ "temperature_celsius": 50 }
```

#### Query

```dataprime
create temperature_status from 
  case_lessthan {
    temperature_celsius,
    10 -> 'freezing',
    20 -> 'cold',
    30 -> 'warm',
    45 -> 'hot',
    _  -> 'extreme'
  }
```

#### Result

```text
{ temperature_celsius: 5, temperature_status: freezing }
{ temperature_celsius: 15, temperature_status: cold }
{ temperature_celsius: 25, temperature_status: warm }
{ temperature_celsius: 50, temperature_status: extreme }
```

______________________________________________________________________

## Common pitfalls or gotchas

- `case` and all its variants return **only the first matching value**—**order matters**.
- `if()` requires a boolean condition as the first argument.
- Don’t forget the `_ -> default` fallback in your `case` statements to avoid `null`s.
- When chaining logic, consider readability—sometimes breaking up logic with intermediate `create` steps helps.

______________________________________________________________________

## Next steps / related guides

- [How to group logs by environment to detect anomalies](#)
- [Using DataPrime to enrich logs with user context](#)
- [How to extract and normalize inconsistent field formats](#)
- [Working with arrays and dynamic conditions](#)
