4.1. Functions #

By default, pgpro_axe functions are installed into the public schema. Currently, ALTER EXTENSION cannot move pgpro_axe to a different schema.

4.1.1. Functions for Reading OLAP Data from a Storage #

read_parquet(path TEXT or TEXT[], optional_parameters) returns SETOF duckdb.row #

Reads a Parquet file from a storage.

Returns DuckDB rows. You can expand these rows using * or select specific columns using the r['column_name'] syntax. To select specific columns, give the function call an easy alias, such as r:

Example 4.1. 

  SELECT * FROM read_parquet('file.parquet');
  SELECT r['id'], r['name'] FROM read_parquet('file.parquet') r WHERE r['age'] > 21;
  SELECT COUNT(*) FROM read_parquet('file.parquet');

Required parameters:

Name

Type

Description

path

text or text[]

The path to the storage with Parquet files to read. It can be a glob or array of files.

Optional parameters mirror the DuckDB read_parquet function. To specify optional parameters, use parameter := 'value'.

read_csv(path TEXT or TEXT[], optional_parameters) returns SETOF duckdb.row #

Reads a CSV file from a storage.

Returns DuckDB rows. You can expand these rows using * or select specific columns using the r['column_name'] syntax. To select specific columns, give the function call an easy alias, such as r:

Example 4.2. 

SELECT * FROM read_csv('file.csv');
SELECT r['id'], r['name'] FROM read_csv('file.csv') r WHERE r['age'] > 21;
SELECT COUNT(*) FROM read_csv('file.csv');

Required parameters:

Name

Type

Description

path

text or text[]

The path to the storage with CSV files to read. It can be a glob or array of files.

Optional parameters mirror the DuckDB read_csv function. To specify optional parameters, use parameter := 'value'.

Note

  • columns is not currently supported

  • nullstr must be an array (TEXT[])

read_json(path TEXT or TEXT[], optional_parameters) returns SETOF duckdb.row #

Reads a JSON file from a storage.

Returns DuckDB rows. You can expand these rows using * or select specific columns using the r['column_name'] syntax. To select specific columns, give the function call an easy alias, such as r:

Example 4.3. 

  SELECT * FROM read_parquet('file.parquet');
  SELECT r['id'], r['name'] FROM read_parquet('file.parquet') r WHERE r['age'] > 21;
  SELECT COUNT(*) FROM read_parquet('file.parquet');

Required parameters:

Name

Type

Description

path

text or text[]

The path to the storage with JSON files to read. It can be a glob or array of files.

Optional parameters mirror the DuckDB read_json function. To specify optional parameters, use parameter := 'value'.

Note

columns is not currently supported.

iceberg_scan(path TEXT, optional_parameters) returns SETOF duckdb.row #

Reads an iceberg table from a storage.

Returns DuckDB rows. You can expand these rows using * or select specific columns using the r['column_name'] syntax. To select specific columns, give the function call an easy alias, such as r:

Example 4.4. 

SELECT * FROM iceberg_scan('data/iceberg/table');
SELECT r['id'], r['name'] FROM iceberg_scan('data/iceberg/table') r WHERE r['age'] > 21;
SELECT COUNT(*) FROM iceberg_scan('data/iceberg/table');

To use iceberg_scan, enable the iceberg extension:

SELECT duckdb.install_extension('iceberg');

Required parameters:

Name

Type

Description

path

text

The path to the storage with the iceberg table to read.

Optional parameters mirror the DuckDB iceberg_scan function. To specify optional parameters, use parameter := 'value'.

Optional parameters:

Name

Type

Default value

Description

allowed_moved_paths

boolean

false

Ensures that path resolution is performed, which allows scanning iceberg tables that are moved.

mode

text

''

metadata_compression_codec

text

'none'

skip_schema_inference

boolean

false

version

text

'version-hint.text'

version_name_format

text

'v%s%s.metadata.json,%s%s.metadata.json'

iceberg_metadata(path TEXT, optional_parameters) returns SETOF iceberg_metadata_record #

To use iceberg_metadata, enable the iceberg extension:

SELECT duckdb.install_extension('iceberg');

Required parameters:

Name

Type

Description

path

text

The path to the storage with the iceberg table to read.

Optional parameters mirror the DuckDB iceberg_metadata function. To specify optional parameters, use parameter := 'value'.

Optional parameters:

Name

Type

Default value

Description

allowed_moved_paths

boolean

false

Ensures that path resolution is performed, which allows scanning iceberg tables that are moved.

metadata_compression_codec

text

'none'

skip_schema_inference

boolean

false

version

text

'version-hint.text'

version_name_format

text

'v%s%s.metadata.json,%s%s.metadata.json'

iceberg_snapshots (path TEXT, optional_parameters) returns SETOF iceberg_snapshot_record #

Reads snapshot information from an iceberg table.

Returns snapshot metadata for an iceberg table, which can be useful for "time travel" queries and understanding table history.

Example 4.5. 

SELECT * FROM iceberg_snapshots('data/iceberg/table');

To use iceberg_snapshots, enable the iceberg extension:

SELECT duckdb.install_extension('iceberg');

Required parameters:

Name

Type

Description

path

text

The path to the storage with the iceberg table to read.

Optional parameters mirror the DuckDB iceberg_snapshots function. To specify optional parameters, use parameter := 'value'.

Optional parameters:

Name

Type

Default value

metadata_compression_codec

text

'none'

skip_schema_inference

boolean

false

version

text

'version-hint.text'

version_name_format

text

'v%s%s.metadata.json,%s%s.metadata.json'

delta_scan(path TEXT) returns SETOF duckdb.row #

Reads a Delta dataset from a storage.

Returns DuckDB rows. You can expand these rows using * or select specific columns using the r['column_name'] syntax. To select specific columns, give the function call an easy alias, such as r:

Example 4.6. 

SELECT * FROM delta_scan('/path/to/delta/dataset');
SELECT r['id'], r['name'] FROM delta_scan('/path/to/delta/dataset') r WHERE r['age'] > 21;
SELECT COUNT(*) FROM delta_scan('/path/to/delta/dataset');

To use delta_scan, enable the delta extension:

SELECT duckdb.install_extension('delta');

Required parameters:

Name

Type

Description

path

text

The path to the storage with the Delta dataset to read.

4.1.2. JSON Functions #

pgpro_axe supports all DuckDB JSON functions and aggregates. Postgres Pro JSON/JSONB functions are not supported.

4.1.3. Union Type Functions #

union_extract(union_col, tag) returns duckdb.unresolved_type #

Extracts a value from a union type by specifying the tag name of the member to access.

Example 4.7. 

-- Extract the string value if the union contains a string
SELECT union_extract(my_union_column, 'string') FROM my_table;

-- Extract integer value from union
SELECT union_extract(data_field, 'integer') AS extracted_int FROM mixed_data;

Required parameters:

Name

Type

Description

union_col

duckdb.union or duckdb.unresolved_type

The union column from which to extract a value

tag

text

The tag name of the union member to extract

union_tag(union_col) returns duckdb.unresolved_type #

Returns the tag name of the currently active member in a union type.

Example 4.8. 

-- Get the active tag for each row
SELECT union_tag(my_union_column) AS active_type FROM my_table;

-- Filter rows based on union tag
SELECT * FROM my_table WHERE union_tag(data_field) = 'string';

Required parameters:

Name

Type

Description

union_col

duckdb.union or duckdb.unresolved_type

The union column from which to get the tag

4.1.4. MAP Functions #

cardinality(map_col duckdb.map) returns numeric #

Returns the size of a map (the number of key-value pairs).

Example 4.9. 

-- Get the number of entries in a map
SELECT cardinality(r['map_col']) as size
FROM duckdb.query($$ SELECT MAP(['a', 'b', 'c'], [1, 2, 3]) as map_col $$) r;
-- Returns: 3

-- Empty map
SELECT cardinality(r['map_col']) as size
FROM duckdb.query($$ SELECT MAP([], []) as map_col $$) r;
-- Returns: 0

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map, the size of which to return

element_at(map_col duckdb.map, key duckdb.unresolved_type) returns duckdb.unresolved_type #

Returns the value for a given key as an array.

Example 4.10. 

-- Get value for a specific key
SELECT element_at(r['map_col'], 'a') as value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: {1}

-- Non-existent key
SELECT element_at(r['map_col'], 'c') as value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: {}

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map from which to extract a value

key

duckdb.unresolved_type

The key for which to extract a value

map_concat(map_col duckdb.map, map_col2 duckdb.map) returns duckdb.map #

Merges two maps. On key collision, the value is taken from the last map.

Example 4.11. 

-- Merge two maps
SELECT map_concat(r1['map1'], r2['map2']) as merged
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map1 $$) r1,
     duckdb.query($$ SELECT MAP(['b', 'c'], [3, 4]) as map2 $$) r2;
-- Returns: {a=1, b=3, c=4}

-- Note: 'b' value from map2 (3) overwrites map1's value (2)

Required parameters:

Name

Type

Description

map_col

duckdb.map

The first map to merge

map_col2

duckdb.map

The second map to merge

map_contains(map_col duckdb.map, key duckdb.unresolved_type) returns boolean #

Checks whether a map contains a given key.

Example 4.12. 

-- Check if key exists
SELECT map_contains(r['map_col'], 'a') as has_key
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: t (true)

-- Check for non-existent key
SELECT map_contains(r['map_col'], 'c') as has_key
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: f (false)

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map where to check a key

key

duckdb.unresolved_type

The key to check

map_contains_entry(map_col duckdb.map, key duckdb.unresolved_type, value duckdb.unresolved_type) boolean #

Checks whether a map contains a given key-value pair.

Example 4.13. 

-- Check if key-value pair exists
SELECT map_contains_entry(r['map_col'], 'a', 1) as has_entry
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: t (true)

-- Check with wrong value for existing key
SELECT map_contains_entry(r['map_col'], 'a', 2) as has_entry
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: f (false)

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map where to check a key-value pair

key

duckdb.unresolved_type

The key to check

value

duckdb.unresolved_type

The value to check

map_contains_value(map_col duckdb.map, value duckdb.unresolved_type) returns boolean #

Checks whether a map contains the specified value.

Example 4.14. 

-- Check if value exists
SELECT map_contains_value(r['map_col'], 1) as has_value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: t (true)

-- Check for non-existent value
SELECT map_contains_value(r['map_col'], 3) as has_value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: f (false)

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map where to check a value

value

duckdb.unresolved_type

The value to check

map_entries(map_col duckdb.map) returns duckdb.struct[] #

Returns an array of structs (key, value) for each key-value pair in the map.

Example 4.15. 

-- Get all key-value pairs as structs
SELECT map_entries(r['map_col']) as entries
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: {"(a,1)","(b,2)"}

-- Access individual struct fields
SELECT unnest(map_entries(r['map_col'])) as entry
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map from which to extract arrays of structs

map_extract(map_col duckdb.map, key duckdb.unresolved_type) returns duckdb.unresolved_type #

Extracts a value from a map using the specified key. If the key does not exist, returns an empty array.

Example 4.16. 

-- Extract value from a map
SELECT map_extract(r['map_col'], 'a') as value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: {1}

-- Extract non-existent key
SELECT map_extract(r['map_col'], 'c') as value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: {}

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map from which to extract a value

key

duckdb.unresolved_type

The key to use for extracting a value

map_extract_value(map_col duckdb.map, key duckdb.unresolved_type) returns duckdb.unresolved_type #

Returns a value for the specified key or NULL if the key is not contained in the map.

Example 4.17. 

-- Extract single value (not as array)
SELECT map_extract_value(r['map_col'], 'a') as value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: 1

-- Non-existent key returns NULL
SELECT map_extract_value(r['map_col'], 'c') as value
FROM duckdb.query($$ SELECT MAP(['a', 'b'], [1, 2]) as map_col $$) r;
-- Returns: NULL

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map from which to extract a value

key

duckdb.unresolved_type

The key for which to extract a value

map_from_entries(entries duckdb.struct[]) returns duckdb.map #

Creates a map from an array of structs (k, v).

Example 4.18. 

-- Create map from array of structs
SELECT map_from_entries(r['entries']) as new_map
FROM duckdb.query($$
    SELECT [{'k': 'a', 'v': 1}, {'k': 'b', 'v': 2}] as entries
$$) r;
-- Returns: {a=1, b=2}

-- This is the inverse operation of map_entries
SELECT map_from_entries(map_entries(r['map_col'])) as reconstructed
FROM duckdb.query($$ SELECT MAP(['x', 'y'], [10, 20]) as map_col $$) r;
-- Returns: {x=10, y=20}

Required parameters:

Name

Type

Description

entries

duckdb.struct[]

Array of structs with 'k' (key) and 'v' (value) fields

map_keys(map_col duckdb.map) returns duckdb.unresolved_type #

Returns all keys from a map as an array.

Example 4.19. 

-- Get all keys from a map
SELECT map_keys(r['map_col']) as keys
FROM duckdb.query($$ SELECT MAP(['a', 'b', 'c'], [1, 2, 3]) as map_col $$) r;
-- Returns: {a,b,c}

-- Empty map
SELECT map_keys(r['map_col']) as keys
FROM duckdb.query($$ SELECT MAP([], []) as map_col $$) r;
-- Returns: {}

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map from which to extract keys

map_values(map_col duckdb.map) returns duckdb.unresolved_type #

Returns all values from a map as an array.

Example 4.20. 

-- Get all values from a map
SELECT map_values(r['map_col']) as values
FROM duckdb.query($$ SELECT MAP(['a', 'b', 'c'], [1, 2, 3]) as map_col $$) r;
-- Returns: {1,2,3}

-- Empty map
SELECT map_values(r['map_col']) as values
FROM duckdb.query($$ SELECT MAP([], []) as map_col $$) r;
-- Returns: {}

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map from which to extract values

4.1.5. Aggregates Functions #

approx_count_distinct(expression) returns BIGINT #

Approximates the count of distinct elements using the HyperLogLog algorithm. This is much faster than COUNT(DISTINCT ...) for large datasets, with a small error rate.

Example 4.21. 

-- Approximate distinct count of customer IDs
SELECT approx_count_distinct(customer_id) FROM orders;

-- Compare with exact count
SELECT
    approx_count_distinct(customer_id) AS approx_distinct,
    COUNT(DISTINCT customer_id) AS exact_distinct
FROM orders;

Required parameters:

Name

Type

Description

expression

any

The expression for which to count distinct values

4.1.6. Sampling Functions #

TABLESAMPLE (sampling_method(percentage | rows)) #

Samples a subset of rows from an analytical table or query result. This is useful for analyzing large datasets by working with representative samples, improving query performance for exploratory data analysis.

Example 4.22. 

-- Sample 10% of rows from a table
SELECT * FROM large_table TABLESAMPLE SYSTEM(10);

-- Sample approximately 1000 rows
SELECT * FROM events TABLESAMPLE SYSTEM(1000 ROWS);

-- Sample from data lake files
SELECT * FROM read_parquet('s3://datalake/**/*.parquet') TABLESAMPLE SYSTEM(5);

-- Use sampling for quick data profiling
SELECT
    region,
    COUNT(*) as sample_count,
    AVG(revenue) as avg_revenue
FROM sales_data TABLESAMPLE SYSTEM(2)
GROUP BY region;

-- Sample from joins for performance
SELECT c.name, COUNT(o.id) as order_count
FROM customers c
JOIN orders o TABLESAMPLE SYSTEM(10) ON c.id = o.customer_id
GROUP BY c.name;

Sampling methods:

  • SYSTEM: Random sampling at the storage level (faster, approximate percentage).

  • BERNOULLI: Row-by-row random sampling (slower, exact percentage).

Example 4.23. 

-- System sampling (recommended for large tables)
SELECT * FROM huge_table TABLESAMPLE SYSTEM(1);

-- Bernoulli sampling (exact percentage)
SELECT * FROM medium_table TABLESAMPLE BERNOULLI(5);

Use cases:

  • Data exploration: Quick analysis of large datasets.

  • Performance testing: Test queries on sample data.

  • Data profiling: Understand data distribution patterns.

  • ETL operations development: Develop pipelines on sample data.

  • Quality checks: Validate data quality on samples.

Required parameters:

Name

Type

Description

sampling_method

keyword

SYSTEM or BERNOULLI

percentage

numeric

Percentage of rows to sample (0-100)

Optional parameters:

Name

Type

Description

rows

integer

Approximate number of rows to sample (use with ROWS keyword)

4.1.7. Time Functions #

time_bucket(bucket_width INTERVAL, timestamp_col TIMESTAMP, origin TIMESTAMP) returns TIMESTAMP #

Buckets timestamps into time intervals for time-series analysis. This function is compatible with the TimescaleDB time_bucket function, allowing for easier migration and interoperability.

Example 4.24. 

-- Group events by hour
SELECT time_bucket(INTERVAL '1 hour', created_at) as hour_bucket, COUNT(*)
FROM events
GROUP BY hour_bucket
ORDER BY hour_bucket;

-- Group by 15-minute intervals
SELECT time_bucket(INTERVAL '15 minutes', timestamp_col), AVG(value)
FROM sensor_data
WHERE timestamp_col >= '2024-01-01'
GROUP BY 1
ORDER BY 1;

Required parameters:

Name

Type

Description

bucket_width

interval

The time interval for bucketing (e.g., '1 hour', '15 minutes')

timestamp_col

timestamp

The timestamp column to bucket

Optional parameters:

Name

Type

Description

origin

timestamp

The origin point for bucketing. Buckets are aligned to this timestamp.

strftime (timestamp_expr, format_string) returns TEXT #

Formats timestamps as strings using standard format codes. This function provides flexible timestamp formatting for display and export purposes.

Example 4.25. 

-- Format current timestamp
SELECT strftime(NOW(), '%Y-%m-%d %H:%M:%S') AS formatted_time;

-- Format timestamps in different formats
SELECT
    order_id,
    strftime(created_at, '%Y-%m-%d') AS order_date,
    strftime(created_at, '%H:%M') AS order_time,
    strftime(created_at, '%A, %B %d, %Y') AS readable_date
FROM orders;

-- Use for partitioning file exports
COPY (SELECT * FROM events WHERE event_date = '2024-01-01')
TO 's3://bucket/events/' || strftime('2024-01-01'::timestamp, '%Y/%m/%d') || '/events.parquet';

Common format codes:

  • %Y: 4-digit year (2024).

  • %m: Month as number (01-12).

  • %d: Day of month (01-31).

  • %H: Hour (00-23).

  • %M: Minute (00-59).

  • %S: Second (00-59).

  • %A: Full weekday name (Monday).

  • %B: Full month name (January).

Optional parameters:

Name

Type

Description

timestamp_expr

timestamp

The timestamp value to format

format_string

text

The format string with format codes

strptime(string_expr, format_string) returns TIMESTAMP #

Parses strings into timestamps using format codes.

Example 4.26. 

-- Parse date strings
SELECT strptime('2024-01-15 14:30:00', '%Y-%m-%d %H:%M:%S') AS parsed_timestamp;

-- Parse different formats
SELECT
    strptime('Jan 15, 2024', '%b %d, %Y') AS date1,
    strptime('15/01/2024', '%d/%m/%Y') AS date2,
    strptime('2024-01-15T14:30:00Z', '%Y-%m-%dT%H:%M:%SZ') AS iso_date;

-- Parse log timestamps
SELECT
    log_id,
    strptime(timestamp_string, '%Y-%m-%d %H:%M:%S') AS parsed_time,
    message
FROM raw_logs;

Required parameters:

Name

Type

Description

string_expr

text

The string to parse as a timestamp

format_string

text

The format string describing the input format

epoch(timestamp_expr) returns BIGINT #

Converts timestamps to Unix epoch seconds (seconds since 1970-01-01 00:00:00 UTC).

Example 4.27. 

-- Get current epoch time
SELECT epoch(NOW()) AS current_epoch;

-- Convert timestamps for API usage
SELECT
    event_id,
    epoch(event_timestamp) AS epoch_seconds
FROM events;

-- Filter using epoch time
SELECT * FROM events
WHERE epoch(created_at) > 1640995200; -- After 2022-01-01

Required parameters:

Name

Type

Description

map_col

duckdb.map

The map from which to extract parameters

key

duckdb.unresolved_type

The key to find in the map

epoch_ms(timestamp_expr) returns BIGINT #

Converts timestamps to Unix epoch milliseconds.

Example 4.28. 

-- High-precision timestamp for JavaScript
SELECT epoch_ms(NOW()) AS timestamp_ms;

-- For time-series data
SELECT
    sensor_id,
    epoch_ms(reading_time) AS timestamp_ms,
    value
FROM sensor_readings;

Required parameters:

Name

Type

Description

timestamp_expr

timestamp

The timestamp to convert to Unix epoch milliseconds

epoch_ms(milliseconds) returns TIMESTAMP #

Converts Unix epoch milliseconds to a timestamp.

Example 4.29. 

-- Convert epoch milliseconds to timestamp
SELECT epoch_ms(1640995200000) AS timestamp_from_ms; -- 2022-01-01 00:00:00

-- Convert stored milliseconds back to timestamps
SELECT
    event_id,
    epoch_ms(timestamp_ms) AS event_time
FROM events;

Required parameters:

Name

Type

Description

milliseconds

bigint

Milliseconds since the Unix epoch

epoch_us(timestamp_expr) returns BIGINT #

Converts timestamps to Unix epoch microseconds.

Example 4.30. 

-- Microsecond precision timestamps
SELECT epoch_us(NOW()) AS timestamp_us;

Required parameters:

Name

Type

Description

timestamp_expr

timestamp

The timestamp to convert to Unix epoch microseconds

epoch_ns(timestamp_expr) returns BIGINT #

Converts timestamps to Unix epoch nanoseconds.

Example 4.31. 

-- Nanosecond precision timestamps
SELECT epoch_ns(NOW()) AS timestamp_ns;

Required parameters:

Name

Type

Description

timestamp_expr

timestamp

The timestamp to convert to Unix epoch nanoseconds

make_timestamp(microseconds) returns TIMESTAMP #

Creates a timestamp from microseconds since the Unix epoch (1970-01-01 00:00:00 UTC).

Example 4.32. 

-- Create timestamp from current epoch microseconds
SELECT make_timestamp(epoch_us(NOW())) AS reconstructed_timestamp;

-- Create specific timestamps
SELECT make_timestamp(1640995200000000) AS new_years_2022; -- 2022-01-01 00:00:00

Required parameters:

Name

Type

Description

microseconds

BIGINT

Microseconds since the Unix epoch

make_timestamptz(microseconds) returns TIMESTAMPTZ #

Creates a timestamp with timezone from microseconds since the Unix epoch.

Example 4.33. 

-- Create timestamptz from current epoch microseconds
SELECT make_timestamptz(epoch_us(NOW())) AS reconstructed_timestamptz;

-- Create specific timestamptz
SELECT make_timestamptz(1640995200000000) AS new_years_2022_tz;

Required parameters:

Name

Type

Description

microseconds

bigint

Microseconds since the Unix epoch

4.1.8. DuckDB Administration Functions #

duckdb.install_extension(extension_name TEXT, repository TEXT DEFAULT 'core') returns bool #

Installs a DuckDB extension and configures it to be loaded automatically in every session that uses pgpro_axe.

Example 4.34. 

  SELECT duckdb.install_extension('iceberg');
  SELECT duckdb.install_extension('avro', 'community');

Since this function can be used to install and download any extensions, it can only be executed by a superuser by default. To allow execution by other administrators, such as my_admin, you can grant them the following privileges:

Example 4.35. 

  GRANT ALL ON FUNCTION duckdb.install_extension(TEXT, TEXT) TO my_admin;

Required parameters:

Name

Type

Description

extension_name

text

The name of the extension to install

duckdb.load_extension(extension_name TEXT) returns void #

Loads a DuckDB extension for the current session only. Unlike duckdb.install_extension, this does not configure the extension to be loaded automatically in future sessions.

Example 4.36. 

SELECT duckdb.load_extension('iceberg');

Required parameters:

Name

Type

Description

extension_name

text

The name of the extension to load

duckdb.autoload_extension(extension_name TEXT, autoload BOOLEAN) returns void #

Specifies whether an installed extension must be automatically loaded in new sessions.

Example 4.37. 

-- Disable auto-loading for an extension
SELECT duckdb.autoload_extension('iceberg', false);

-- Enable auto-loading for an extension
SELECT duckdb.autoload_extension('iceberg', true);

Required parameters:

Name

Type

Description

extension_nametext

The name of the extension

autoload

boolean

Specifies whether the extension must be automatically loaded in new sessions

duckdb.query(query TEXT) returns SETOF duckdb.row #

Executes the given SELECT query directly against DuckDB. This can be useful if the DuckDB syntax makes the query easier to write or to use a function that is not exposed by pgpro_axe yet.

Example 4.38. 

This query puts FROM before SELECT and uses a list comprehension. Both of these features are not supported in Postgres Pro.

  SELECT * FROM duckdb.query('FROM range(10) as a(a) SELECT [a for i in generate_series(0, a)] as arr');

duckdb.raw_query(extension_name TEXT) returns void #

Runs an arbitrary query directly against DuckDB.

Compared to duckdb.query, this function can execute any query, not just SELECT. The main downside is that it does not return its result as rows but instead sends the query result to logs. It is recommended to use duckdb.query when possible.

duckdb.recycle_ddb() returns void #

pgpro_axe keeps the DuckDB instance open inbetween transactions. This is done to save session level state, such as manually executed SET commands. To clear the session level state, you can close the currently open DuckDB instance by calling this function.

Example 4.39. 

  CALL duckdb.recycle_ddb();

4.1.9. Secrets Management Functions #

For more information about secrets, refer to Section 3.1.5.

duckdb.create_simple_secret(type TEXT, key_id TEXT, secret TEXT, region TEXT, optional_parameters) returns void #

Creates a simple secret for accessing cloud storage services, such as S3, GCS, or R2.

Example 4.40. 

-- Create an S3 secret
SELECT duckdb.create_simple_secret(
    type := 'S3',
    key_id := 'your_access_key',
    secret := 'your_secret_key',
    region := 'us-east-1'
);

-- Create an S3 secret with session token
SELECT duckdb.create_simple_secret(
    type := 'S3',
    key_id := 'your_access_key',
    secret := 'your_secret_key',
    region := 'us-east-1',
    session_token := 'your_session_token'
);

Required parameters:

Name

Type

Description

type

text

The type of secret (e.g., 'S3', 'GCS', 'R2')

key_id

text

The access key ID or equivalent

secret

text

The secret key or equivalent

Optional parameters:

Name

Type

Description

session_token

text

Session token for temporary credentials

endpoint

text

Custom endpoint URL

url_style

text

URL style.

Possible values:

  • 'vhost'

  • 'path'

use_ssltext

Specifies whether to use SSL.

Possible values:

  • true

  • false

Default value: true.

scope

text

Scope for the secret.

Default value: ''

region

text

The region for the service