Search Shortcut cmd + k | ctrl + k

- Installation
- Documentation

- Getting Started
- Connect

- Overview
- Concurrency

- Data Import

- Overview
- Data Sources
- CSV Files

- Overview
- Auto Detection
- Reading Faulty CSV Files
- Tips

- JSON Files

- Overview
- Creating JSON
- Loading JSON
- Writing JSON
- JSON Type
- JSON Functions
- Format Settings
- Installing and Loading
- SQL to / from JSON
- Caveats

- Multiple Files

- Overview
- Combining Schemas

- Parquet Files

- Overview
- Metadata
- Encryption
- Tips

- Partitioning

- Hive Partitioning
- Partitioned Writes

- Appender
- INSERT Statements

- Client APIs

- Overview
- C

- Overview
- Startup
- Configuration
- Query
- Data Chunks
- Vectors
- Values
- Types
- Prepared Statements
- Appender
- Table Functions
- Replacement Scans
- API Reference

- C++
- CLI

- Overview
- Arguments
- Dot Commands
- Output Formats
- Editing
- Autocomplete
- Syntax Highlighting

- Dart
- Go
- Java
- Julia
- Node.js (Neo)

- Overview

- Node.js

- Overview
- API Reference

- Python

- Overview
- Data Ingestion
- Conversion between DuckDB and Python
- DB API
- Relational API
- Function API
- Types API
- Expression API
- Spark API
- API Reference
- Known Python Issues

- R
- Rust
- Swift
- Wasm

- Overview
- Instantiation
- Data Ingestion
- Query
- Extensions

- ADBC
- ODBC

- Overview
- Linux Setup
- Windows Setup
- macOS Setup
- Configuration

- SQL

- Introduction
- Statements

- Overview
- ANALYZE
- ALTER TABLE
- ALTER VIEW
- ATTACH and DETACH
- CALL
- CHECKPOINT
- COMMENT ON
- COPY
- CREATE INDEX
- CREATE MACRO
- CREATE SCHEMA
- CREATE SECRET
- CREATE SEQUENCE
- CREATE TABLE
- CREATE VIEW
- CREATE TYPE
- DELETE
- DESCRIBE
- DROP
- EXPORT and IMPORT DATABASE
- INSERT
- LOAD / INSTALL
- PIVOT
- Profiling
- SELECT
- SET / RESET
- SET VARIABLE
- SUMMARIZE
- Transaction Management
- UNPIVOT
- UPDATE
- USE
- VACUUM

- Query Syntax

- SELECT
- FROM and JOIN
- WHERE
- GROUP BY
- GROUPING SETS
- HAVING
- ORDER BY
- LIMIT and OFFSET
- SAMPLE
- Unnesting
- WITH
- WINDOW
- QUALIFY
- VALUES
- FILTER
- Set Operations
- Prepared Statements

- Data Types

- Overview
- Array
- Bitstring
- Blob
- Boolean
- Date
- Enum
- Interval
- List
- Literal Types
- Map
- NULL Values
- Numeric
- Struct
- Text
- Time
- Timestamp
- Time Zones
- Union
- Typecasting

- Expressions

- Overview
- CASE Statement
- Casting
- Collations
- Comparisons
- IN Operator
- Logical Operators
- Star Expression
- Subqueries

- Functions

- Overview
- Aggregate Functions
- Array Functions
- Bitstring Functions
- Blob Functions
- Date Format Functions
- Date Functions
- Date Part Functions
- Enum Functions
- Interval Functions
- Lambda Functions
- List Functions
- Map Functions
- Nested Functions
- Numeric Functions
- Pattern Matching
- Regular Expressions
- Struct Functions
- Text Functions
- Time Functions
- Timestamp Functions
- Timestamp with Time Zone Functions
- Union Functions
- Utility Functions
- Window Functions

- Constraints
- Indexes
- Meta Queries

- Information Schema
- Metadata Functions

- DuckDB's SQL Dialect

- Overview
- Indexing
- Friendly SQL
- Keywords and Identifiers
- Order Preservation
- PostgreSQL Compatibility

- Samples

- Configuration

- Overview
- Pragmas
- Secrets Manager

- Extensions

- Overview
- Core Extensions
- Community Extensions
- Working with Extensions
- Versioning of Extensions
- Arrow
- AutoComplete
- AWS
- Azure
- Delta
- Excel
- Full Text Search
- httpfs (HTTP and S3)

- Overview
- HTTP(S) Support
- Hugging Face
- S3 API Support
- Legacy Authentication Scheme for S3 API

- Iceberg
- ICU
- inet
- jemalloc
- MySQL
- PostgreSQL
- Spatial

- Overview
- Function Reference
- R-Tree Indexes
- GDAL Integration

- SQLite
- Substrait
- TPC-DS
- TPC-H
- VSS

- Guides

- Overview
- Data Viewers

- Tableau
- CLI Charting with YouPlot

- Database Integration

- Overview
- MySQL Import
- PostgreSQL Import
- SQLite Import

- File Formats

- Overview
- CSV Import
- CSV Export
- Directly Reading Files
- Excel Import
- Excel Export
- JSON Import
- JSON Export
- Parquet Import
- Parquet Export
- Querying Parquet Files

- Network and Cloud Storage

- Overview
- HTTP Parquet Import
- S3 Parquet Import
- S3 Parquet Export
- S3 Iceberg Import
- S3 Express One
- GCS Import
- Cloudflare R2 Import
- DuckDB over HTTPS / S3

- Meta Queries

- Describe Table
- EXPLAIN: Inspect Query Plans
- EXPLAIN ANALYZE: Profile Queries
- List Tables
- Summarize
- DuckDB Environment

- ODBC

- ODBC Guide

- Performance

- Overview
- Environment
- Import
- Schema
- Indexing
- Join Operations
- File Formats
- How to Tune Workloads
- My Workload Is Slow
- Benchmarks

- Python

- Installation
- Executing SQL
- Jupyter Notebooks
- SQL on Pandas
- Import from Pandas
- Export to Pandas
- Import from Numpy
- Export to Numpy
- SQL on Arrow
- Import from Arrow
- Export to Arrow
- Relational API on Pandas
- Multiple Python Threads
- Integration with Ibis
- Integration with Polars
- Using fsspec Filesystems

- SQL Editors

- DBeaver SQL IDE

- SQL Features

- AsOf Join
- Full-Text Search
- query and query_table Functions

- Snippets

- Create Synthetic Data
- Sharing Macros

- Glossary of Terms
- Browse Offline

- Operations Manual

- Overview
- Limits
- Non-Deterministic Behavior
- Embedding DuckDB
- DuckDB's Footprint

- Files Created by DuckDB
- Gitignore for DuckDB
- Reclaiming Space

- Securing DuckDB

- Overview
- Securing Extensions

- Development

- DuckDB Repositories
- Testing

- Overview
- sqllogictest Introduction
- Writing Tests
- Debugging
- Result Verification
- Persistent Testing
- Loops
- Multiple Connections
- Catch

- Profiling
- Release Calendar
- Building

- Overview
- Build Instructions
- Build Configuration
- Building Extensions
- Platforms
- Troubleshooting

- Benchmark Suite

- Internals

- Overview
- Storage Versions and Format
- Execution Format
- Pivot

- Sitemap
- Why DuckDB
- Media
- FAQ
- Code of Conduct
- Live Demo

Types

DuckDB is a strongly typed database system. As such, every column has a single type specified. This type is constant over the entire column. That is to say, a column that is labeled as an `INTEGER` column will only contain `INTEGER` values.

DuckDB also supports columns of composite types. For example, it is possible to define an array of integers (`INTEGER[]`). It is also possible to define types as arbitrary structs (`ROW(i INTEGER, j VARCHAR)`). For that reason, native DuckDB type objects are not mere enums, but a class that can potentially be nested.

Types in the C API are modeled using an enum (`duckdb_type`) and a complex class (`duckdb_logical_type`). For most primitive types, e.g., integers or varchars, the enum is sufficient. For more complex types, such as lists, structs or decimals, the logical type must be used.

    typedef enum DUCKDB_TYPE {
      DUCKDB_TYPE_INVALID = 0,
      DUCKDB_TYPE_BOOLEAN = 1,
      DUCKDB_TYPE_TINYINT = 2,
      DUCKDB_TYPE_SMALLINT = 3,
      DUCKDB_TYPE_INTEGER = 4,
      DUCKDB_TYPE_BIGINT = 5,
      DUCKDB_TYPE_UTINYINT = 6,
      DUCKDB_TYPE_USMALLINT = 7,
      DUCKDB_TYPE_UINTEGER = 8,
      DUCKDB_TYPE_UBIGINT = 9,
      DUCKDB_TYPE_FLOAT = 10,
      DUCKDB_TYPE_DOUBLE = 11,
      DUCKDB_TYPE_TIMESTAMP = 12,
      DUCKDB_TYPE_DATE = 13,
      DUCKDB_TYPE_TIME = 14,
      DUCKDB_TYPE_INTERVAL = 15,
      DUCKDB_TYPE_HUGEINT = 16,
      DUCKDB_TYPE_UHUGEINT = 32,
      DUCKDB_TYPE_VARCHAR = 17,
      DUCKDB_TYPE_BLOB = 18,
      DUCKDB_TYPE_DECIMAL = 19,
      DUCKDB_TYPE_TIMESTAMP_S = 20,
      DUCKDB_TYPE_TIMESTAMP_MS = 21,
      DUCKDB_TYPE_TIMESTAMP_NS = 22,
      DUCKDB_TYPE_ENUM = 23,
      DUCKDB_TYPE_LIST = 24,
      DUCKDB_TYPE_STRUCT = 25,
      DUCKDB_TYPE_MAP = 26,
      DUCKDB_TYPE_ARRAY = 33,
      DUCKDB_TYPE_UUID = 27,
      DUCKDB_TYPE_UNION = 28,
      DUCKDB_TYPE_BIT = 29,
      DUCKDB_TYPE_TIME_TZ = 30,
      DUCKDB_TYPE_TIMESTAMP_TZ = 31,
    } duckdb_type;

## Functions

The enum type of a column in the result can be obtained using the `duckdb_column_type` function. The logical type of a column can be obtained using the `duckdb_column_logical_type` function.

### `duckdb_value`

The `duckdb_value` functions will auto-cast values as required. For example, it is no problem to use `duckdb_value_double` on a column of type `duckdb_value_int32`. The value will be auto-cast and returned as a double. Note that in certain cases the cast may fail. For example, this can happen if we request a `duckdb_value_int8` and the value does not fit within an `int8` value. In this case, a default value will be returned (usually `0` or `nullptr`). The same default value will also be returned if the corresponding value is `NULL`.

The `duckdb_value_is_null` function can be used to check if a specific value is `NULL` or not.

The exception to the auto-cast rule is the `duckdb_value_varchar_internal` function. This function does not auto-cast and only works for `VARCHAR` columns. The reason this function exists is that the result does not need to be freed.

> `duckdb_value_varchar` and `duckdb_value_blob` require the result to be de-allocated using `duckdb_free`.

### `duckdb_fetch_chunk`

The `duckdb_fetch_chunk` function can be used to read data chunks from a DuckDB result set, and is the most efficient way of reading data from a DuckDB result using the C API. It is also the only way of reading data of certain types from a DuckDB result. For example, the `duckdb_value` functions do not support structural reading of composite types (lists or structs) or more complex types like enums and decimals.

For more information about data chunks, see the documentation on data chunks.

## API Reference Overview

    duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_index);
    bool duckdb_result_is_streaming(duckdb_result result);
    idx_t duckdb_result_chunk_count(duckdb_result result);
    duckdb_result_type duckdb_result_return_type(duckdb_result result);

### Date Time Timestamp Helpers

    duckdb_date_struct duckdb_from_date(duckdb_date date);
    duckdb_date duckdb_to_date(duckdb_date_struct date);
    bool duckdb_is_finite_date(duckdb_date date);
    duckdb_time_struct duckdb_from_time(duckdb_time time);
    duckdb_time_tz duckdb_create_time_tz(int64_t micros, int32_t offset);
    duckdb_time_tz_struct duckdb_from_time_tz(duckdb_time_tz micros);
    duckdb_time duckdb_to_time(duckdb_time_struct time);
    duckdb_timestamp_struct duckdb_from_timestamp(duckdb_timestamp ts);
    duckdb_timestamp duckdb_to_timestamp(duckdb_timestamp_struct ts);
    bool duckdb_is_finite_timestamp(duckdb_timestamp ts);

### Hugeint Helpers

    double duckdb_hugeint_to_double(duckdb_hugeint val);
    duckdb_hugeint duckdb_double_to_hugeint(double val);

### Decimal Helpers

    duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale);
    double duckdb_decimal_to_double(duckdb_decimal val);

### Logical Type Interface

    duckdb_logical_type duckdb_create_logical_type(duckdb_type type);
    char *duckdb_logical_type_get_alias(duckdb_logical_type type);
    void duckdb_logical_type_set_alias(duckdb_logical_type type, const char *alias);
    duckdb_logical_type duckdb_create_list_type(duckdb_logical_type type);
    duckdb_logical_type duckdb_create_array_type(duckdb_logical_type type, idx_t array_size);
    duckdb_logical_type duckdb_create_map_type(duckdb_logical_type key_type, duckdb_logical_type value_type);
    duckdb_logical_type duckdb_create_union_type(duckdb_logical_type *member_types, const char **member_names, idx_t member_count);
    duckdb_logical_type duckdb_create_struct_type(duckdb_logical_type *member_types, const char **member_names, idx_t member_count);
    duckdb_logical_type duckdb_create_enum_type(const char **member_names, idx_t member_count);
    duckdb_logical_type duckdb_create_decimal_type(uint8_t width, uint8_t scale);
    duckdb_type duckdb_get_type_id(duckdb_logical_type type);
    uint8_t duckdb_decimal_width(duckdb_logical_type type);
    uint8_t duckdb_decimal_scale(duckdb_logical_type type);
    duckdb_type duckdb_decimal_internal_type(duckdb_logical_type type);
    duckdb_type duckdb_enum_internal_type(duckdb_logical_type type);
    uint32_t duckdb_enum_dictionary_size(duckdb_logical_type type);
    char *duckdb_enum_dictionary_value(duckdb_logical_type type, idx_t index);
    duckdb_logical_type duckdb_list_type_child_type(duckdb_logical_type type);
    duckdb_logical_type duckdb_array_type_child_type(duckdb_logical_type type);
    idx_t duckdb_array_type_array_size(duckdb_logical_type type);
    duckdb_logical_type duckdb_map_type_key_type(duckdb_logical_type type);
    duckdb_logical_type duckdb_map_type_value_type(duckdb_logical_type type);
    idx_t duckdb_struct_type_child_count(duckdb_logical_type type);
    char *duckdb_struct_type_child_name(duckdb_logical_type type, idx_t index);
    duckdb_logical_type duckdb_struct_type_child_type(duckdb_logical_type type, idx_t index);
    idx_t duckdb_union_type_member_count(duckdb_logical_type type);
    char *duckdb_union_type_member_name(duckdb_logical_type type, idx_t index);
    duckdb_logical_type duckdb_union_type_member_type(duckdb_logical_type type, idx_t index);
    void duckdb_destroy_logical_type(duckdb_logical_type *type);
    duckdb_state duckdb_register_logical_type(duckdb_connection con, duckdb_logical_type type, duckdb_create_type_info info);

#### `duckdb_result_get_chunk`

> Warning Deprecation notice. This method is scheduled for removal in a future release.

Fetches a data chunk from the duckdb_result. This function should be called repeatedly until the result is exhausted.

The result must be destroyed with `duckdb_destroy_data_chunk`.

This function supersedes all `duckdb_value` functions, as well as the `duckdb_column_data` and `duckdb_nullmask_data` functions. It results in significantly better performance, and should be preferred in newer code-bases.

If this function is used, none of the other result functions can be used and vice versa (i.e., this function cannot be mixed with the legacy result functions).

Use `duckdb_result_chunk_count` to figure out how many chunks there are in the result.

##### Syntax

    duckdb_data_chunk duckdb_result_get_chunk(
      duckdb_result result,
      idx_t chunk_index
    );

##### Parameters

- `result`: The result object to fetch the data chunk from.
- `chunk_index`: The chunk index to fetch from.

##### Return Value

The resulting data chunk. Returns `NULL` if the chunk index is out of bounds.

#### `duckdb_result_is_streaming`

> Warning Deprecation notice. This method is scheduled for removal in a future release.

Checks if the type of the internal result is StreamQueryResult.

##### Syntax

    bool duckdb_result_is_streaming(
      duckdb_result result
    );

##### Parameters

- `result`: The result object to check.

##### Return Value

Whether or not the result object is of the type StreamQueryResult

#### `duckdb_result_chunk_count`

> Warning Deprecation notice. This method is scheduled for removal in a future release.

Returns the number of data chunks present in the result.

##### Syntax

    idx_t duckdb_result_chunk_count(
      duckdb_result result
    );

##### Parameters

- `result`: The result object

##### Return Value

Number of data chunks present in the result.

#### `duckdb_result_return_type`

Returns the return_type of the given result, or DUCKDB_RETURN_TYPE_INVALID on error

##### Syntax

    duckdb_result_type duckdb_result_return_type(
      duckdb_result result
    );

##### Parameters

- `result`: The result object

##### Return Value

The return_type

#### `duckdb_from_date`

Decompose a `duckdb_date` object into year, month and date (stored as `duckdb_date_struct`).

##### Syntax

    duckdb_date_struct duckdb_from_date(
      duckdb_date date
    );

##### Parameters

- `date`: The date object, as obtained from a `DUCKDB_TYPE_DATE` column.

##### Return Value

The `duckdb_date_struct` with the decomposed elements.

#### `duckdb_to_date`

Re-compose a `duckdb_date` from year, month and date (`duckdb_date_struct`).

##### Syntax

    duckdb_date duckdb_to_date(
      duckdb_date_struct date
    );

##### Parameters

- `date`: The year, month and date stored in a `duckdb_date_struct`.

##### Return Value

The `duckdb_date` element.

#### `duckdb_is_finite_date`

Test a `duckdb_date` to see if it is a finite value.

##### Syntax

    bool duckdb_is_finite_date(
      duckdb_date date
    );

##### Parameters

- `date`: The date object, as obtained from a `DUCKDB_TYPE_DATE` column.

##### Return Value

True if the date is finite, false if it is ±infinity.

#### `duckdb_from_time`

Decompose a `duckdb_time` object into hour, minute, second and microsecond (stored as `duckdb_time_struct`).

##### Syntax

    duckdb_time_struct duckdb_from_time(
      duckdb_time time
    );

##### Parameters

- `time`: The time object, as obtained from a `DUCKDB_TYPE_TIME` column.

##### Return Value

The `duckdb_time_struct` with the decomposed elements.

#### `duckdb_create_time_tz`

Create a `duckdb_time_tz` object from micros and a timezone offset.

##### Syntax

    duckdb_time_tz duckdb_create_time_tz(
      int64_t micros,
      int32_t offset
    );

##### Parameters

- `micros`: The microsecond component of the time.
- `offset`: The timezone offset component of the time.

##### Return Value

The `duckdb_time_tz` element.

#### `duckdb_from_time_tz`

Decompose a TIME_TZ objects into micros and a timezone offset.

Use `duckdb_from_time` to further decompose the micros into hour, minute, second and microsecond.

##### Syntax

    duckdb_time_tz_struct duckdb_from_time_tz(
      duckdb_time_tz micros
    );

##### Parameters

- `micros`: The time object, as obtained from a `DUCKDB_TYPE_TIME_TZ` column.

#### `duckdb_to_time`

Re-compose a `duckdb_time` from hour, minute, second and microsecond (`duckdb_time_struct`).

##### Syntax

    duckdb_time duckdb_to_time(
      duckdb_time_struct time
    );

##### Parameters

- `time`: The hour, minute, second and microsecond in a `duckdb_time_struct`.

##### Return Value

The `duckdb_time` element.

#### `duckdb_from_timestamp`

Decompose a `duckdb_timestamp` object into a `duckdb_timestamp_struct`.

##### Syntax

    duckdb_timestamp_struct duckdb_from_timestamp(
      duckdb_timestamp ts
    );

##### Parameters

- `ts`: The ts object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column.

##### Return Value

The `duckdb_timestamp_struct` with the decomposed elements.

#### `duckdb_to_timestamp`

Re-compose a `duckdb_timestamp` from a duckdb_timestamp_struct.

##### Syntax

    duckdb_timestamp duckdb_to_timestamp(
      duckdb_timestamp_struct ts
    );

##### Parameters

- `ts`: The de-composed elements in a `duckdb_timestamp_struct`.

##### Return Value

The `duckdb_timestamp` element.

#### `duckdb_is_finite_timestamp`

Test a `duckdb_timestamp` to see if it is a finite value.

##### Syntax

    bool duckdb_is_finite_timestamp(
      duckdb_timestamp ts
    );

##### Parameters

- `ts`: The timestamp object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column.

##### Return Value

True if the timestamp is finite, false if it is ±infinity.

#### `duckdb_hugeint_to_double`

Converts a duckdb_hugeint object (as obtained from a `DUCKDB_TYPE_HUGEINT` column) into a double.

##### Syntax

    double duckdb_hugeint_to_double(
      duckdb_hugeint val
    );

##### Parameters

- `val`: The hugeint value.

##### Return Value

The converted `double` element.

#### `duckdb_double_to_hugeint`

Converts a double value to a duckdb_hugeint object.

If the conversion fails because the double value is too big the result will be 0.

##### Syntax

    duckdb_hugeint duckdb_double_to_hugeint(
      double val
    );

##### Parameters

- `val`: The double value.

##### Return Value

The converted `duckdb_hugeint` element.

#### `duckdb_double_to_decimal`

Converts a double value to a duckdb_decimal object.

If the conversion fails because the double value is too big, or the width/scale are invalid the result will be 0.

##### Syntax

    duckdb_decimal duckdb_double_to_decimal(
      double val,
      uint8_t width,
      uint8_t scale
    );

##### Parameters

- `val`: The double value.

##### Return Value

The converted `duckdb_decimal` element.

#### `duckdb_decimal_to_double`

Converts a duckdb_decimal object (as obtained from a `DUCKDB_TYPE_DECIMAL` column) into a double.

##### Syntax

    double duckdb_decimal_to_double(
      duckdb_decimal val
    );

##### Parameters

- `val`: The decimal value.

##### Return Value

The converted `double` element.

#### `duckdb_create_logical_type`

Creates a `duckdb_logical_type` from a primitive type. The resulting logical type must be destroyed with `duckdb_destroy_logical_type`.

Returns an invalid logical type, if type is: `DUCKDB_TYPE_INVALID`, `DUCKDB_TYPE_DECIMAL`, `DUCKDB_TYPE_ENUM`, `DUCKDB_TYPE_LIST`, `DUCKDB_TYPE_STRUCT`, `DUCKDB_TYPE_MAP`, `DUCKDB_TYPE_ARRAY`, or `DUCKDB_TYPE_UNION`.

##### Syntax

    duckdb_logical_type duckdb_create_logical_type(
      duckdb_type type
    );

##### Parameters

- `type`: The primitive type to create.

##### Return Value

The logical type.

#### `duckdb_logical_type_get_alias`

Returns the alias of a duckdb_logical_type, if set, else `nullptr`. The result must be destroyed with `duckdb_free`.

##### Syntax

    char *duckdb_logical_type_get_alias(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type

##### Return Value

The alias or `nullptr`

#### `duckdb_logical_type_set_alias`

Sets the alias of a duckdb_logical_type.

##### Syntax

    void duckdb_logical_type_set_alias(
      duckdb_logical_type type,
      const char *alias
    );

##### Parameters

- `type`: The logical type
- `alias`: The alias to set

#### `duckdb_create_list_type`

Creates a LIST type from its child type. The return type must be destroyed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_create_list_type(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The child type of the list

##### Return Value

The logical type.

#### `duckdb_create_array_type`

Creates an ARRAY type from its child type. The return type must be destroyed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_create_array_type(
      duckdb_logical_type type,
      idx_t array_size
    );

##### Parameters

- `type`: The child type of the array.
- `array_size`: The number of elements in the array.

##### Return Value

The logical type.

#### `duckdb_create_map_type`

Creates a MAP type from its key type and value type. The return type must be destroyed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_create_map_type(
      duckdb_logical_type key_type,
      duckdb_logical_type value_type
    );

##### Parameters

- `key_type`: The map's key type.
- `value_type`: The map's value type.

##### Return Value

The logical type.

#### `duckdb_create_union_type`

Creates a UNION type from the passed arrays. The return type must be destroyed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_create_union_type(
      duckdb_logical_type *member_types,
      const char **member_names,
      idx_t member_count
    );

##### Parameters

- `member_types`: The array of union member types.
- `member_names`: The union member names.
- `member_count`: The number of union members.

##### Return Value

The logical type.

#### `duckdb_create_struct_type`

Creates a STRUCT type based on the member types and names. The resulting type must be destroyed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_create_struct_type(
      duckdb_logical_type *member_types,
      const char **member_names,
      idx_t member_count
    );

##### Parameters

- `member_types`: The array of types of the struct members.
- `member_names`: The array of names of the struct members.
- `member_count`: The number of members of the struct.

##### Return Value

The logical type.

#### `duckdb_create_enum_type`

Creates an ENUM type from the passed member name array. The resulting type should be destroyed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_create_enum_type(
      const char **member_names,
      idx_t member_count
    );

##### Parameters

- `member_names`: The array of names that the enum should consist of.
- `member_count`: The number of elements that were specified in the array.

##### Return Value

The logical type.

#### `duckdb_create_decimal_type`

Creates a DECIMAL type with the specified width and scale. The resulting type should be destroyed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_create_decimal_type(
      uint8_t width,
      uint8_t scale
    );

##### Parameters

- `width`: The width of the decimal type
- `scale`: The scale of the decimal type

##### Return Value

The logical type.

#### `duckdb_get_type_id`

Retrieves the enum `duckdb_type` of a `duckdb_logical_type`.

##### Syntax

    duckdb_type duckdb_get_type_id(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type.

##### Return Value

The `duckdb_type` id.

#### `duckdb_decimal_width`

Retrieves the width of a decimal type.

##### Syntax

    uint8_t duckdb_decimal_width(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The width of the decimal type

#### `duckdb_decimal_scale`

Retrieves the scale of a decimal type.

##### Syntax

    uint8_t duckdb_decimal_scale(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The scale of the decimal type

#### `duckdb_decimal_internal_type`

Retrieves the internal storage type of a decimal type.

##### Syntax

    duckdb_type duckdb_decimal_internal_type(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The internal type of the decimal type

#### `duckdb_enum_internal_type`

Retrieves the internal storage type of an enum type.

##### Syntax

    duckdb_type duckdb_enum_internal_type(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The internal type of the enum type

#### `duckdb_enum_dictionary_size`

Retrieves the dictionary size of the enum type.

##### Syntax

    uint32_t duckdb_enum_dictionary_size(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The dictionary size of the enum type

#### `duckdb_enum_dictionary_value`

Retrieves the dictionary value at the specified position from the enum.

The result must be freed with `duckdb_free`.

##### Syntax

    char *duckdb_enum_dictionary_value(
      duckdb_logical_type type,
      idx_t index
    );

##### Parameters

- `type`: The logical type object
- `index`: The index in the dictionary

##### Return Value

The string value of the enum type. Must be freed with `duckdb_free`.

#### `duckdb_list_type_child_type`

Retrieves the child type of the given LIST type. Also accepts MAP types. The result must be freed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_list_type_child_type(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type, either LIST or MAP.

##### Return Value

The child type of the LIST or MAP type.

#### `duckdb_array_type_child_type`

Retrieves the child type of the given ARRAY type.

The result must be freed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_array_type_child_type(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type. Must be ARRAY.

##### Return Value

The child type of the ARRAY type.

#### `duckdb_array_type_array_size`

Retrieves the array size of the given array type.

##### Syntax

    idx_t duckdb_array_type_array_size(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The fixed number of elements the values of this array type can store.

#### `duckdb_map_type_key_type`

Retrieves the key type of the given map type.

The result must be freed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_map_type_key_type(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The key type of the map type. Must be destroyed with `duckdb_destroy_logical_type`.

#### `duckdb_map_type_value_type`

Retrieves the value type of the given map type.

The result must be freed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_map_type_value_type(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The value type of the map type. Must be destroyed with `duckdb_destroy_logical_type`.

#### `duckdb_struct_type_child_count`

Returns the number of children of a struct type.

##### Syntax

    idx_t duckdb_struct_type_child_count(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type object

##### Return Value

The number of children of a struct type.

#### `duckdb_struct_type_child_name`

Retrieves the name of the struct child.

The result must be freed with `duckdb_free`.

##### Syntax

    char *duckdb_struct_type_child_name(
      duckdb_logical_type type,
      idx_t index
    );

##### Parameters

- `type`: The logical type object
- `index`: The child index

##### Return Value

The name of the struct type. Must be freed with `duckdb_free`.

#### `duckdb_struct_type_child_type`

Retrieves the child type of the given struct type at the specified index.

The result must be freed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_struct_type_child_type(
      duckdb_logical_type type,
      idx_t index
    );

##### Parameters

- `type`: The logical type object
- `index`: The child index

##### Return Value

The child type of the struct type. Must be destroyed with `duckdb_destroy_logical_type`.

#### `duckdb_union_type_member_count`

Returns the number of members that the union type has.

##### Syntax

    idx_t duckdb_union_type_member_count(
      duckdb_logical_type type
    );

##### Parameters

- `type`: The logical type (union) object

##### Return Value

The number of members of a union type.

#### `duckdb_union_type_member_name`

Retrieves the name of the union member.

The result must be freed with `duckdb_free`.

##### Syntax

    char *duckdb_union_type_member_name(
      duckdb_logical_type type,
      idx_t index
    );

##### Parameters

- `type`: The logical type object
- `index`: The child index

##### Return Value

The name of the union member. Must be freed with `duckdb_free`.

#### `duckdb_union_type_member_type`

Retrieves the child type of the given union member at the specified index.

The result must be freed with `duckdb_destroy_logical_type`.

##### Syntax

    duckdb_logical_type duckdb_union_type_member_type(
      duckdb_logical_type type,
      idx_t index
    );

##### Parameters

- `type`: The logical type object
- `index`: The child index

##### Return Value

The child type of the union member. Must be destroyed with `duckdb_destroy_logical_type`.

#### `duckdb_destroy_logical_type`

Destroys the logical type and de-allocates all memory allocated for that type.

##### Syntax

    void duckdb_destroy_logical_type(
      duckdb_logical_type *type
    );

##### Parameters

- `type`: The logical type to destroy.

#### `duckdb_register_logical_type`

Registers a custom type within the given connection. The type must have an alias

##### Syntax

    duckdb_state duckdb_register_logical_type(
      duckdb_connection con,
      duckdb_logical_type type,
      duckdb_create_type_info info
    );

##### Parameters

- `con`: The connection to use
- `type`: The custom type to register

##### Return Value

Whether or not the registration was successful.

##### About this page

- Report content issue
- Edit this page on GitHub