Skip to main content
NQL’s type system bridges the gap between your queries and multiple underlying database engines. Understanding how types work helps you write portable queries and avoid common pitfalls.

Why NQL needs its own type system

Different database engines handle types differently:
  • Snowflake uses NUMBER, VARCHAR, VARIANT for semi-structured data
  • Spark uses LONG, STRING, and nested types with specific semantics
  • BigQuery uses INT64, STRING, and STRUCT/ARRAY with its own rules
NQL provides a consistent type system that the control plane maps to the appropriate native types during transpilation. You write one query, and it works correctly regardless of where your data lives.

Primitive types

NQL’s primitive types map to standard database types across all supported engines:

When precision matters

For financial or measurement data where exact precision is required, use DECIMAL instead of DOUBLE:

Complex types

Data collaboration often involves hierarchical and nested data structures. NQL supports three complex types that work consistently across engines.

Arrays

Arrays store ordered collections of same-type elements. They’re useful for:
  • Lists of identifiers
  • Tags or categories
  • Time-series values
Why arrays exist: Many identity resolution scenarios involve multiple identifiers per record. Arrays let you store and query these without flattening to separate rows.

Structs

Structs group named fields with potentially different types—like a row within a row. They’re useful for:
  • Nested attributes
  • Composite identifiers
  • Grouped metadata
Why structs exist: Real-world data is hierarchical. An identity might have a type and value; an address might have street, city, and postal code. Structs preserve this structure without requiring separate columns.

Maps

Maps store key-value pairs where all keys share a type and all values share a type. They’re useful for:
  • Dynamic properties
  • Metadata with variable keys
  • Key-value attributes
Why maps exist: Some data has dynamic or sparse attributes. Rather than creating columns for every possible property, maps store only the properties that exist for each record.

Nested types

Complex types can be nested to represent hierarchical data:

Accessing nested data

Use dot notation for struct fields and bracket notation for arrays:

Type coercion

NQL automatically converts types in certain contexts to reduce the need for explicit casting.

Implicit coercion

When to use explicit CAST

Use CAST when:
  • Converting between incompatible types
  • Ensuring specific precision
  • Documenting intent clearly

NULL handling

NULL represents missing or unknown data. Understanding NULL behavior prevents subtle bugs.

NULL in comparisons

NULL is not equal to anything, including itself:
Use IS NULL and IS NOT NULL for NULL checks:

NULL in operations

Operations involving NULL typically return NULL:

NULL-safe comparisons

Use IS NOT DISTINCT FROM for NULL-safe equality:
This is especially useful in MERGE conditions:

Type inference

NQL infers types from context when possible:

ARRAY type inference

Array literals infer element type from contents:

Cross-engine considerations

While NQL abstracts type differences, some edge cases exist:

Timestamp precision

Different engines support different timestamp precision. NQL uses millisecond precision as the common denominator.

String collation

String comparison and sorting may differ slightly between engines. For consistent behavior, normalize strings (lowercase, trim) before comparison.

Numeric overflow

Large numbers may overflow differently across engines. For critical calculations, consider using DECIMAL with explicit precision.

Troubleshooting type errors

UnsupportedTypeError

This error occurs when an operation doesn’t support the given types:
Fix: Use explicit CAST:

Type mismatch in arrays

All array elements must have the same type:
Fix: Ensure consistent types or cast explicitly:

NULL type resolution

NULL by itself has no type. In some contexts, you need to cast NULL:

Data Types Reference

Complete type reference with syntax

NQL vs SQL

How NQL types compare to standard SQL

Functions Reference

Type conversion and manipulation functions

Troubleshooting

Common type-related errors and solutions