# `Adbc.Column`
[🔗](https://github.com/elixir-explorer/adbc/blob/v0.12.1/lib/adbc/column.ex#L1)

Represents columns in the table.

It contains the column's field definition and data.
The field (an `Adbc.Field`) describes the column's name, type,
and metadata. The data field is opaque and must not be accessed
directly, use functions such as `to_list/1` to get a list of
values of the column's data type.

You can create new columns using constructors such as `s8/2`,
`boolean/2`, etc. `new/2` is available as a convenience that
infers the type for you.

# `interval_day_time`

```elixir
@type interval_day_time() :: {s32(), s32()}
```

# `interval_month`

```elixir
@type interval_month() :: s32()
```

# `interval_month_day_nano`

```elixir
@type interval_month_day_nano() :: {s32(), s32(), s64()}
```

# `precision128`

```elixir
@type precision128() :: 1..38
```

# `precision256`

```elixir
@type precision256() :: 1..76
```

# `s8`

```elixir
@type s8() :: -128..127
```

# `s16`

```elixir
@type s16() :: -32768..32767
```

# `s32`

```elixir
@type s32() :: -2_147_483_648..2_147_483_647
```

# `s64`

```elixir
@type s64() :: -9_223_372_036_854_775_808..9_223_372_036_854_775_807
```

# `t`

```elixir
@type t() :: %Adbc.Column{
  data: term(),
  field: Adbc.Field.t(),
  size: non_neg_integer() | nil
}
```

# `u8`

```elixir
@type u8() :: 0..255
```

# `u16`

```elixir
@type u16() :: 0..65535
```

# `u32`

```elixir
@type u32() :: 0..4_294_967_295
```

# `u64`

```elixir
@type u64() :: 0..18_446_744_073_709_551_615
```

# `binary`

```elixir
@spec binary([iodata() | nil], Keyword.t()) :: t()
```

A column that contains binary values.

## Arguments

* `data`: A list of binary values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.binary([<<0>>, <<1>>, <<2>>])
    iex> col.field
    %Adbc.Field{name: nil, type: :binary}
    iex> Adbc.Column.to_list(col)
    [<<0>>, <<1>>, <<2>>]

# `boolean`

```elixir
@spec boolean([boolean()], Keyword.t()) :: t()
```

A column that contains booleans.

## Arguments

* `data`: A list of booleans
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.boolean([true, false, true])
    iex> col.field
    %Adbc.Field{name: nil, type: :boolean}
    iex> Adbc.Column.to_list(col)
    [true, false, true]

# `date32`

```elixir
@spec date32([Date.t() | s32() | nil], Keyword.t()) :: t()
```

A column that contains date represented as 32-bit signed integers in UTC.

## Arguments

* `data`: a list, each element of which can be one of the following:
  * a `Date.t()`
  * a 32-bit signed integer representing the number of days since the Unix epoch.
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `date64`

```elixir
@spec date64([Date.t() | s64() | nil], Keyword.t()) :: t()
```

A column that contains date represented as 64-bit signed integers in UTC.

## Arguments

* `data`: a list, each element of which can be one of the following:
  * a `Date.t()`
  * a 64-bit signed integer representing the number of milliseconds since the Unix epoch.
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `decimal128`

```elixir
@spec decimal128(
  [Decimal.t() | integer() | nil],
  precision128(),
  integer(),
  Keyword.t()
) :: t()
```

A column that contains 128-bit decimals.

## Arguments

* `data`: a list, each element can be either
  * a `Decimal.t()`
  * an `integer()`
* `precision`: The precision of the decimal values; precision should be between 1 and 38
* `scale`: The scale of the decimal values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `decimal256`

```elixir
@spec decimal256(
  [Decimal.t() | integer() | nil],
  precision256(),
  integer(),
  Keyword.t()
) :: t()
```

A column that contains 256-bit decimals.

## Arguments

* `data`: a list, each element can be either
  * a `Decimal.t()`
  * an `integer()`
* `precision`: The precision of the decimal values; precision should be between 1 and 76
* `scale`: The scale of the decimal values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `dictionary`

```elixir
@spec dictionary(t(), t(), Keyword.t()) :: t()
```

Construct an array using dictionary encoding.

Dictionary encoding is a data representation technique to represent values by integers
referencing a dictionary usually consisting of unique values. It can be effective when
you have data with many repeated values.

Any array can be dictionary-encoded. The dictionary is stored as an optional property
of an array. When a field is dictionary encoded, the values are represented by an array
of non-negative integers representing the index of the value in the dictionary. The memory
layout for a dictionary-encoded array is the same as that of a primitive integer layout.
The dictionary is handled as a separate columnar array with its own respective layout.

As an example, you could have the following data:

```elixir
Adbc.Column.string(["foo", "bar", "foo", "bar", nil, "baz"])
```

In dictionary-encoded form, this could appear as:

```elixir
Adbc.Column.dictionary(
  Adbc.Column.string(["foo", "bar", "baz"]),
  Adbc.Column.s32([0, 1, 0, 1, nil, 2])
)
```

## Arguments

* `data`: a list, each element of which can be one of the following:
  - `nil`
  - `Adbc.Column`

  Note that each `Adbc.Column` in the list should have the same type.

* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `duration`

```elixir
@spec duration([s64() | nil], Adbc.Field.time_unit(), Keyword.t()) :: t()
```

A column that contains durations represented as 64-bit signed integers.

## Arguments

* `data`: a list of integer values representing the time in the specified unit

* `unit`: specify the unit of the time value, one of the following:
  * `:seconds`
  * `:milliseconds`
  * `:microseconds`
  * `:nanoseconds`

* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `f16`

```elixir
@spec f16([integer() | float() | nil | :infinity | :neg_infinity | :nan], Keyword.t()) ::
  t()
```

A column that contains 16-bit half-precision floats.

## Arguments

* `data`: A list of float values (will be converted to 16-bit floats in C). Integer values are automatically cast to floats.
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.f16([1.0, 2.0, 3.0])
    iex> col.field
    %Adbc.Field{name: nil, type: :f16}
    iex> Adbc.Column.to_list(col)
    [1.0, 2.0, 3.0]

# `f32`

```elixir
@spec f32([integer() | float() | nil | :infinity | :neg_infinity | :nan], Keyword.t()) ::
  t()
```

A column that contains 32-bit single-precision floats.

## Arguments

* `data`: A list of 32-bit single-precision float values. Integer values are automatically cast to floats.
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.f32([1.0, 2.0, 3.0])
    iex> col.field
    %Adbc.Field{name: nil, type: :f32}
    iex> Adbc.Column.to_list(col)
    [1.0, 2.0, 3.0]

# `f64`

```elixir
@spec f64([integer() | float() | nil | :infinity | :neg_infinity | :nan], Keyword.t()) ::
  t()
```

A column that contains 64-bit double-precision floats.

## Arguments

* `data`: A list of 64-bit double-precision float values. Integer values are automatically cast to floats.
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.f64([1.0, 2.0, 3.0])
    iex> col.field
    %Adbc.Field{name: nil, type: :f64}
    iex> Adbc.Column.to_list(col)
    [1.0, 2.0, 3.0]

# `fixed_size_binary`

```elixir
@spec fixed_size_binary([iodata() | nil], non_neg_integer(), Keyword.t()) :: t()
```

A column that contains fixed size binaries.

Similar to `binary/2`, but each binary value has the same fixed size in bytes.

## Arguments

* `data`: A list of binary values
* `nbytes`: The fixed size of the binary values in bytes
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.fixed_size_binary([<<0>>, <<1>>, <<2>>], 1)
    iex> col.field
    %Adbc.Field{name: nil, type: {:fixed_size_binary, 1}}
    iex> Adbc.Column.to_list(col)
    [<<0>>, <<1>>, <<2>>]

# `fixed_size_list`

```elixir
@spec fixed_size_list(list(), Adbc.Field.t(), s32(), Keyword.t()) :: t()
```

Similar to `list/3`, but the length of the list is the same.

## Arguments

* `data`: a list of lists (or `nil` for null rows)
* `inner_field`: an `Adbc.Field` describing the type of the list elements
* `fixed_size`: The fixed size of the list.
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `has_validity?`

```elixir
@spec has_validity?(t()) :: boolean()
```

Returns whether the column contains a validity bitmap (which would
indicate the presence of nils).

# `interval`

```elixir
@spec interval(
  [interval_month() | interval_day_time() | interval_month_day_nano() | nil],
  Adbc.Field.interval_unit(),
  Keyword.t()
) :: t()
```

A column that contains durations represented as signed integers.

## Arguments

* `data`: a list, each element of which can be one of the following:
  - if `unit` is `:month`:
    * a 32-bit signed integer representing the number of months.

  - if `unit` is `:day_time`:
    * a 2-tuple, both the number of days and the number of milliseconds are in 32-bit signed integers.

  - if `unit` is `:month_day_nano`:
    * a 3-tuple, the number of months, days, and nanoseconds;
      the number of months and days are in 32-bit signed integers,
      and the number of nanoseconds is in 64-bit signed integers

* `unit`: specify the unit of the time value, one of the following:
  * `:month`
  * `:day_time`
  * `:month_day_nano`

* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `large_binary`

```elixir
@spec large_binary([iodata() | nil], Keyword.t()) :: t()
```

A column that contains large binary values.

Similar to `binary/2`, but for binary values larger than 2GB.

## Arguments

* `data`: A list of binary values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.large_binary([<<0>>, <<1>>, <<2>>])
    iex> col.field
    %Adbc.Field{name: nil, type: :large_binary}
    iex> Adbc.Column.to_list(col)
    [<<0>>, <<1>>, <<2>>]

# `large_list`

```elixir
@spec large_list([t() | nil], Adbc.Field.t(), Keyword.t()) :: t()
```

Similar to `list/3`, but for large lists.

## Arguments

* `data`: a list of lists (or `nil` for null rows)
* `inner_field`: an `Adbc.Field` describing the type of the list elements
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `large_string`

```elixir
@spec large_string([String.t() | nil], Keyword.t()) :: t()
```

A column that contains UTF-8 encoded large strings.

Similar to `string/2`, but for strings larger than 2GB.

## Arguments

* `data`: A list of UTF-8 encoded string values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.large_string(["a", "ab", "abc"])
    iex> col.field
    %Adbc.Field{name: nil, type: :large_string}
    iex> Adbc.Column.to_list(col)
    ["a", "ab", "abc"]

# `list`

```elixir
@spec list([t() | nil], Adbc.Field.t(), Keyword.t()) :: t()
```

A column that each row is a list of some type or nil.

## Arguments

* `data`: a list of lists (or `nil` for null rows)
* `inner_field`: an `Adbc.Field` describing the type of the list elements
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `materialize`

> This function is deprecated. Adbc.Column.materialize/1 is no longer necessary, it is a noop..

```elixir
@spec materialize(t()) :: t()
```

# `new`

```elixir
@spec new(list(), Keyword.t()) :: t()
```

Creates a column by inferring the type from the data.

This is a higher-level API that traverses the data element by element,
inferring the most appropriate type.

## Type inference rules

  * `true` / `false` → `:boolean`
  * integers → `:s64`
  * floats, `:nan`, `:infinity`, `:neg_infinity` → `:f64`
    (integers in the same column are promoted to `:f64`)
  * binaries → `:string`
  * `%Date{}` → `:date32` (integers also supported)
  * `%Time{}` → `{:time64, :microseconds}` (integers representing microseconds also supported)
  * `%NaiveDateTime{}` → `{:timestamp, :microseconds, "UTC"}` (integers representing microseconds also supported)

If there are no values, the default type of `:string` is assumed.

## Options

  * `:name` - The name of the column

## Examples

    iex> col = Adbc.Column.new([1, 2, 3], name: "ids")
    iex> col.field
    %Adbc.Field{name: "ids", type: :s64}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

    iex> col = Adbc.Column.new([1, nil, 3.0])
    iex> col.field
    %Adbc.Field{name: nil, type: :f64}
    iex> Adbc.Column.to_list(col)
    [1.0, nil, 3.0]

# `s8`

```elixir
@spec s8([s8() | nil], Keyword.t()) :: t()
```

A column that contains signed 8-bit integers.

## Arguments

* `data`: A list of signed 8-bit integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.s8([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :s8}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

# `s16`

```elixir
@spec s16([s16() | nil], Keyword.t()) :: t()
```

A column that contains signed 16-bit integers.

## Arguments

* `data`: A list of signed 16-bit integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.s16([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :s16}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

# `s32`

```elixir
@spec s32([s32() | nil], Keyword.t()) :: t()
```

A column that contains 32-bit signed integers.

## Arguments

* `data`: A list of 32-bit signed integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.s32([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :s32}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

# `s64`

```elixir
@spec s64([s64() | nil], Keyword.t()) :: t()
```

A column that contains 64-bit signed integers.

## Arguments

* `data`: A list of 64-bit signed integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.s64([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :s64}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

# `string`

```elixir
@spec string([String.t() | nil], Keyword.t()) :: t()
```

A column that contains UTF-8 encoded strings.

## Arguments

* `data`: A list of UTF-8 encoded string values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.string(["a", "ab", "abc"])
    iex> col.field
    %Adbc.Field{name: nil, type: :string}
    iex> Adbc.Column.to_list(col)
    ["a", "ab", "abc"]

# `time`

```elixir
@spec time([Time.t() | s64() | nil], Adbc.Field.time_unit(), Keyword.t()) :: t()
```

A column that contains time represented as signed integers in UTC.

## Arguments

* `data`:
  * a list of `Time.t()` value
  * a list of integer values representing the time in the specified unit

    Note that when using `:seconds` or `:milliseconds` as the unit,
    the time value is limited to the range of 32-bit signed integers.

    For `:microseconds` and `:nanoseconds`, the time value is limited
    to the range of 64-bit signed integers.

* `unit`: specify the unit of the time value, one of the following:
  * `:seconds`
  * `:milliseconds`
  * `:microseconds`
  * `:nanoseconds`

* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `timestamp`

```elixir
@spec timestamp(
  [NaiveDateTime.t() | s64() | nil],
  Adbc.Field.time_unit(),
  String.t(),
  Keyword.t()
) :: t()
```

A column that contains timestamps represented as signed integers in the given timezone.

## Arguments

* `data`:
  * a list of `NaiveDateTime.t()` value
  * a list of 64-bit signed integer values representing the time in the specified unit

* `unit`: specify the unit of the time value, one of the following:
  * `:seconds`
  * `:milliseconds`
  * `:microseconds`
  * `:nanoseconds`

* `timezone`: the timezone of the timestamp

* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

# `to_binary`

```elixir
@spec to_binary(t()) :: binary()
```

Returns the column's data as a raw binary.

Supported types and their binary formats:

  * `:s8` / `:u8` / `:s16` / `:u16` / `:s32` / `:u32` / `:s64` / `:u64`
  * `:f16` / `:f32` / `:f64`
  * `:date32` - equivalent to `:s32`
  * `:date64` - equivalent to `:s64`
  * `{:time32, unit}` - equivalent to `:s32`
  * `{:time64, unit}` - equivalent to `:s64`
  * `{:timestamp, unit, tz}` - equivalent to `:s64`
  * `{:duration, unit}` - equivalent to `:s64`
  * `{:interval, :month}` - equivalent to `:s32`
  * `{:interval, :day_time}` - two `:s32` values per element (days, milliseconds)
  * `{:interval, :month_day_nano}` - `:s32` + `:s32` + `:s64` per element (months, days, nanoseconds)
  * `{:decimal128, precision, scale}` - 128-bit signed little-endian two's complement
  * `{:decimal256, precision, scale}` - 256-bit signed little-endian two's complement
  * `{:fixed_size_binary, n}` - `n` raw bytes per element
  * `{:dictionary, key_type, _}` - returns the key binary in the key's format

Raises `ArgumentError` for other data types.

# `to_list`

```elixir
@spec to_list(t()) :: [term()]
```

Converts a column's data to a plain Elixir list.

For primitive columns, returns the data as-is. For composite
types (dictionary, list, struct, list_view, run_end_encoded),
expands the data into its logical representation.

## Examples

    iex> Adbc.Column.s32([1, 2, 3]) |> Adbc.Column.to_list()
    [1, 2, 3]

    iex> col = Adbc.Column.dictionary(
    ...>   Adbc.Column.s32([0, 1, 0, 2]),
    ...>   Adbc.Column.string(["a", "b", "c"])
    ...> )
    iex> Adbc.Column.to_list(col)
    ["a", "b", "a", "c"]

# `u8`

```elixir
@spec u8([u8() | nil], Keyword.t()) :: t()
```

A column that contains unsigned 8-bit integers.

## Arguments

* `data`: A list of unsigned 8-bit integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.u8([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :u8}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

# `u16`

```elixir
@spec u16([u16() | nil], Keyword.t()) :: t()
```

A column that contains unsigned 16-bit integers.

## Arguments

* `data`: A list of unsigned 16-bit integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.u16([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :u16}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

# `u32`

```elixir
@spec u32([u32() | nil], Keyword.t()) :: t()
```

A column that contains un32-bit signed integers.

## Arguments

* `data`: A list of un32-bit signed integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.u32([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :u32}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

# `u64`

```elixir
@spec u64([u64() | nil], Keyword.t()) :: t()
```

A column that contains un64-bit signed integers.

## Arguments

* `data`: A list of un64-bit signed integer values
* `opts`: A keyword list of options

## Options

* `:name` - The name of the column
* `:metadata` - A map of metadata

## Examples

    iex> col = Adbc.Column.u64([1, 2, 3])
    iex> col.field
    %Adbc.Field{name: nil, type: :u64}
    iex> Adbc.Column.to_list(col)
    [1, 2, 3]

---

*Consult [api-reference.md](api-reference.md) for complete listing*
