# Dynamic

`Dynamic` stores values of different concrete types in the same declared column. Each value retains its active type, which can be inspected or extracted by a function.

Use Dynamic when the types are not known in advance. Use [Variant](https://coordinatordb.com/docs/reference/data-types/variant) to restrict values to a declared alternative list.

## Creating Dynamic

```text
Dynamic
Dynamic(max_types=N)
```

* `N` — A value from 0 through 254, defaulting to 32. This parameter is retained as type metadata; it does not limit the types admitted by CoordinatorDB.

SQL `NULL` is accepted without a Nullable wrapper.

## Using Dynamic type in functions

`dynamic_type(value)` returns the active type name, or `'None'` for `NULL`. `dynamic_element(value, 'Type')` extracts the payload when the active type matches and returns `NULL` otherwise.

Arithmetic uses the actual payload and retains a Dynamic result. Numeric aggregates require extraction or an explicit numeric cast. Ordering uses the active type's canonical name and then its value; distinct active numeric types are not collapsed merely because their numeric values are equal.

## Examples

### Different types in one column

```sql
CREATE TABLE observations(id UInt32, value Dynamic);
INSERT INTO observations VALUES
    (1, CAST(7 AS UInt64)),
    (2, 'hello'),
    (3, NULL);
```

```sql
SELECT id, dynamic_type(value)
FROM observations
ORDER BY id
FORMAT csv;
```

```text
1,"UInt64"
2,"String"
3,"None"
```

### Extracting a matching type

```sql
SELECT dynamic_element(CAST('hello' AS Dynamic), 'String'),
       dynamic_element(CAST('hello' AS Dynamic), 'UInt64')
FORMAT csv;
```

```text
"hello",\N
```
