Search Shortcut cmd + k | ctrl + k
anofox_tabular

A DuckDB extension for data quality, validation and anomaly detection in SQL - 18 data quality checks (volume, nulls, freshness, schema drift, regex and value-set compliance, duplicates, referential integrity, time-aware baselines) with a table-driven check-suite runner, column profiling and correlations including nested types, hash- and join-based table diffing, anomaly detection with Isolation Forest (categorical, Extended IF, SCiForest), DBSCAN and explainable OutlierTree, PII detection and masking (17 types including IBAN, credit cards, API keys and NER-based names, organizations and locations), email validation with DNS/SMTP checks, international address parsing (libpostal), phone number validation (libphonenumber), EU VAT validation (28 countries), and currency-aware money arithmetic.

Maintainer(s): jrosskopf

Compatibility Matrix

This table covers all DuckDB releases that have not reached end-of-life, including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.

Platform 1.4.4 1.4.5 1.5.5 1.5.6 2.0.0
Linux AMD64
Linux ARM64
macOS AMD64
macOS ARM64
Windows AMD64
Windows ARM64
WebAssembly

Installing and Loading

INSTALL anofox_tabular FROM community;
LOAD anofox_tabular;

Example

-- Validate contact data
SELECT email_is_valid('[email protected]'), vat_is_valid('DE136695976');

-- Find and mask PII in free text
SELECT pii_mask('Reach [email protected], card 4111 1111 1111 1111', 'redact');
-- Reach [EMAIL], card [CREDIT_CARD]

-- A data quality check: one pass/fail row with a message
CREATE TABLE orders AS
  SELECT i AS id, CASE WHEN i % 50 = 0 THEN NULL ELSE i % 7 END AS customer_id,
         CASE WHEN i = 77 THEN 99999.0 ELSE 20 + i % 13 END AS amount
  FROM range(1, 501) t(i);
SELECT status, message FROM null_rate('orders', 'customer_id', 0.01);
-- fail | Null rate 0.02 (10/500) exceeds maximum 0.01

-- Anomaly scores with Isolation Forest (trees, sample size, contamination)
SELECT * FROM isolation_forest('orders', 'amount', 100, 256, 0.1, 'scores')
ORDER BY anomaly_score DESC LIMIT 3;

About anofox_tabular

Anofox Tabular brings data quality engineering into DuckDB: checks that return pass/fail assertion rows, check suites defined in a SQL table, profiling, table diffs for migration validation, and anomaly detection, plus validators and normalizers for emails, addresses, phone numbers, EU VAT IDs, money and PII. Everything runs locally inside DuckDB.

Functions carry an anofox_tab_ prefix and a short alias (email_is_valid for anofox_tab_email_is_valid). Documentation: https://github.com/DataZooDE/anofox-tabular/blob/main/docs/API_REFERENCE.md

Added Functions

function_name function_type description comment examples
agg_check table Asserts that an aggregate ('avg', 'min', 'max', 'sum', 'median', 'stddev') of a numeric column is between lower_threshold and upper_threshold (NULL = unbounded). NULL [SELECT * FROM agg_check('orders', 'amount', 'avg', 10.0, 500.0);]
anofox_ner_status table Returns the status of the NER (Named Entity Recognition) model used for name detection. NULL [SELECT * FROM anofox_ner_status();]
anofox_tab_agg_check table Asserts that an aggregate ('avg', 'min', 'max', 'sum', 'median', 'stddev') of a numeric column is between lower_threshold and upper_threshold (NULL = unbounded). NULL [SELECT * FROM agg_check('orders', 'amount', 'avg', 10.0, 500.0);]
anofox_tab_compliance table Asserts that the share of rows satisfying a SQL boolean expression is at least min_rate. Rows where the expression is NULL count as non-compliant. The expression is executed with the caller's privileges. NULL [SELECT * FROM compliance('orders', 'amount > 0 AND status IS NOT NULL', 0.95);]
anofox_tab_currency_name scalar Returns the full English name of a currency given its ISO 4217 code (e.g., 'US Dollar'). NULL [SELECT currency_name('EUR');]
anofox_tab_currency_symbol scalar Returns the currency symbol for a given ISO 4217 currency code (e.g., '$' for USD). NULL [SELECT currency_symbol('EUR');]
anofox_tab_dbscan table Clusters rows by a numeric column using DBSCAN. Returns cluster labels and noise flags. NULL [SELECT * FROM dbscan('orders', 'amount', 0.5, 5, 'clusters');]
anofox_tab_dbscan_mv table Clusters rows by multiple numeric columns (comma-separated) using DBSCAN. Returns cluster labels and noise flags. NULL [SELECT * FROM dbscan_mv('orders', 'amount,qty', 0.5, 5, 'clusters');]
anofox_tab_diff_hashdiff table Computes a row-level diff between two tables using a primary key (VARCHAR or VARCHAR[]). Currently identical to diff_joindiff; the bisection_threshold/bisection_factor parameters are not implemented and rejected. NULL [SELECT * FROM diff_hashdiff('products_v1', 'products_v2', 'product_id');, SELECT * FROM diff_hashdiff('products_v1', 'products_v2', ['product_id', 'sku']);]
anofox_tab_diff_joindiff table Computes a row-level diff between two tables using a primary key (VARCHAR or VARCHAR[]), returning rows that were added, removed, or changed. Primary keys are matched NULL-safely (IS NOT DISTINCT FROM). NULL [SELECT * FROM diff_joindiff('orders_v1', 'orders_v2', 'order_id');, SELECT * FROM diff_joindiff('orders_v1', 'orders_v2', ['order_id', 'line_id']);]
anofox_tab_distinct_count table Asserts that the number of distinct values in a column is between min_distinct and max_distinct. NULL [SELECT * FROM distinct_count('orders', 'status', 1, 10);]
anofox_tab_duplicate_count table Asserts that the number of duplicate values in a column (or comma-separated column combination) does not exceed max_duplicates (default 0). NULL [SELECT * FROM duplicate_count('orders', 'order_id');, SELECT * FROM duplicate_count('orders', 'customer_id,order_date', 10);]
anofox_tab_email_config table Returns the current configuration settings for the email validation module. NULL [SELECT * FROM email_config();]
anofox_tab_email_is_valid scalar Returns TRUE if the email address passes validation using the specified mode ('regex', 'dns', or 'smtp'). Defaults to the configured mode. NULL [SELECT email_is_valid('[email protected]');, SELECT email_is_valid('[email protected]', 'smtp');]
anofox_tab_email_validate scalar Validates an email address using the specified validation mode ('regex', 'dns', or 'smtp'). Returns a struct with validation details. Defaults to the configured mode. NULL [SELECT email_validate('[email protected]');, SELECT email_validate('[email protected]', 'dns');]
anofox_tab_freshness table Returns rows where the most recent value in a timestamp column is older than the specified maximum age interval. Optionally accepts a reference time. NULL [SELECT * FROM freshness('events', 'created_at', INTERVAL '1 day');]
anofox_tab_iqr table Identifies rows where a numeric column value is an outlier by the IQR (interquartile range) method. NULL [SELECT * FROM iqr('orders', 'amount', 1.5);]
anofox_tab_is_valid_currency scalar Returns TRUE if the given string is a valid ISO 4217 currency code. NULL [SELECT is_valid_currency('USD');]
anofox_tab_is_valid_vat_country scalar Returns TRUE if the 2-letter string is a country that uses VAT numbers. NULL [SELECT is_valid_vat_country('DE');]
anofox_tab_isolation_forest table Detects univariate outliers in a numeric column using the Isolation Forest algorithm. Returns scores and outlier labels. NULL [SELECT * FROM isolation_forest('sales', 'amount', 100, 256, 0.05, 'scores');]
anofox_tab_isolation_forest_mv table Detects multivariate outliers across multiple numeric columns (comma-separated) using the Isolation Forest algorithm. NULL [SELECT * FROM isolation_forest_mv('sales', 'amount,qty', 100, 256, 0.05, 'scores');]
anofox_tab_match_rate table Asserts that the share of left-table rows with a join partner in the right table (comma-separated key columns) is at least min_rate. Doubles as a referential-integrity check. NULL [SELECT * FROM match_rate('orders', 'customers', 'customer_id', 'id', 1.0);]
anofox_tab_metric_anomaly_iqr table Flags the reference date as anomalous when its daily metric (row count or AVG of metric_column) falls outside Q1/Q3 +/- k*IQR of the trailing window. Mode 'both', 'upper' or 'lower' selects the bounds. NULL [SELECT * FROM metric_anomaly_iqr('orders', 'order_date', NULL, 30, 1.5, 'both');]
anofox_tab_money scalar Creates a money value from a decimal amount and ISO 4217 currency code. NULL [SELECT money(19.99, 'USD');]
anofox_tab_money_abs scalar Returns the absolute value of a money amount. NULL [SELECT money_abs(money(-19.99, 'USD'));]
anofox_tab_money_add scalar Adds two money values of the same currency. NULL [SELECT money_add(money(10.00, 'USD'), money(5.00, 'USD'));]
anofox_tab_money_amount scalar Extracts the exact numeric amount (DECIMAL(18,3)) from a money value. NULL [SELECT money_amount(money(19.99, 'USD'));]
anofox_tab_money_currency scalar Extracts the ISO 4217 currency code from a money value. NULL [SELECT money_currency(money(19.99, 'USD'));]
anofox_tab_money_format scalar Formats a money value as a string using the specified style ('symbol', 'code', or 'plain'). NULL [SELECT money_format(money(19.99, 'USD'), 'symbol');]
anofox_tab_money_from_cents scalar Creates a money value from an integer amount in the smallest currency unit (e.g. cents) and ISO 4217 currency code. NULL [SELECT money_from_cents(1999, 'USD');]
anofox_tab_money_in_range scalar Returns TRUE if the money amount is within the inclusive range [min, max]. NULL [SELECT money_in_range(money(15.00, 'USD'), 10.0, 20.0);]
anofox_tab_money_is_negative scalar Returns TRUE if the money amount is less than zero. NULL [SELECT money_is_negative(money(-5.00, 'USD'));]
anofox_tab_money_is_positive scalar Returns TRUE if the money amount is greater than zero. NULL [SELECT money_is_positive(money(19.99, 'USD'));]
anofox_tab_money_is_zero scalar Returns TRUE if the money amount is exactly zero. NULL [SELECT money_is_zero(money(0.00, 'USD'));]
anofox_tab_money_multiply scalar Multiplies a money amount by a scalar factor. NULL [SELECT money_multiply(money(10.00, 'USD'), 1.5);]
anofox_tab_money_same_currency scalar Returns TRUE if two money values have the same currency code. NULL [SELECT money_same_currency(money(10.00, 'USD'), money(5.00, 'USD'));]
anofox_tab_money_subtract scalar Subtracts the second money value from the first (must be the same currency). NULL [SELECT money_subtract(money(10.00, 'USD'), money(3.00, 'USD'));]
anofox_tab_null_rate table Asserts that the fraction of NULL values in a column does not exceed max_null_rate. NULL [SELECT * FROM null_rate('orders', 'email', 0.05);]
anofox_tab_occurrence table Asserts that the highest ('max') or lowest ('min') frequency of any single value in a column is between lower_threshold and upper_threshold (NULL = unbounded). NULL [SELECT * FROM occurrence('orders', 'customer_id', 'max', NULL, 100);]
anofox_tab_outlier_tree table Identifies statistical outliers in a table using the OutlierTree algorithm, returning an explanation of which conditions make each row an outlier. NULL [SELECT * FROM outlier_tree('transactions', 'amount,balance', 'summary');]
anofox_tab_phonenumber_example scalar Returns an example valid phone number for the given 2-letter ISO region code (e.g., 'US'). NULL [SELECT phonenumber_example('US');]
anofox_tab_phonenumber_format scalar Formats a phone number string in the specified format: 'E164', 'INTERNATIONAL', 'NATIONAL', or 'RFC3966'. NULL [SELECT phonenumber_format('+14155552671', 'NATIONAL');]
anofox_tab_phonenumber_is_possible scalar Returns TRUE if the phone number length is plausible for its region (lighter check than is_valid). NULL [SELECT phonenumber_is_possible('+14155552671');]
anofox_tab_phonenumber_is_valid scalar Returns TRUE if the phone number is a valid, dialable number. NULL [SELECT phonenumber_is_valid('+14155552671');]
anofox_tab_phonenumber_is_valid_for_region scalar Returns TRUE if the phone number is valid for the specified 2-letter ISO region code (e.g., 'US'). NULL [SELECT phonenumber_is_valid_for_region('+14155552671', 'US');]
anofox_tab_phonenumber_match scalar Returns TRUE if two phone number strings refer to the same number. NULL [SELECT phonenumber_match('+14155552671', '(415) 555-2671');]
anofox_tab_phonenumber_parse scalar Parses a phone number string and returns a struct with E164, national, international, and RFC3966 formats, plus the region code. NULL [SELECT phonenumber_parse('+14155552671');]
anofox_tab_phonenumber_region scalar Returns the 2-letter ISO region code (e.g., 'US', 'DE') for a given phone number. NULL [SELECT phonenumber_region('+14155552671');]
anofox_tab_phonenumber_status table Returns the current configuration and status of the phone number module. NULL [SELECT * FROM phonenumber_status();]
anofox_tab_pii_audit_table table Returns a row-level audit of PII detected in all string columns of a table. NULL [SELECT * FROM pii_audit_table('customers');]
anofox_tab_pii_config table Returns the current configuration settings of the PII detection module. NULL [SELECT * FROM pii_config();]
anofox_tab_pii_contains scalar Returns TRUE if the text contains any PII of the specified type (e.g., 'email', 'phone', 'ssn'). NULL [SELECT pii_contains('Contact us at [email protected]', 'email');]
anofox_tab_pii_count scalar Returns the total count of PII entities detected in the text. NULL [SELECT pii_count('John at [email protected], tel: +1-555-0100');]
anofox_tab_pii_detect scalar Detects all PII entities in a text string and returns them as a list of structs with type, value, start, and end positions. NULL [SELECT pii_detect('Contact John at [email protected] or +1-555-123-4567');]
anofox_tab_pii_detect_batch scalar Runs all PII detectors on an array of text strings and returns a combined list of all detected entities per input. NULL [SELECT pii_detect_batch(['[email protected]', 'SSN: 123-45-6789']);]
anofox_tab_pii_detect_credit_cards scalar Detects all credit card numbers in the text and returns them as a list of structs. NULL [SELECT pii_detect_credit_cards('Pay with 4111111111111111');]
anofox_tab_pii_detect_emails scalar Detects all email addresses in the text and returns them as a list of structs. NULL [SELECT pii_detect_emails('Contact [email protected] or [email protected]');]
anofox_tab_pii_detect_ibans scalar Detects all IBAN numbers in the text and returns them as a list of structs. NULL [SELECT pii_detect_ibans('Bank: DE89370400440532013000');]
anofox_tab_pii_detect_names scalar Detects all person names in the text using NLP and returns them as a list of structs. NULL [SELECT pii_detect_names('Signed by John Smith and Jane Doe');]
anofox_tab_pii_detect_phones scalar Detects all phone numbers in the text and returns them as a list of structs. NULL [SELECT pii_detect_phones('Call +1-555-0100 or 0800 123 456');]
anofox_tab_pii_detect_ssns scalar Detects all Social Security Numbers (SSNs) in the text and returns them as a list of structs. NULL [SELECT pii_detect_ssns('SSN: 123-45-6789');]
anofox_tab_pii_is_valid_credit_card scalar Returns TRUE if the string is a valid credit card number (uses Luhn algorithm). NULL [SELECT pii_is_valid_credit_card('4111111111111111');]
anofox_tab_pii_is_valid_crypto_address scalar Returns TRUE if the string is a valid cryptocurrency wallet address (Bitcoin, Ethereum, etc.). NULL [SELECT pii_is_valid_crypto_address('1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf');]
anofox_tab_pii_is_valid_de_tax_id scalar Returns TRUE if the string is a valid German tax identification number (Steueridentifikationsnummer). NULL [SELECT pii_is_valid_de_tax_id('12345678901');]
anofox_tab_pii_is_valid_iban scalar Returns TRUE if the string is a valid IBAN (International Bank Account Number). NULL [SELECT pii_is_valid_iban('DE89370400440532013000');]
anofox_tab_pii_is_valid_nino scalar Returns TRUE if the string is a valid UK National Insurance Number (NINO). NULL [SELECT pii_is_valid_nino('AB123456C');]
anofox_tab_pii_is_valid_ssn scalar Returns TRUE if the string is a valid US Social Security Number (SSN). NULL [SELECT pii_is_valid_ssn('123-45-6789');]
anofox_tab_pii_mask scalar Masks all detected PII in a text string using the specified strategy ('redact', 'hash', 'partial'). Defaults to 'redact'. NULL [SELECT pii_mask('Call me at +1-555-123-4567');, SELECT pii_mask('[email protected]', 'hash');]
anofox_tab_pii_mask_column scalar Masks a value of a specific PII type using the specified strategy ('redact', 'hash', 'partial'). NULL [SELECT pii_mask_column('[email protected]', 'email', 'hash');]
anofox_tab_pii_redact_column scalar Detects and redacts all PII in a text value using the specified strategy. Defaults to 'redact'. NULL [SELECT pii_redact_column('[email protected]');, SELECT pii_redact_column('[email protected]', 'hash');]
anofox_tab_pii_scan_table table Scans all string columns of a table and returns a summary of detected PII types per column. NULL [SELECT * FROM pii_scan_table('customers');]
anofox_tab_pii_status table Returns the current configuration and status of the PII detection module. NULL [SELECT * FROM pii_status();]
anofox_tab_postal_expand_address scalar Expands a postal address into all normalized variants using libpostal. NULL [SELECT postal_expand_address('123 main st springfield il');]
anofox_tab_postal_load_data scalar Downloads and installs the libpostal data bundle (~500 MB) required for address parsing and expansion. NULL [SELECT postal_load_data();]
anofox_tab_postal_parse_address scalar Parses a free-form postal address string into its structural components (house_number, road, city, state, postcode, country). NULL [SELECT postal_parse_address('123 Main St, Springfield, IL 62701');]
anofox_tab_postal_status table Returns the current status of the libpostal address parser, including whether it is initialized and the data directory path. NULL [SELECT * FROM postal_status();]
anofox_tab_profile_correlations table Computes pairwise Pearson correlation coefficients for numeric columns in a table. NULL [SELECT * FROM profile_correlations('orders');, SELECT * FROM profile_correlations('orders', ['amount', 'qty']);]
anofox_tab_profile_summary table Returns a summary profile of all columns in a table, including min, max, null_count, and distinct_count. NULL [SELECT * FROM profile_summary('orders');]
anofox_tab_profile_table table Profiles selected columns of a table with detailed statistics (min, max, mean, stddev, null_count, distinct_count, sample rows). Optionally filters columns, sets sample size, or uses exact counts. NULL [SELECT * FROM profile_table('orders');, SELECT * FROM profile_table('orders', ['amount', 'status']);]
anofox_tab_regex_match table Asserts that the share of non-NULL values matching a regex pattern is between min_match_rate and max_match_rate. NULL [SELECT * FROM regex_match('users', 'email', '^[^@]+@[^@]+$', 0.99);]
anofox_tab_rel_count_change table Asserts that the daily (distinct) count on the reference date deviates from the rolling window average by a relative change within [lower_threshold, upper_threshold]. Defaults: count rows, 7-day window, reference = latest date in the data. NULL [SELECT * FROM rel_count_change('orders', 'order_date', NULL, 7, -0.5, 0.5);]
anofox_tab_rolling_values_in_set table Asserts that the share of values contained in the allowed set over the trailing window_days days (ending at the reference date, inclusive) is at least min_rate. NULL [SELECT * FROM rolling_values_in_set('orders', 'status', ['completed', 'pending'], 'order_date', 14);]
anofox_tab_run_checks table Runs every check defined in a checks table (columns: check_name, check_type, table_name, column_name, params JSON, lower_threshold, upper_threshold, monitor_only, identifier_column, filter_expr) and returns one uniform result row per check and identifier partition (run_ts, check_name, check_type, table_name, column_name, identifier, value, lower_threshold, upper_threshold, status, message). The checks table must be a regular (non-temporary) table; target tables may be temporary. NULL [SELECT * FROM run_checks('dq_checks');, INSERT INTO dq_results SELECT * FROM run_checks('dq_checks');]
anofox_tab_schema_check table Asserts that a table contains all the required column names. NULL [SELECT * FROM schema_check('orders', ['id', 'amount', 'status']);]
anofox_tab_values_in_set table Asserts that the share of non-NULL values contained in the allowed value set is at least min_rate. Reports up to 5 sample violations. NULL [SELECT * FROM values_in_set('orders', 'status', ['completed', 'pending', 'failed']);]
anofox_tab_vat scalar Parses a VAT number string and returns a struct with country code, normalized number, and validity flags. NULL [SELECT vat('DE123456789');]
anofox_tab_vat_country_name scalar Returns the English country name for the VAT number's country prefix (e.g., 'Germany'). NULL [SELECT vat_country_name('DE123456789');]
anofox_tab_vat_exists scalar Returns TRUE if the country prefix of the VAT number exists in the supported country list. NULL [SELECT vat_exists('DE123456789');]
anofox_tab_vat_format scalar Formats a VAT number using the specified style: 'plain' (digits only) or 'iso' (VAT country prefix + digits). NULL [SELECT vat_format('DE123456789', 'iso');]
anofox_tab_vat_is_eu_member scalar Returns TRUE if the VAT number belongs to an EU member state. NULL [SELECT vat_is_eu_member('DE123456789');]
anofox_tab_vat_is_valid scalar Returns TRUE if the VAT number has valid syntax and passes the country's check-digit validation where implemented. NULL [SELECT vat_is_valid('DE111111125');]
anofox_tab_vat_is_valid_syntax scalar Returns TRUE if the VAT number matches the expected syntax for its country prefix (no network check). NULL [SELECT vat_is_valid_syntax('DE123456789');]
anofox_tab_vat_normalize scalar Normalizes a VAT number by removing spaces, dashes, and other formatting characters. NULL [SELECT vat_normalize('DE 123 456 789');]
anofox_tab_vat_split scalar Splits a VAT number into a struct with 'country_code' and 'number' fields. NULL [SELECT vat_split('DE123456789');]
anofox_tab_volume table Asserts that a table has between min_rows and max_rows rows, returning the count and assertion status. NULL [SELECT * FROM volume('orders', 100, 1000000);]
anofox_tab_zscore table Identifies rows where a numeric column value deviates more than threshold standard deviations from the mean. NULL [SELECT * FROM zscore('orders', 'amount', 3.0);]
compliance table Asserts that the share of rows satisfying a SQL boolean expression is at least min_rate. Rows where the expression is NULL count as non-compliant. The expression is executed with the caller's privileges. NULL [SELECT * FROM compliance('orders', 'amount > 0 AND status IS NOT NULL', 0.95);]
currency_name scalar Returns the full English name of a currency given its ISO 4217 code (e.g., 'US Dollar'). NULL [SELECT currency_name('EUR');]
currency_symbol scalar Returns the currency symbol for a given ISO 4217 currency code (e.g., '$' for USD). NULL [SELECT currency_symbol('EUR');]
dbscan table Clusters rows by a numeric column using DBSCAN. Returns cluster labels and noise flags. NULL [SELECT * FROM dbscan('orders', 'amount', 0.5, 5, 'clusters');]
dbscan_mv table Clusters rows by multiple numeric columns (comma-separated) using DBSCAN. Returns cluster labels and noise flags. NULL [SELECT * FROM dbscan_mv('orders', 'amount,qty', 0.5, 5, 'clusters');]
diff_hashdiff table Computes a row-level diff between two tables using a primary key (VARCHAR or VARCHAR[]). Currently identical to diff_joindiff; the bisection_threshold/bisection_factor parameters are not implemented and rejected. NULL [SELECT * FROM diff_hashdiff('products_v1', 'products_v2', 'product_id');, SELECT * FROM diff_hashdiff('products_v1', 'products_v2', ['product_id', 'sku']);]
diff_joindiff table Computes a row-level diff between two tables using a primary key (VARCHAR or VARCHAR[]), returning rows that were added, removed, or changed. Primary keys are matched NULL-safely (IS NOT DISTINCT FROM). NULL [SELECT * FROM diff_joindiff('orders_v1', 'orders_v2', 'order_id');, SELECT * FROM diff_joindiff('orders_v1', 'orders_v2', ['order_id', 'line_id']);]
distinct_count table Asserts that the number of distinct values in a column is between min_distinct and max_distinct. NULL [SELECT * FROM distinct_count('orders', 'status', 1, 10);]
duplicate_count table Asserts that the number of duplicate values in a column (or comma-separated column combination) does not exceed max_duplicates (default 0). NULL [SELECT * FROM duplicate_count('orders', 'order_id');, SELECT * FROM duplicate_count('orders', 'customer_id,order_date', 10);]
email_config table Returns the current configuration settings for the email validation module. NULL [SELECT * FROM email_config();]
email_is_valid scalar Returns TRUE if the email address passes validation using the specified mode ('regex', 'dns', or 'smtp'). Defaults to the configured mode. NULL [SELECT email_is_valid('[email protected]');, SELECT email_is_valid('[email protected]', 'smtp');]
email_validate scalar Validates an email address using the specified validation mode ('regex', 'dns', or 'smtp'). Returns a struct with validation details. Defaults to the configured mode. NULL [SELECT email_validate('[email protected]');, SELECT email_validate('[email protected]', 'dns');]
freshness table Returns rows where the most recent value in a timestamp column is older than the specified maximum age interval. Optionally accepts a reference time. NULL [SELECT * FROM freshness('events', 'created_at', INTERVAL '1 day');]
iqr table Identifies rows where a numeric column value is an outlier by the IQR (interquartile range) method. NULL [SELECT * FROM iqr('orders', 'amount', 1.5);]
is_valid_currency scalar Returns TRUE if the given string is a valid ISO 4217 currency code. NULL [SELECT is_valid_currency('USD');]
is_valid_vat_country scalar Returns TRUE if the 2-letter string is a country that uses VAT numbers. NULL [SELECT is_valid_vat_country('DE');]
isolation_forest table Detects univariate outliers in a numeric column using the Isolation Forest algorithm. Returns scores and outlier labels. NULL [SELECT * FROM isolation_forest('sales', 'amount', 100, 256, 0.05, 'scores');]
isolation_forest_mv table Detects multivariate outliers across multiple numeric columns (comma-separated) using the Isolation Forest algorithm. NULL [SELECT * FROM isolation_forest_mv('sales', 'amount,qty', 100, 256, 0.05, 'scores');]
match_rate table Asserts that the share of left-table rows with a join partner in the right table (comma-separated key columns) is at least min_rate. Doubles as a referential-integrity check. NULL [SELECT * FROM match_rate('orders', 'customers', 'customer_id', 'id', 1.0);]
metric_anomaly_iqr table Flags the reference date as anomalous when its daily metric (row count or AVG of metric_column) falls outside Q1/Q3 +/- k*IQR of the trailing window. Mode 'both', 'upper' or 'lower' selects the bounds. NULL [SELECT * FROM metric_anomaly_iqr('orders', 'order_date', NULL, 30, 1.5, 'both');]
money scalar Creates a money value from a decimal amount and ISO 4217 currency code. NULL [SELECT money(19.99, 'USD');]
money_abs scalar Returns the absolute value of a money amount. NULL [SELECT money_abs(money(-19.99, 'USD'));]
money_add scalar Adds two money values of the same currency. NULL [SELECT money_add(money(10.00, 'USD'), money(5.00, 'USD'));]
money_amount scalar Extracts the exact numeric amount (DECIMAL(18,3)) from a money value. NULL [SELECT money_amount(money(19.99, 'USD'));]
money_currency scalar Extracts the ISO 4217 currency code from a money value. NULL [SELECT money_currency(money(19.99, 'USD'));]
money_format scalar Formats a money value as a string using the specified style ('symbol', 'code', or 'plain'). NULL [SELECT money_format(money(19.99, 'USD'), 'symbol');]
money_from_cents scalar Creates a money value from an integer amount in the smallest currency unit (e.g. cents) and ISO 4217 currency code. NULL [SELECT money_from_cents(1999, 'USD');]
money_in_range scalar Returns TRUE if the money amount is within the inclusive range [min, max]. NULL [SELECT money_in_range(money(15.00, 'USD'), 10.0, 20.0);]
money_is_negative scalar Returns TRUE if the money amount is less than zero. NULL [SELECT money_is_negative(money(-5.00, 'USD'));]
money_is_positive scalar Returns TRUE if the money amount is greater than zero. NULL [SELECT money_is_positive(money(19.99, 'USD'));]
money_is_zero scalar Returns TRUE if the money amount is exactly zero. NULL [SELECT money_is_zero(money(0.00, 'USD'));]
money_multiply scalar Multiplies a money amount by a scalar factor. NULL [SELECT money_multiply(money(10.00, 'USD'), 1.5);]
money_same_currency scalar Returns TRUE if two money values have the same currency code. NULL [SELECT money_same_currency(money(10.00, 'USD'), money(5.00, 'USD'));]
money_subtract scalar Subtracts the second money value from the first (must be the same currency). NULL [SELECT money_subtract(money(10.00, 'USD'), money(3.00, 'USD'));]
null_rate table Asserts that the fraction of NULL values in a column does not exceed max_null_rate. NULL [SELECT * FROM null_rate('orders', 'email', 0.05);]
occurrence table Asserts that the highest ('max') or lowest ('min') frequency of any single value in a column is between lower_threshold and upper_threshold (NULL = unbounded). NULL [SELECT * FROM occurrence('orders', 'customer_id', 'max', NULL, 100);]
outlier_tree table Identifies statistical outliers in a table using the OutlierTree algorithm, returning an explanation of which conditions make each row an outlier. NULL [SELECT * FROM outlier_tree('transactions', 'amount,balance', 'summary');]
phonenumber_example scalar Returns an example valid phone number for the given 2-letter ISO region code (e.g., 'US'). NULL [SELECT phonenumber_example('US');]
phonenumber_format scalar Formats a phone number string in the specified format: 'E164', 'INTERNATIONAL', 'NATIONAL', or 'RFC3966'. NULL [SELECT phonenumber_format('+14155552671', 'NATIONAL');]
phonenumber_is_possible scalar Returns TRUE if the phone number length is plausible for its region (lighter check than is_valid). NULL [SELECT phonenumber_is_possible('+14155552671');]
phonenumber_is_valid scalar Returns TRUE if the phone number is a valid, dialable number. NULL [SELECT phonenumber_is_valid('+14155552671');]
phonenumber_is_valid_for_region scalar Returns TRUE if the phone number is valid for the specified 2-letter ISO region code (e.g., 'US'). NULL [SELECT phonenumber_is_valid_for_region('+14155552671', 'US');]
phonenumber_match scalar Returns TRUE if two phone number strings refer to the same number. NULL [SELECT phonenumber_match('+14155552671', '(415) 555-2671');]
phonenumber_parse scalar Parses a phone number string and returns a struct with E164, national, international, and RFC3966 formats, plus the region code. NULL [SELECT phonenumber_parse('+14155552671');]
phonenumber_region scalar Returns the 2-letter ISO region code (e.g., 'US', 'DE') for a given phone number. NULL [SELECT phonenumber_region('+14155552671');]
phonenumber_status table Returns the current configuration and status of the phone number module. NULL [SELECT * FROM phonenumber_status();]
pii_audit_table table Returns a row-level audit of PII detected in all string columns of a table. NULL [SELECT * FROM pii_audit_table('customers');]
pii_config table Returns the current configuration settings of the PII detection module. NULL [SELECT * FROM pii_config();]
pii_contains scalar Returns TRUE if the text contains any PII of the specified type (e.g., 'email', 'phone', 'ssn'). NULL [SELECT pii_contains('Contact us at [email protected]', 'email');]
pii_count scalar Returns the total count of PII entities detected in the text. NULL [SELECT pii_count('John at [email protected], tel: +1-555-0100');]
pii_detect scalar Detects all PII entities in a text string and returns them as a list of structs with type, value, start, and end positions. NULL [SELECT pii_detect('Contact John at [email protected] or +1-555-123-4567');]
pii_detect_batch scalar Runs all PII detectors on an array of text strings and returns a combined list of all detected entities per input. NULL [SELECT pii_detect_batch(['[email protected]', 'SSN: 123-45-6789']);]
pii_detect_credit_cards scalar Detects all credit card numbers in the text and returns them as a list of structs. NULL [SELECT pii_detect_credit_cards('Pay with 4111111111111111');]
pii_detect_emails scalar Detects all email addresses in the text and returns them as a list of structs. NULL [SELECT pii_detect_emails('Contact [email protected] or [email protected]');]
pii_detect_ibans scalar Detects all IBAN numbers in the text and returns them as a list of structs. NULL [SELECT pii_detect_ibans('Bank: DE89370400440532013000');]
pii_detect_names scalar Detects all person names in the text using NLP and returns them as a list of structs. NULL [SELECT pii_detect_names('Signed by John Smith and Jane Doe');]
pii_detect_phones scalar Detects all phone numbers in the text and returns them as a list of structs. NULL [SELECT pii_detect_phones('Call +1-555-0100 or 0800 123 456');]
pii_detect_ssns scalar Detects all Social Security Numbers (SSNs) in the text and returns them as a list of structs. NULL [SELECT pii_detect_ssns('SSN: 123-45-6789');]
pii_is_valid_credit_card scalar Returns TRUE if the string is a valid credit card number (uses Luhn algorithm). NULL [SELECT pii_is_valid_credit_card('4111111111111111');]
pii_is_valid_crypto_address scalar Returns TRUE if the string is a valid cryptocurrency wallet address (Bitcoin, Ethereum, etc.). NULL [SELECT pii_is_valid_crypto_address('1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf');]
pii_is_valid_de_tax_id scalar Returns TRUE if the string is a valid German tax identification number (Steueridentifikationsnummer). NULL [SELECT pii_is_valid_de_tax_id('12345678901');]
pii_is_valid_iban scalar Returns TRUE if the string is a valid IBAN (International Bank Account Number). NULL [SELECT pii_is_valid_iban('DE89370400440532013000');]
pii_is_valid_nino scalar Returns TRUE if the string is a valid UK National Insurance Number (NINO). NULL [SELECT pii_is_valid_nino('AB123456C');]
pii_is_valid_ssn scalar Returns TRUE if the string is a valid US Social Security Number (SSN). NULL [SELECT pii_is_valid_ssn('123-45-6789');]
pii_mask scalar Masks all detected PII in a text string using the specified strategy ('redact', 'hash', 'partial'). Defaults to 'redact'. NULL [SELECT pii_mask('Call me at +1-555-123-4567');, SELECT pii_mask('[email protected]', 'hash');]
pii_mask_column scalar Masks a value of a specific PII type using the specified strategy ('redact', 'hash', 'partial'). NULL [SELECT pii_mask_column('[email protected]', 'email', 'hash');]
pii_redact_column scalar Detects and redacts all PII in a text value using the specified strategy. Defaults to 'redact'. NULL [SELECT pii_redact_column('[email protected]');, SELECT pii_redact_column('[email protected]', 'hash');]
pii_scan_table table Scans all string columns of a table and returns a summary of detected PII types per column. NULL [SELECT * FROM pii_scan_table('customers');]
pii_status table Returns the current configuration and status of the PII detection module. NULL [SELECT * FROM pii_status();]
postal_expand_address scalar Expands a postal address into all normalized variants using libpostal. NULL [SELECT postal_expand_address('123 main st springfield il');]
postal_load_data scalar Downloads and installs the libpostal data bundle (~500 MB) required for address parsing and expansion. NULL [SELECT postal_load_data();]
postal_parse_address scalar Parses a free-form postal address string into its structural components (house_number, road, city, state, postcode, country). NULL [SELECT postal_parse_address('123 Main St, Springfield, IL 62701');]
postal_status table Returns the current status of the libpostal address parser, including whether it is initialized and the data directory path. NULL [SELECT * FROM postal_status();]
profile_correlations table Computes pairwise Pearson correlation coefficients for numeric columns in a table. NULL [SELECT * FROM profile_correlations('orders');, SELECT * FROM profile_correlations('orders', ['amount', 'qty']);]
profile_summary table Returns a summary profile of all columns in a table, including min, max, null_count, and distinct_count. NULL [SELECT * FROM profile_summary('orders');]
profile_table table Profiles selected columns of a table with detailed statistics (min, max, mean, stddev, null_count, distinct_count, sample rows). Optionally filters columns, sets sample size, or uses exact counts. NULL [SELECT * FROM profile_table('orders');, SELECT * FROM profile_table('orders', ['amount', 'status']);]
regex_match table Asserts that the share of non-NULL values matching a regex pattern is between min_match_rate and max_match_rate. NULL [SELECT * FROM regex_match('users', 'email', '^[^@]+@[^@]+$', 0.99);]
rel_count_change table Asserts that the daily (distinct) count on the reference date deviates from the rolling window average by a relative change within [lower_threshold, upper_threshold]. Defaults: count rows, 7-day window, reference = latest date in the data. NULL [SELECT * FROM rel_count_change('orders', 'order_date', NULL, 7, -0.5, 0.5);]
rolling_values_in_set table Asserts that the share of values contained in the allowed set over the trailing window_days days (ending at the reference date, inclusive) is at least min_rate. NULL [SELECT * FROM rolling_values_in_set('orders', 'status', ['completed', 'pending'], 'order_date', 14);]
run_checks table Runs every check defined in a checks table (columns: check_name, check_type, table_name, column_name, params JSON, lower_threshold, upper_threshold, monitor_only, identifier_column, filter_expr) and returns one uniform result row per check and identifier partition (run_ts, check_name, check_type, table_name, column_name, identifier, value, lower_threshold, upper_threshold, status, message). The checks table must be a regular (non-temporary) table; target tables may be temporary. NULL [SELECT * FROM run_checks('dq_checks');, INSERT INTO dq_results SELECT * FROM run_checks('dq_checks');]
schema_check table Asserts that a table contains all the required column names. NULL [SELECT * FROM schema_check('orders', ['id', 'amount', 'status']);]
values_in_set table Asserts that the share of non-NULL values contained in the allowed value set is at least min_rate. Reports up to 5 sample violations. NULL [SELECT * FROM values_in_set('orders', 'status', ['completed', 'pending', 'failed']);]
vat scalar Parses a VAT number string and returns a struct with country code, normalized number, and validity flags. NULL [SELECT vat('DE123456789');]
vat_country_name scalar Returns the English country name for the VAT number's country prefix (e.g., 'Germany'). NULL [SELECT vat_country_name('DE123456789');]
vat_exists scalar Returns TRUE if the country prefix of the VAT number exists in the supported country list. NULL [SELECT vat_exists('DE123456789');]
vat_format scalar Formats a VAT number using the specified style: 'plain' (digits only) or 'iso' (VAT country prefix + digits). NULL [SELECT vat_format('DE123456789', 'iso');]
vat_is_eu_member scalar Returns TRUE if the VAT number belongs to an EU member state. NULL [SELECT vat_is_eu_member('DE123456789');]
vat_is_valid scalar Returns TRUE if the VAT number has valid syntax and passes the country's check-digit validation where implemented. NULL [SELECT vat_is_valid('DE111111125');]
vat_is_valid_syntax scalar Returns TRUE if the VAT number matches the expected syntax for its country prefix (no network check). NULL [SELECT vat_is_valid_syntax('DE123456789');]
vat_normalize scalar Normalizes a VAT number by removing spaces, dashes, and other formatting characters. NULL [SELECT vat_normalize('DE 123 456 789');]
vat_split scalar Splits a VAT number into a struct with 'country_code' and 'number' fields. NULL [SELECT vat_split('DE123456789');]
volume table Asserts that a table has between min_rows and max_rows rows, returning the count and assertion status. NULL [SELECT * FROM volume('orders', 100, 1000000);]
zscore table Identifies rows where a numeric column value deviates more than threshold standard deviations from the mean. NULL [SELECT * FROM zscore('orders', 'amount', 3.0);]

Overloaded Functions

This extension does not add any function overloads.

Added Types

This extension does not add any types.

Added Settings

name description input_type scope aliases typed_value
anofox_ner_cache_size LRU cache size for NER results (0 to disable) BIGINT GLOBAL [] 10000
anofox_ner_device OpenVINO device for NER inference: AUTO (default), CPU, GPU, GPU.0, etc. VARCHAR GLOBAL [] AUTO
anofox_ner_model NER model to use (supported: distilbert-en); must be set before the model is first loaded VARCHAR GLOBAL [] distilbert-en
anofox_pii_deep_validation Enable deep validation using libphonenumber for phone numbers (default: false) BOOLEAN GLOBAL [] false
anofox_pii_default_mask_strategy Default masking strategy (REDACT, HASH, PARTIAL, ASTERISK, NONE) VARCHAR GLOBAL [] redact
anofox_pii_enabled_types Comma-separated list of PII types to detect (empty = all) VARCHAR GLOBAL []  
anofox_pii_min_confidence Minimum confidence threshold for NER-based PII detection (0.0 - 1.0) DOUBLE GLOBAL [] 0.5
anofox_tab_email_default_validation Default validation mode for anofox_tab_email_is_valid (regex, dns, smtp) VARCHAR GLOBAL [] regex
anofox_tab_email_dns_timeout_ms DNS resolver timeout in milliseconds BIGINT GLOBAL [] 1000
anofox_tab_email_dns_tries Number of DNS queries to attempt before failing (1-10) INTEGER GLOBAL [] 1
anofox_tab_email_regex_pattern Regular expression used during email regex validation VARCHAR GLOBAL [] ^[A-Za-z0-9.!#$%&'+/=?^_`{|}~-]+@[A-Za-z0-9-]+(?:.[A-Za-z0-9-]+)$
anofox_tab_email_smtp_connect_timeout_ms SMTP connect timeout in milliseconds BIGINT GLOBAL [] 5000
anofox_tab_email_smtp_helo_domain Domain value used during SMTP EHLO negotiation VARCHAR GLOBAL [] duckdb.local
anofox_tab_email_smtp_mail_from MAIL FROM address presented during SMTP verification VARCHAR GLOBAL [] [email protected]
anofox_tab_email_smtp_port SMTP port used when connecting to MX hosts INTEGER GLOBAL [] 25
anofox_tab_email_smtp_read_timeout_ms SMTP read/write timeout in milliseconds BIGINT GLOBAL [] 5000
anofox_tab_phonenumber_default_region Default region code used when the region hint is NULL VARCHAR GLOBAL [] US
anofox_tab_postal_data_path Directory storing libpostal assets VARCHAR GLOBAL [] .duckdb/extensions/libpostal
anofox_tab_trace_enabled Enable anofox tracing output BOOLEAN GLOBAL [] true
anofox_tab_trace_level Minimum tracing level (trace/debug/info/warn/error/critical/off) VARCHAR GLOBAL [] info
anofox_telemetry_enabled Enable or disable anonymous usage telemetry BOOLEAN GLOBAL [] true
anofox_telemetry_key PostHog API key for telemetry VARCHAR GLOBAL [] phc_t3wwRLtpyEmLHYaZCSszG0MqVr74J6wnCrj9D41zk2t
datazoo_banner Show the DataZoo feedback banner when an extension is loaded in an interactive terminal (at most once a day per extension). BOOLEAN GLOBAL [] true
temp_directory Set the directory to which temporary files are written. VARCHAR GLOBAL [] post.db.tmp