Context Variables
Context variables give you access to runtime information inside SQL expressions. Use them to implement row-level security, multi-tenancy, dynamic date ranges, and environment-specific logic.
Overview
Context variables provide access to runtime information within cube definitions. Use them for dynamic SQL generation, filter handling, and security context.
Context Variables
{CUBE}
References the current cube without repeating its name:
cubes:
- name: orders
dimensions:
- name: status
type: string
sql: "{CUBE}.status" # Same as "{orders}.status"
measures:
- name: completed_count
type: count
filters:
- sql: "{CUBE}.status = 'completed'"Essential when using extends so SQL works in child cubes.
FILTER_PARAMS
Access filter values from queries during SQL generation:
cubes:
- name: orders
sql: >
SELECT * FROM orders
WHERE {FILTER_PARAMS.orders.created_at.filter('created_at')}Useful for:
- Partition pruning in data warehouses
- Predicate pushdown optimization
- Dynamic table selection
Syntax: {FILTER_PARAMS.cube_name.member_name.filter('sql_expression')}
FILTER_GROUP
Wraps multiple FILTER_PARAMS when combining with OR:
sql: >
SELECT * FROM orders
WHERE {FILTER_GROUP(
FILTER_PARAMS.orders.status.filter('status'),
FILTER_PARAMS.orders.type.filter('type')
)}Prevents incorrect SQL when filters use OR logic.
COMPILE_CONTEXT
Evaluated once per deployment context. Access via Jinja syntax:
cubes:
- name: orders
sql_table: "{{ COMPILE_CONTEXT.schema }}.orders"
public: "{{ 'true' if COMPILE_CONTEXT.role == 'admin' else 'false' }}"Common uses:
- Multi-tenant table names
- Environment-specific configuration
- Role-based visibility
SQL_UTILS
Helper functions for SQL generation:
dimensions:
- name: created_at_local
type: time
sql: "{SQL_UTILS.convertTz('created_at', 'UTC', 'America/New_York')}"convertTz(): Converts timestamps between timezones.
Note: Don't use SQL_UTILS dimensions as timeDimensions in queries to avoid double conversion.
Examples
Partition Filtering (Snowflake/BigQuery)
cubes:
- name: events
sql: >
SELECT * FROM events
WHERE {FILTER_PARAMS.events.timestamp.filter('timestamp')}When querying with a date filter, this pushes the filter to the partition column for efficient pruning.
Multi-Tenant Tables
cubes:
- name: orders
sql_table: "{{ COMPILE_CONTEXT.tenant_schema }}.orders"Dynamic Visibility
cubes:
- name: sensitive_data
public: "{{ 'true' if COMPILE_CONTEXT.user_role in ['admin', 'analyst'] else 'false' }}"Timezone Conversion
dimensions:
- name: created_at_et
type: time
sql: "{SQL_UTILS.convertTz('created_at', 'UTC', 'America/New_York')}"
title: "Created At (ET)"Best Practices
- Use {CUBE} in extendable cubes — never hardcode cube names
- Use FILTER_PARAMS for partition pruning — improves query performance
- Use COMPILE_CONTEXT for deployment config — not for per-query logic
- Test filter pushdown — verify FILTER_PARAMS generates expected SQL
Row-Level Security via access_policy
For row-level filtering based on the current user or tenant, use access_policy with {securityContext.attrs.X} in filter values:
views:
- name: orders
access_policy:
- group: sdk
row_level:
filters:
- member: tenant_id
operator: equals
values:
- "{securityContext.attrs.tenant_id}"The sdk group is a platform-reserved group automatically assigned to all SDK tokens. Security context attributes are set during token exchange. See Security Context for the full B2B multi-tenancy guide.
Note: The upstream
SECURITY_CONTEXTSQL variable is deprecated. Useaccess_policyrow-level filters with{securityContext.attrs.X}instead.
See Also
Syntax
YAML syntax reference for defining cubes and views in Bonnard. Covers naming conventions, property formats, SQL expressions, Jinja templating, and member references.
References
References let you point to columns, measures, dimensions, and other cubes inside SQL expressions. Use curly-brace syntax to create type-safe, refactor-friendly cross-cube references.