Skip to content

Apache Ossie - Core Metadata Specification

DRAFT version — in development, schema may change before 0.2.0 is released.

Version: 0.2.0.dev0

Goals

  • Standardization: Establish uniform language and structure for semantic model definitions, ensuring consistency and ease of interpretation across various tools and systems.
  • Extensibility: Support domain-specific extensions while maintaining core compatibility.
  • Interoperability: Enable exchange and reuse across different AI and BI applications.

Table of Contents

  1. Enumerations
  2. Semantic Model
  3. Datasets
  4. Relationships
  5. Fields
  6. Metrics
  7. Examples

Enumerations

Standard enumeration values used throughout the specification.

Dialects

Dialects in which metric and field expressions can be declared.

Dialect Description
ANSI_SQL Standard SQL dialect
SNOWFLAKE Snowflake SQL
MDX Multi-Dimensional Expressions
TABLEAU Tableau calculations
DATABRICKS Databricks SQL
MAQL GoodData MAQL (Multi-Dimensional Analytical Query Language)
BIGQUERY Google BigQuery (GoogleSQL)
SIGMA Sigma Computing's spreadsheet-style formula language
THOUGHTSPOT ThoughtSpot formula language
DAX Data Analysis Expressions (Power BI / Analysis Services)
HOLISTICS_AQL Holistics AQL (Analytical Query Language)
OSSIE_SQL_2026 Ossie's portable SQL expression language, defined in expression_language.md

OSSIE_SQL_2026 is the only dialect whose semantics this specification defines. The other values identify vendor or third-party expression languages. Ossie treats expressions in those dialects as opaque, and implementations MAY ignore them (see Dialect Extensions). Registering a dialect makes it valid for declaring a model; it does not mean Ossie supports querying in that dialect (see Model Declaration vs. Querying).

Data types

DataType declares the logical value type of a field or metric independently of its role and physical representation. The shared names align with the ontology specification's built-in value types; Time, DateTimeTz, and Opaque are additional core data types.

DataType Description
String Variable-length Unicode character data; length and collation are unspecified.
Integer Exact integral number; width and signedness are unspecified.
Decimal Exact base-10 number; precision and scale are unspecified.
Float Approximate floating-point number.
Boolean Logical two-valued truth type.
Date Calendar date with no time-of-day component.
Time Time-of-day with no date or timezone.
DateTime Local/civil date and time with no timezone or offset.
DateTimeTz Date and time with sufficient offset or timezone context to identify an instant. Preservation of a named timezone identifier is not guaranteed.
Opaque Known type outside the portable vocabulary; use custom_extensions for vendor-specific refinement. Omit datatype when the type is unknown or unspecified.

Semantic Model

Each JSON or YAML document represents exactly one semantic model.

A standalone document must contain version, name, and a non-empty datasets array. For bulk exchange, use separate model documents. This specification does not define a bundle format or cross-model references.

Schema

Field Type Required Description
version string Yes Apache Ossie specification version (0.2.0.dev0)
name string Yes Unique identifier for the semantic model
description string No Human-readable description
ai_context string/object No Additional context for AI tools (e.g., custom instructions)
datasets array Yes Collection of logical datasets (fact and dimension tables)
relationships array No Defines how logical datasets are connected
metrics array No Quantifiable measures defined as aggregate expressions on fields from logical datasets
custom_extensions array No Vendor-specific attributes for extensibility

Example

version: 0.2.0.dev0
name: sales_analytics
description: Sales and customer analytics model
ai_context:
  instructions: "Use this model for sales analysis and customer insights"
datasets:
  - name: orders
    source: sales.public.orders
relationships: []
metrics: []
custom_extensions:
  - vendor_name: DBT
    data: '{"project_name": "tpcds_analytics", "models_path": "models/semantic"}'

The same document structure in JSON:

{
  "version": "0.2.0.dev0",
  "name": "sales_analytics",
  "datasets": [
    {"name": "orders", "source": "sales.public.orders"}
  ]
}

Migrating earlier document shapes

This is a breaking change in the unreleased 0.2.0.dev0 specification. Earlier releases and earlier development snapshots use a semantic_model array. The current schema accepts only the flat document shape; it does not accept the array or an object-valued wrapper.

To migrate a document containing one model, move that model's properties to the root and remove semantic_model. Use version: 0.2.0.dev0 for the migrated document. Remove any root-level dialects and vendors declarations; preserve per-expression dialects and vendor information in custom_extensions. For multiple models, create one document per model and validate each result. An empty model array cannot produce a valid model document. Preserve model contents and custom extensions; never silently select only the first model or overwrite a file when splitting a document.

For ontology maps, each embedded model must be a complete core document.


Datasets

Logical datasets represent business entities or concepts (fact and dimension tables). They contain fields and define the structure of the data.

Schema

Field Type Required Description
name string Yes Unique identifier for the dataset
source string Yes Reference to underlying physical table/view (e.g., database.schema.table) or query
primary_key array No Primary key columns that uniquely identify rows (single or composite)
unique_keys array of arrays No Array of unique key definitions (each can be single or composite)
description string No Human-readable description
ai_context string/object No Additional context for AI tools (e.g., synonyms, common terms)
fields array No Row-level attributes for grouping, filtering, and metric expressions
custom_extensions array No Vendor-specific attributes

Primary Key Examples

# Simple primary key
primary_key: [customer_id]

# Composite primary key
primary_key: [order_id, line_number]

Unique Keys Examples

# Multiple unique keys (each can be simple or composite)
unique_keys:
  - [email]                    # Simple unique key
  - [first_name, last_name]    # Composite unique key

Example

datasets:
  - name: orders
    source: sales.public.orders
    primary_key: [order_id]
    unique_keys:
      - [order_id]
      - [order_number]
    description: Order transactions
    ai_context:
      synonyms:
        - "purchases"
        - "sales"
    fields: []
    custom_extensions:
      - vendor_name: DBT
        data: '{"materialized": "table"}'

Relationships

Relationships define how logical datasets are connected through foreign key constraints. They support both simple and composite keys.

Schema

Field Type Required Description
name string Yes Unique identifier for the relationship
from string Yes The logical dataset on the many side of the relationship
to string Yes The logical dataset on the one side of the relationship
from_columns array Yes Array of column names in the "from" dataset (foreign key columns)
to_columns array Yes Array of column names in the "to" dataset (primary or unique key columns)
ai_context string/object No Additional context for AI tools
custom_extensions array No Vendor-specific attributes

Important Notes

  • The order of columns in from_columns must correspond to the order in to_columns
  • Both arrays must have the same number of columns
  • For simple relationships, use a single column: [column1]
  • For composite relationships, use multiple columns: [column1, column2]

Examples

Simple Relationship:

- name: orders_to_customers
  from: orders
  to: customers
  from_columns: [customer_id]
  to_columns: [id]

Composite Relationship:

# order_lines.product_id = products.id AND order_lines.variant_id = products.variant_id
- name: order_lines_to_products
  from: order_lines
  to: products
  from_columns: [product_id, variant_id]
  to_columns: [id, variant_id]

Fields

Fields represent row-level attributes that can be used for grouping, filtering, and in metric expressions. They can be simple column references or computed expressions.

Schema

Field Type Required Description
name string Yes Unique identifier for the field within the dataset
expression object Yes Expression definition with dialect support
dimension object No Dimension metadata (e.g., is_time flag)
label string No Label for categorization
description string No Human-readable description
datatype string (enum) No Logical data type for this field. See Data types.
ai_context string/object No Additional context for AI tools (e.g., synonyms)
custom_extensions array No Vendor-specific attributes

Expression Object

The expression object supports multiple SQL dialects for cross-platform compatibility. Each field can define expressions in different dialects.

Structure:

expression:
  dialects:
    - dialect: ANSI_SQL  # Must be one of the dialects enum values
      expression: "customer_id"  # Scalar SQL expression

Key Points:

  • Use scalar SQL expressions (no aggregations)
  • Can be simple column references (e.g., customer_id) or computed expressions (e.g., first_name || ' ' || last_name)
  • Multiple dialect versions can be provided for the same field

Dimension Object

Field Type Description
is_time boolean Temporal-role marker. When true, consumers that distinguish time dimensions (e.g. for time-series analysis or temporal filtering) should treat this field as a time dimension. This is a role flag, independent of the field's data type. See DataType and is_time: type vs. role.

Examples

Simple Column Reference for a Dimension:

- name: customer_id
  expression:
    dialects:
      - dialect: ANSI_SQL
        expression: customer_id
  description: Customer identifier
  dimension:
    is_time: false

Computed Field:

- name: full_name
  expression:
    dialects:
      - dialect: ANSI_SQL
        expression: first_name || ' ' || last_name
  description: Customer full name
  ai_context:
    synonyms:
      - "name"
      - "customer name"

Time Dimension:

- name: order_date
  expression:
    dialects:
      - dialect: ANSI_SQL
        expression: order_date
  datatype: Date
  dimension:
    is_time: true
  description: Date when order was placed
  ai_context:
    synonyms:
      - "purchase date"
      - "transaction date"

Multi-Dialect Field:

- name: email_normalized
  expression:
    dialects:
      - dialect: ANSI_SQL
        expression: LOWER(email)
      - dialect: SNOWFLAKE
        expression: LOWER(email)::VARCHAR
      - dialect: BIGQUERY
        expression: SAFE_CAST(LOWER(email) AS STRING)
  description: Normalized email address

DataType and is_time: type vs. role

datatype and dimension.is_time are independent properties that answer different questions:

  • datatype describes the data type of the field (e.g. Date, Integer, String, DateTimeTz): what kind of values the field holds.
  • dimension.is_time is a temporal-role marker: whether the field should be treated as a time dimension for time-series analysis or temporal filtering, regardless of its data type.

Default for is_time. When is_time is not set explicitly, it defaults to true if datatype is one of Date, Time, DateTime, DateTimeTz, and false otherwise. Explicit is_time always wins. Set is_time: false on a temporal-typed column (e.g. an audit created_at you don't want on the time axis) to opt out of the default.

Common combinations:

Column example datatype is_time Effective role Why
d_date (calendar date) Date omitted time dimension Temporal datatype; is_time defaults to true.
order_timestamp DateTimeTz omitted time dimension Same.
created_at (audit timestamp) DateTime false regular dimension Explicit opt-out of the temporal default.
d_year (integer year grain) Integer true time dimension Non-temporal datatype; is_time: true makes the role explicit.
d_quarter_name (e.g. "Q1") String true time dimension String-valued temporal grain.
customer_id Integer omitted regular dimension Non-temporal datatype; is_time defaults to false.

Precedent. This type/role separation mirrors Snowflake Semantic Views' YAML authoring form, which has a structural time_dimensions: collection whose entries can carry any data_type. The published example annotates order_year with data_type: NUMBER. LookML supports a similar split via its dimension_group, whose datatype enum covers date, datetime, timestamp, plus the integer-encoded forms epoch and yyyymmdd.

Consumer guidance.

  • For data-type questions (casting, serialization, downstream type inference): prefer datatype when present. If only is_time: true is set, do not infer a specific scalar type from it.
  • For role questions (classifying time dimensions in a query UI, generating time-series output sections, choosing time-aware aggregations): treat the field as a time dimension when is_time resolves to true, whether explicitly set or defaulted from a temporal datatype.

Metrics

Quantitative measures defined on business data, representing key calculations like sums, averages, ratios, etc. Metrics are defined at the semantic model level and can span multiple datasets.

Schema

Field Type Required Description
name string Yes Unique identifier for the metric
expression object Yes Expression definition with dialect support
description string No Human-readable description of what the metric measures
datatype string (enum) No Logical data type for this metric. See Data types.
ai_context string/object No Additional context for AI tools (e.g., synonyms)
custom_extensions array No Vendor-specific attributes

Expression Object

The expression object supports multiple dialects

expression:
  dialects:
  - dialect: ANSI_SQL  # Default
    expression: "SUM(order.sales) / COUNT(DISTINCT order.customer_id)"

Examples

Simple Aggregation:

- name: total_revenue
  expression:
    dialects:
      - dialect: ANSI_SQL
        expression: SUM(orders.amount)
  description: Total revenue across all orders
  datatype: Decimal
  ai_context:
    synonyms:
      - "total sales"
      - "revenue"

Cross-Dataset Metric:

- name: avg_orders
  expression:
    dialects:
      - dialect: ANSI_SQL
        expression: SUM(orders.amount) / COUNT(DISTINCT customers.id)
  description: Average orders
  datatype: Decimal
  ai_context:
    synonyms:
      - "Order Average by customer"

Custom Extensions

Custom extensions allow vendors to add platform-specific metadata without breaking core compatibility. Each extension includes a vendor name and arbitrary JSON data.

Schema

custom_extensions:
  - vendor_name: string  # Free-form string identifying the vendor
    data: string         # JSON string containing vendor-specific data

Vendor Names

The vendor_name field is a free-form string, allowing any vendor or organization to define custom extensions without requiring changes to the core specification.

The following are well-known examples:

Vendor Description
COMMON Common/standard extensions
SNOWFLAKE Snowflake-specific attributes
SALESFORCE Salesforce/Tableau-specific attributes
DBT dbt-specific attributes
DATABRICKS Databricks-specific attributes
GOODDATA GoodData-specific attributes
HONEYDEW Honeydew-specific attributes
WISDOM WisdomAI-specific attributes
POWER_BI Microsoft Power BI-specific attributes
SIGMA Sigma Computing-specific attributes
THOUGHTSPOT ThoughtSpot-specific attributes
HEX Hex-specific attributes

Examples

Snowflake Extension:

- vendor_name: SNOWFLAKE
  data: '{
    "warehouse": "ANALYTICS_WH",
    "database": "PROD",
    "schema": "PUBLIC"
  }'

Salesforce Extension:

- vendor_name: SALESFORCE
  data: '{
    "tableau_workbook_id": "sales_dashboard",
    "einstein_enabled": true,
    "crm_sync": {
      "enabled": true,
      "sync_frequency": "daily"
    }
  }'

DBT Extension:

- vendor_name: DBT
  data: '{
    "project_name": "analytics",
    "materialized": "table",
    "tags": ["daily", "core"]
  }'

Databricks Extension:

- vendor_name: Databricks
  data: '{
    "default_catalog": "finance",
    "default_schema": "gold"
  }'

Complete Example

Here's a complete semantic model example showing all components working together:

version: 0.2.0.dev0
name: ecommerce_analytics
description: E-commerce sales and customer analytics
ai_context:
  instructions: "Use this model for analyzing sales trends, customer behavior, and product performance"

datasets:
  - name: orders
    source: sales.public.orders
    primary_key: [order_id]
    description: Customer orders
    fields:
      - name: order_id
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: order_id
        description: Order identifier

      - name: customer_id
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: customer_id
        description: Customer identifier

      - name: order_date
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: order_date
        datatype: Date
        dimension:
          is_time: true
        description: Order date

      - name: amount
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: amount
        description: Order amount

  - name: customers
    source: sales.public.customers
    primary_key: [id]
    description: Customer information
    fields:
      - name: id
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: id
        description: Customer identifier

      - name: email
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: email
        description: Customer email

relationships:
  - name: orders_to_customers
    from: orders
    to: customers
    from_columns: [customer_id]
    to_columns: [id]

metrics:
  - name: total_revenue
    expression:
      dialects:
        - dialect: ANSI_SQL
          expression: SUM(orders.amount)
    description: Total revenue from all orders
    ai_context:
      synonyms:
        - "total sales"
        - "revenue"

  - name: customer_count
    expression:
      dialects:
        - dialect: ANSI_SQL
          expression: COUNT(DISTINCT customers.id)
    description: Total number of customers
    ai_context:
      synonyms:
        - "total customers"
        - "customer base"

custom_extensions:
  - vendor_name: SNOWFLAKE
    data: '{"warehouse": "ANALYTICS_WH"}'

AI Context Structure

The ai_context field can be either a simple string or a structured object with specific keys:

Simple String:

ai_context: "orders, purchases, sales"

Structured Object:

ai_context:
  instructions: "Use this for sales analysis"
  synonyms:
    - "orders"
    - "purchases"
    - "sales"
  examples:
    - "Show total sales last month"
    - "What's the revenue by region?"
Field Type Description
instructions string Instructions for AI on how to use this entity
synonyms array Alternative names and terms
examples array Sample questions or use cases

Version History

  • 0.2.0.dev0 (Unreleased): In-development next minor release. Schema is mutable; do not depend on this version in production.
  • Breaking: each standalone document contains one model directly at the root; the semantic_model array is removed.
  • 0.1.1 (2025-12-11): Initial release
  • Core semantic model structure
  • Support for datasets, relationships, fields, and metrics
  • Multi-dialect metric expressions
  • Vendor extensibility framework
  • Context for agents

License

See LICENSE file for details.