Skip to main content

Struct

Structs let you group related fields together into a single data structure. Unlike SQL's ROW type, Hamelin structs use field names rather than position to identify each field, making them safer and easier to work with.

Creating structs

You create structs using curly braces with field names and values.

SET user_data = {
user_id: 12345,
name: "Alice Johnson",
email: "[email protected]"
}

This creates a struct with three fields: user_id, name, and email. Each field has a name and a value.

Accessing struct fields

Use dot notation to access individual fields within a struct.

FROM user_events
| WHERE user_info.user_id == 12345
| SELECT
user_name = user_info.name,
user_email = user_info.email

You can access any field by name, regardless of the order they were defined in the struct.

Field order and naming

Structs maintain the order of fields as you define them, but field identity during type expansion comes from the name, not the position. You can read more about that in type expansion.

// These two structs declare different types, but they can be aligned during expansion
SET
profile1 = {
id: 1001,
status: "active",
created: ts('2024-01-15T00:00:00')
},
profile2 = {
status: "inactive",
id: 1002,
created: ts('2024-01-16T00:00:00')
}

Nested structs

Structs can contain other structs for organizing complex data.

FROM events
| SELECT structured_event = {
user: {
id: user_id,
profile: {
name: user_name,
email: email_address
}
},
event: {
type: event_type,
timestamp: event_time,
source: data_source
}
}

Access nested fields by chaining field names with dots:

| SELECT
user_name = structured_event.user.profile.name,
event_time = structured_event.event.timestamp

Practical examples

Structs work well for organizing related information that belongs together:

// HTTP request logging
FROM access_logs
| SELECT request_data = {
request: {
method: http_method,
path: url_path,
status: response_code
},
timing: {
start_time: request_start,
end_time: request_end,
duration_ms: response_time
},
client: {
ip: client_ip,
user_agent: user_agent
}
}

This creates clean, organized output where related fields are grouped logically rather than scattered across many fields.