Skip to main content

Validation Functions

AnoFox Tabular provides 26 validation functions across 4 domains: 3 email functions (regex in under 1ms, DNS lookup in ~100ms, SMTP verification in ~500ms), 4 address functions powered by libpostal for international address parsing and normalization, 9 phone functions built on Google's libphonenumber library, and 10 VAT functions covering syntax validation, check-digit verification, normalization, and formatting for 29 European countries. All offline-capable functions execute in under 1ms per record.

Email, address, phone, and VAT validation APIs. Every function is also available under a short alias without the anofox_tab_ prefix (e.g. email_is_valid, phonenumber_is_valid, vat_is_valid).

Quick Reference

FunctionDescriptionSQL Signature
anofox_tab_email_is_validValidate email (boolean)(email [, mode]) -> BOOLEAN
anofox_tab_email_validateValidate email (details)(email [, mode]) -> STRUCT
anofox_tab_phonenumber_is_validValidate phone(phone [, region]) -> BOOLEAN
anofox_tab_phonenumber_parseParse phone number(phone [, region]) -> STRUCT
anofox_tab_vat_is_validValidate VAT (syntax + check digit)(vat_number) -> BOOLEAN
anofox_tab_vat_is_valid_syntaxValidate VAT syntax only(vat_number) -> BOOLEAN
anofox_tab_postal_parse_addressParse address(address) -> STRUCT
anofox_tab_postal_expand_addressNormalize address variants(address) -> VARCHAR[]

Email Functions (3)

anofox_tab_email_is_valid

Quick boolean email validation using one of three modes.

Parameters

ParameterTypeRequiredDefaultDescription
emailVARCHARYes-Email address to validate
modeVARCHARNoconfigured mode ('regex')'regex' (<1ms), 'dns' (~100ms), 'smtp' (~500ms)

Returns: TRUE if valid, FALSE otherwise

Example

SELECT
email,
anofox_tab_email_is_valid(email, 'regex') as syntax_valid,
anofox_tab_email_is_valid(email, 'dns') as domain_valid,
anofox_tab_email_is_valid(email, 'smtp') as mailbox_valid
FROM customers;

anofox_tab_email_validate

Detailed email validation. Returns a struct with the validation stage, failure reason, MX hosts (DNS/SMTP modes), and the SMTP transcript (SMTP mode).

Parameters

ParameterTypeRequiredDefaultDescription
emailVARCHARYes-Email address to validate
modeVARCHARNoconfigured mode ('regex')'regex', 'dns', or 'smtp'

Returns: STRUCT(valid BOOLEAN, stage VARCHAR, reason VARCHAR, mx_hosts VARCHAR[], smtp_transcript VARCHAR[])

SELECT anofox_tab_email_validate('support@example.org', 'dns');
-- Output: {valid: true, stage: 'dns', reason: NULL, mx_hosts: [...], smtp_transcript: NULL}

anofox_tab_email_config

Table function returning the current email validation configuration (timeouts, SMTP settings, tracing).

SELECT * FROM anofox_tab_email_config();

Address Functions (4)

Address functions are powered by libpostal and require its data bundle (~500 MB), installed once via anofox_tab_postal_load_data().

anofox_tab_postal_parse_address

Parse a free-form address string into structured components.

Returns: STRUCT(house_number VARCHAR, road VARCHAR, city VARCHAR, state VARCHAR, postcode VARCHAR, country VARCHAR)

SELECT anofox_tab_postal_parse_address('123 Main St, New York, NY 10001');
-- Output: {house_number: '123', road: 'main st', city: 'new york', state: 'ny', postcode: '10001', country: NULL}

anofox_tab_postal_expand_address

Expand an address into all normalized variants for fuzzy matching and deduplication.

SELECT anofox_tab_postal_expand_address('123 Main St');
-- Output: ['123 main street', '123 main saint', ...]

anofox_tab_postal_status

Table function returning the libpostal initialization status and data directory path.

SELECT * FROM anofox_tab_postal_status();

anofox_tab_postal_load_data

Download and install the libpostal data bundle (~500 MB) required for parsing and expansion.

SELECT anofox_tab_postal_load_data();

Phone Functions (9)

anofox_tab_phonenumber_format

Format a phone number in a standard format.

Parameters

ParameterTypeRequiredDefaultDescription
phoneVARCHARYes-Phone number (any format)
formatVARCHARYes-'E164', 'INTERNATIONAL', 'NATIONAL', or 'RFC3966'
regionVARCHARNoconfigured default region2-letter ISO region hint

Example

SELECT
anofox_tab_phonenumber_format('415-555-0123', 'E164', 'US'), -- '+14155550123'
anofox_tab_phonenumber_format('0203 946 0958', 'INTERNATIONAL', 'GB'); -- '+44 20 3946 0958'

anofox_tab_phonenumber_is_valid

Check whether a phone number is a valid, dialable number.

SELECT
anofox_tab_phonenumber_is_valid('+1 415-555-0123', 'US'), -- true/false
anofox_tab_phonenumber_is_valid('123', 'US'); -- false

anofox_tab_phonenumber_is_possible

Lighter check than is_valid: TRUE if the number's length is plausible for its region.

SELECT anofox_tab_phonenumber_is_possible('4155550123', 'US');

anofox_tab_phonenumber_is_valid_for_region

Check whether a phone number is valid for a specific 2-letter ISO region.

SELECT anofox_tab_phonenumber_is_valid_for_region('+44 20 3946 0958', 'GB');

anofox_tab_phonenumber_region

Return the 2-letter ISO region code for a phone number.

SELECT anofox_tab_phonenumber_region('+44 20 3946 0958');
-- Output: GB

anofox_tab_phonenumber_parse

Parse a phone number and return a struct with E164, national, international, and RFC3966 formats plus the region code.

SELECT anofox_tab_phonenumber_parse('+1 (415) 555-0123', 'US');

anofox_tab_phonenumber_match

Check whether two phone number strings refer to the same number.

SELECT anofox_tab_phonenumber_match('+1 415-555-0123', '4155550123', 'US');

anofox_tab_phonenumber_example

Return an example valid phone number for a 2-letter ISO region.

SELECT anofox_tab_phonenumber_example('US');
-- Output: '+1 650-253-0000'

anofox_tab_phonenumber_status

Table function returning the phone module configuration and status (including the default region).

SELECT * FROM anofox_tab_phonenumber_status();

VAT Functions (10)

anofox_tab_vat_is_valid

Full VAT validation: syntax check plus the country's check-digit validation where implemented.

SELECT
anofox_tab_vat_is_valid('DE111111125'), -- true
anofox_tab_vat_is_valid('DE123456789'); -- false (valid syntax, bad check digit)

anofox_tab_vat_is_valid_syntax

Validate VAT syntax against the country pattern (no check digits, no network calls).

SELECT
anofox_tab_vat_is_valid_syntax('DE123456789'), -- true
anofox_tab_vat_is_valid_syntax('INVALID'); -- false

anofox_tab_vat

Parse a VAT number into a struct with country code, normalized number, and validity flags.

SELECT anofox_tab_vat('DE123456789');

anofox_tab_vat_split

Split a VAT number into a struct with country_code and number fields.

SELECT anofox_tab_vat_split('DE123456789');
-- Output: {country_code: 'DE', number: '123456789'}

anofox_tab_vat_normalize

Remove spaces, dashes, and other formatting characters from a VAT number.

SELECT anofox_tab_vat_normalize('de 123-456-789');
-- Output: 'DE123456789'

anofox_tab_vat_format

Format a VAT number using a style: 'plain' (digits only) or 'iso' (country prefix + digits).

SELECT
anofox_tab_vat_format('de 123-456-789', 'iso'), -- 'DE123456789'
anofox_tab_vat_format('DE123456789', 'plain'); -- '123456789'

anofox_tab_vat_exists

Check whether the VAT number's country prefix exists in the supported country list.

SELECT anofox_tab_vat_exists('DE123456789');  -- true

anofox_tab_vat_is_eu_member

Check whether a VAT number belongs to an EU member state.

SELECT
anofox_tab_vat_is_eu_member('DE123456789'), -- true
anofox_tab_vat_is_eu_member('GB123456789'); -- false (post-Brexit)

anofox_tab_vat_country_name

Return the English country name for the VAT number's country prefix.

SELECT anofox_tab_vat_country_name('DE123456789');
-- Output: 'Germany'

anofox_tab_is_valid_vat_country

Check whether a 2-letter code is a country that uses VAT numbers (accepts the VAT aliases EL and XI).

SELECT
anofox_tab_is_valid_vat_country('DE'), -- true
anofox_tab_is_valid_vat_country('US'); -- false

Performance Characteristics

FunctionSpeedNetworkCacheable
Email regex<1msNoYes
Email DNS~100msYesYes
Email SMTP~500msYesNo
Phone (libphonenumber)<1msNoYes
VAT (syntax + check digit)<1msNoYes
Address (libpostal)~1msNoYes

The performance profile reveals a clear strategy for production pipelines: use offline validation (regex, phone, VAT, address) for bulk processing at sub-millisecond speeds, and reserve network-dependent validation (DNS, SMTP) for targeted verification of flagged records. Email regex validation, phone formatting, and VAT checks all execute in under 1ms per record, making them suitable for validating millions of rows in a single DuckDB query without external service dependencies.


🍪 Cookie Settings