EraQL language reference
EraQL is a functional query language designed for data transformation and analysis. It combines SQL-like operations with functional programming concepts and a rich set of built-in functions.
Core Syntax
Data Sources
Table
Connect to existing database tables (must be followed by a Select):
Table(
  {
    name: 'users',
    schema: 'analytics'
  },
  {
    created_at: timestamp,
    user_id: string,
    username: string,
    email: string
  }
)
  |> Select({
    id: "user_id",
    name: "username",
    email: "email",
    created: "created_at"
  })
From
Alternative syntax for defining data sources:
From({
  name: 'orders',
  schema: 'sales',
  attributes: {
    customer_email: string,
    order_id: int,
    order_date: timestamp,
    status: string
  }
})
Pipeline Operator
Use the pipe operator |> to chain operations:
data |> Where(condition) |> Select(fields) |> Aggregate(grouping, calculations)
Data Types
Basic Types
string: Text dataint: Integer numbersfloat: Floating-point numbersboolean: True/false valuestimestamp: Date and time values
Complex Types
ARRAY(type): Arrays of elements- Records: 
{ field1: type1, field2: type2 } 
Type Operations
null_of
Create null values of specific types:
null_of('int') // null integer
null_of('string') // null string
type_of(null_of('string')) // returns 'string'
type_of
Get the type of any value:
type_of(1) // 'RANGE(1, 1)!'
type_of('hello') // "ENUM('hello')!"
type_of(true) // 'boolean!'
tag
Tag values with specific types:
tag(1, 'float') // Tags integer as float type
type_of(tag(1, 'float')) // 'RANGE(1, 1)! @float'
Query Operations
Selection and Projection
Select
Transform and project columns:
// Basic selection
data |> Select({
  id: "order_id",
  name: "customer_name",
  created: "order_date"
})
// With transformations
data |> Select(|t| {
  ...t,  // Spread existing fields
  id: t"order_id" |> cast('string'),
  full_name: concat(t"first_name", ' ', t"last_name")
})
// With distinct option
data |> Select({ id: "user_id", name: "username" }, { distinct: true })
Derive
Add computed columns without removing existing ones:
data
  |> Derive({
    id: "user_id",
    metadata: {
      title: "post_title",
      content: "post_content",
      id: "post_id"
    }
  })
Where
Filter rows based on conditions:
data |> Where("item_count" == 1)
data |> Where("item_count" > 1 && ("is_premium" || "has_discount"))
data |> Where(one_of(lower("category"), ['electronics', 'books', 'clothing']))
Aggregation
Aggregate
Group data and perform calculations:
data
  |> Aggregate(
    ["customer_id"], // Group by columns
    {
      customer_id: "customer_id",
      unique_orders: count_distinct("order_id"),
      total_spent: sum("amount")
    }
  )
Summary
Perform calculations across all rows:
data
  |> Summary({
    total_count: count(1),
    items: `[{{string_agg(cast("item_data", string), ', ')}}]`
  })
Joins
LeftJoin
Perform left outer joins:
orders |> LeftJoin(customers, |ord, cust| {
  on: ord"customer_id" == cust"id",
  select: {
    ...ord,
    customer_name: cust"name",
    total_value: ord"quantity" |> mul(cust"unit_price")
  }
})
Set Operations
UnionAll
Combine multiple datasets:
UnionAll(active_users, inactive_users)
Built-in Functions
Mathematical Functions
Basic Arithmetic
add(1, 2) // 3
sub(5, 2) // 3
mul(2, 3) // 6
div(6, 2) // 3
to_the_power_of(2, 3) // 8
Mathematical Operations
abs(-5.5) // 5.5
floor(1.9) // 1
ceil(1.1) // 2
round(1.56, 1) // 1.6
Logarithmic Functions
ln(10) // 2.302585092994046
log_2(8) // 3
log_10(100) // 2
Advanced Math
cosine_distance([1, 0], [0, 1]) // 1
random() // Random number 0-1
nan() // NaN value
is_nan(div(0, 0)) // true
String Functions
Case Conversion
lower('HELLO') // 'hello'
upper('hello') // 'HELLO'
String Manipulation
concat('Hello', ' ', 'World') // 'Hello World'
length('hello') // 5
replace('hello world', 'world', 'there') // 'hello there'
substring('hello world', 1, 5) // 'hello'
String Analysis
starts_with('hello world', 'hello') // true
ends_with('hello world', 'world') // true
like('hello', 'h%') // true (SQL LIKE pattern)
is_numeric_string('123') // true
String Splitting
split_part('hello-world', '-', 1) // 'hello'
split_part('a,b,c', ',', 2) // 'b'
String Prefix/Suffix
remove_prefix('prefix-value', 'prefix-') // 'value'
remove_suffix('value-suffix', '-suffix') // 'value'
String Formatting
Template Strings
;`hello {{1+1}}` // 'hello 2'
format`hello {{1+1}}` // 'hello 2'
format_nullable`hello {{null_of(int)}}` // null
Comparison Functions
Equality
eq(1, 1) // true
neq(1, 2) // true
5 == 5 // true
5 != 3 // true
Ordering
gt(5, 3) // true
gte(5, 5) // true
lt(3, 5) // true
lte(5, 5) // true
5 > 3 // true
5 >= 5 // true
3 < 5 // true
5 <= 5 // true
Logical Functions
Boolean Operations
and(true, 2 > 1) // true
or(false, true) // true
not(true) // false
Null Handling
Null Checks
is_null(null_of(int)) // true
is_not_null(0) // true
Null Operations
coalesce(null_of(int), 3) // 3 (first non-null)
null_if(1, 1) // null (null if equal)
Array and Set Functions
Set Operations
one_of(1, [1, 2, 3]) // true
one_of('a', ['b', 'c']) // false
Array Creation
empty_array_of(int) // []
Date and Time Functions
Date Arithmetic
date_add(@2023-04-01, 1, 'days')      // Add 1 day
date_diff(@2023-04-01, @2023-04-15, 'days')  // 14 days difference
Date Manipulation
date_trunc(@2023-04-15, 'month')      // Truncate to month start
date_part(@2023-04-15, 'month')       // Extract month (4)
now()                                 // Current timestamp
Aggregation Functions
Basic Aggregations
count(1) // Count rows
count_distinct("field") // Count unique values
sum("amount") // Sum values
max("value") // Maximum value
min("value") // Minimum value
string_agg("field", ',') // Concatenate with delimiter
Window Functions
Ranking and Numbering
row_number_over({
  partition_by: ["group_id", "category"],
  order_by: ["created_date"]
})
first_value_over("message_text", {
  partition_by: ["conversation_id"],
  order_by: ["timestamp"]
})
count_over(true, {
  partition_by: ["user_id"]
})
Utility Functions
Data Generation
gen_random_uuid() // Generate UUID
impure(1 + 1) // Disable optimization
Type Conversion
cast('123', 'int') // Convert to integer
cast(123, 'string') // Convert to string
Record Operations
get_from_record({ a: 1, b: 2 }, 'a') // 1
Category Functions
category_concat('a', 'b') // 'a~>b'
category_at('a~>b~>c', 0) // 'a'
Conditional Logic
Conditional Expressions
if(condition, {then: value1, else: value2})
// Example in aggregation
sum(if("is_active", {then: "points", else: 0}))
Advanced Features
Lambda Expressions
Use lambda syntax for complex transformations:
data |> Select(|t| {
  ...t,
  computed_field: some_function(t"field1", t"field2")
})
Field References
Reference fields using quoted syntax:
t"field_name"        // Reference field in lambda
"field_name"         // Reference field in operations
Spread Operator
Use ... to include all existing fields:
Select(|t| {
  ...t,              // Include all existing fields
  new_field: "value" // Add new field
})
Type Casting
Convert between types explicitly:
"user_id" |> cast('string')
"amount" |> cast('float')
Best Practices
Query Organization
- Use meaningful variable names with 
letbindings - Break complex queries into smaller, reusable parts
 - Comment complex logic for maintainability
 
Performance Optimization
- Place 
Whereclauses early in the pipeline - Use appropriate aggregation functions
 - Consider using 
distinct: truewhen needed 
Type Safety
- Explicitly cast types when necessary
 - Use 
null_of()for type-safe null values - Validate types with 
type_of()during development 
Data Integrity
- Handle null values explicitly with 
coalesce()and null checks - Use 
is_numeric_string()before string-to-number conversions - Validate data ranges and constraints in 
Whereclauses 
This reference covers the core EraQL language features. The language continues to evolve with additional functions and capabilities being added regularly.