From 38fab75a1c9018deecb6741012e2606fc5eecaed Mon Sep 17 00:00:00 2001 From: Mike Carlo Date: Wed, 22 Jul 2026 21:54:13 -0500 Subject: [PATCH 1/5] feat: Add DAX, and examples to the Dialects --- core-spec/expression_language.md | 20 ++++++++++++-------- core-spec/osi-schema.json | 4 ++-- core-spec/spec.md | 1 + core-spec/spec.yaml | 1 + 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/core-spec/expression_language.md b/core-spec/expression_language.md index f635dc4d..43674b79 100644 --- a/core-spec/expression_language.md +++ b/core-spec/expression_language.md @@ -643,6 +643,8 @@ a IS DISTINCT FROM b -- TRUE if one is NULL and other isn't Ossie implementations MAY support additional functions through dialect-specific extensions. When using dialect extensions, the expression must specify the dialect. +Standardized dialect identifiers in the core spec include `ANSI_SQL`, `SNOWFLAKE`, `MDX`, `DAX`, `TABLEAU`, `DATABRICKS`, `MAQL`, and `BIGQUERY`. + The Ossie dialect should always be supported. Other dialects MAY be ignored. There is no guarantee that all different dialects for an expression will act the same, so implementations should be consistent with their dialect handling. This means that if an Ossie model has an expression written in two dialects, the implementation should deterministically choose which dialect to use. ### Declaring Dialect-Specific Expressions @@ -656,18 +658,20 @@ expression: expression: DATE_TRUNC('month', order_date) - dialect: BIGQUERY expression: DATE_TRUNC(order_date, MONTH) + - dialect: DAX + expression: STARTOFMONTH(order_date) ``` ### Common Dialect Variations -| Function | ANSI\_SQL | Snowflake | BigQuery | Databricks | PostgreSQL | -| :---- | :---- | :---- | :---- | :---- | :---- | -| Date truncation | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC(d, MONTH)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | -| Date add | `DATEADD(day, 7, d)` | `DATEADD(day, 7, d)` | `DATE_ADD(d, INTERVAL 7 DAY)` | `DATE_ADD(d, 7)` | `d + INTERVAL '7 days'` | -| String concat | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT(a, b)` | `a || b` | -| Null coalesce | `COALESCE(a, b)` | `COALESCE(a, b)` or `NVL(a, b)` | `COALESCE(a, b)` or `IFNULL(a, b)` | `COALESCE(a, b)` | `COALESCE(a, b)` | -| Current timestamp | `CURRENT_TIMESTAMP` | `CURRENT_TIMESTAMP()` | `CURRENT_TIMESTAMP()` | `CURRENT_TIMESTAMP()` | `CURRENT_TIMESTAMP` | -| Substring | `SUBSTRING(s, start, len)` | `SUBSTR(s, start, len)` | `SUBSTR(s, start, len)` | `SUBSTRING(s, start, len)` | `SUBSTRING(s, start, len)` | +| Function | ANSI\_SQL | Snowflake | BigQuery | Databricks | PostgreSQL | DAX | +| :---- | :---- | :---- | :---- | :---- | :---- | :---- | +| Date truncation | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC(d, MONTH)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | `STARTOFMONTH(d)` | +| Date add | `DATEADD(day, 7, d)` | `DATEADD(day, 7, d)` | `DATE_ADD(d, INTERVAL 7 DAY)` | `DATE_ADD(d, 7)` | `d + INTERVAL '7 days'` | `DATEADD(d, 7, DAY)` | +| String concat | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT_WS('', a, b)` | `CONCATENATE(a, b)` or `a & b` | +| Null coalesce | `COALESCE(a, b)` | `COALESCE(a, b)` or `NVL(a, b)` | `COALESCE(a, b)` or `IFNULL(a, b)` | `COALESCE(a, b)` | `COALESCE(a, b)` | `COALESCE(a, b)` | +| Current timestamp | `CURRENT_TIMESTAMP` | `CURRENT_TIMESTAMP()` | `CURRENT_TIMESTAMP()` | `CURRENT_TIMESTAMP()` | `CURRENT_TIMESTAMP` | `NOW()` or `UTCNOW()` | +| Substring | `SUBSTRING(s, start, len)` | `SUBSTR(s, start, len)` | `SUBSTR(s, start, len)` | `SUBSTRING(s, start, len)` | `SUBSTRING(s, start, len)` | `MID(s, start, len)` | ### diff --git a/core-spec/osi-schema.json b/core-spec/osi-schema.json index 163db20a..97f9fe94 100644 --- a/core-spec/osi-schema.json +++ b/core-spec/osi-schema.json @@ -23,12 +23,12 @@ "$defs": { "Dialect": { "type": "string", - "enum": ["ANSI_SQL", "SNOWFLAKE", "MDX", "TABLEAU", "DATABRICKS", "MAQL", "BIGQUERY"], + "enum": ["ANSI_SQL", "SNOWFLAKE", "MDX", "DAX", "TABLEAU", "DATABRICKS", "MAQL", "BIGQUERY"], "description": "Supported SQL and expression language dialects" }, "Vendor": { "type": "string", - "examples": ["COMMON", "SNOWFLAKE", "SALESFORCE", "DBT", "DATABRICKS", "GOODDATA", "WISDOM"], + "examples": ["COMMON", "SNOWFLAKE", "SALESFORCE", "DBT", "DATABRICKS", "GOODDATA", "WISDOM", "MICROSOFT"], "description": "Vendor name for custom extensions. Any string value is accepted." }, "AIContext": { diff --git a/core-spec/spec.md b/core-spec/spec.md index b7c285ed..dfdd5548 100644 --- a/core-spec/spec.md +++ b/core-spec/spec.md @@ -54,6 +54,7 @@ Supported SQL and expression language dialects for metrics and field definitions | `ANSI_SQL` | Standard SQL dialect | | `SNOWFLAKE` | Snowflake SQL | | `MDX` | Multi-Dimensional Expressions | +| `DAX` | Data Analysis Expressions | | `TABLEAU` | Tableau calculations | | `DATABRICKS` | Databricks SQL | | `MAQL` | GoodData MAQL (Metric Analysis and Query Language) | diff --git a/core-spec/spec.yaml b/core-spec/spec.yaml index 2c9c73e5..31271054 100644 --- a/core-spec/spec.yaml +++ b/core-spec/spec.yaml @@ -33,6 +33,7 @@ dialects: - "ANSI_SQL" # Standard SQL dialect - "SNOWFLAKE" # Snowflake - "MDX" # Multi-Dimensional Expressions + - "DAX" # Data Analysis Expressions - "TABLEAU" # Tableau - "DATABRICKS" # Databricks SQL - "MAQL" # GoodData MAQL (Multi-Dimensional Analytical Query Language) From 5ab2940e1c5a4091edf99215dfd4a8183d24b48f Mon Sep 17 00:00:00 2001 From: Mike Carlo Date: Wed, 22 Jul 2026 22:04:07 -0500 Subject: [PATCH 2/5] chore: update validation script and example to include DAX dialect. --- examples/tpcds_semantic_model.yaml | 2 ++ validation/validate.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/tpcds_semantic_model.yaml b/examples/tpcds_semantic_model.yaml index c20f288e..f605d2a2 100644 --- a/examples/tpcds_semantic_model.yaml +++ b/examples/tpcds_semantic_model.yaml @@ -517,6 +517,8 @@ semantic_model: dialects: - dialect: ANSI_SQL expression: SUM(store_sales.ss_ext_sales_price) + - dialect: DAX + expression: SUM(store_sales.ss_ext_sales_price) description: Total sales revenue across all transactions ai_context: synonyms: diff --git a/validation/validate.py b/validation/validate.py index 258d34f1..e20c867b 100644 --- a/validation/validate.py +++ b/validation/validate.py @@ -67,12 +67,13 @@ "DATABRICKS": "databricks", "BIGQUERY": "bigquery", "MDX": None, # Not supported by sqlglot, skip validation + "DAX": None, # Not supported by sqlglot, skip validation "TABLEAU": None, # Not supported by sqlglot, skip validation "MAQL": None, # Not supported by sqlglot, skip validation } # Dialects that sqlglot cannot parse -SKIP_SQL_VALIDATION = {"MDX", "TABLEAU", "MAQL"} +SKIP_SQL_VALIDATION = {"MDX", "DAX", "TABLEAU", "MAQL"} def validate_schema(data: dict, schema: dict) -> list[str]: From 1586f7379cfe807197ef1ab92e1b3d75a19b0139 Mon Sep 17 00:00:00 2001 From: Mike Carlo Date: Wed, 22 Jul 2026 22:10:30 -0500 Subject: [PATCH 3/5] fix: update spacing in Enum --- core-spec/osi-schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-spec/osi-schema.json b/core-spec/osi-schema.json index 97f9fe94..93a35f93 100644 --- a/core-spec/osi-schema.json +++ b/core-spec/osi-schema.json @@ -23,7 +23,7 @@ "$defs": { "Dialect": { "type": "string", - "enum": ["ANSI_SQL", "SNOWFLAKE", "MDX", "DAX", "TABLEAU", "DATABRICKS", "MAQL", "BIGQUERY"], + "enum": ["ANSI_SQL", "SNOWFLAKE", "MDX", "DAX", "TABLEAU", "DATABRICKS", "MAQL", "BIGQUERY"], "description": "Supported SQL and expression language dialects" }, "Vendor": { From 593033cf8cf56cccd578d9fd25c09527910354b6 Mon Sep 17 00:00:00 2001 From: Mike Carlo Date: Wed, 22 Jul 2026 22:17:29 -0500 Subject: [PATCH 4/5] fix: update models.py to handle DAX --- python/src/ossie/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/src/ossie/models.py b/python/src/ossie/models.py index 9be74a6c..223333c4 100644 --- a/python/src/ossie/models.py +++ b/python/src/ossie/models.py @@ -28,6 +28,7 @@ class OSIDialect(str, Enum): ANSI_SQL = "ANSI_SQL" SNOWFLAKE = "SNOWFLAKE" MDX = "MDX" + DAX = "DAX" MAQL = "MAQL" TABLEAU = "TABLEAU" DATABRICKS = "DATABRICKS" From dd1ab1421613c790190fe8dd0f68fec833fe20c4 Mon Sep 17 00:00:00 2001 From: Mike Carlo Date: Wed, 22 Jul 2026 22:20:18 -0500 Subject: [PATCH 5/5] fix: Update DAX sample expression to be a Scalar --- core-spec/expression_language.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-spec/expression_language.md b/core-spec/expression_language.md index 43674b79..6fdeb735 100644 --- a/core-spec/expression_language.md +++ b/core-spec/expression_language.md @@ -659,14 +659,14 @@ expression: - dialect: BIGQUERY expression: DATE_TRUNC(order_date, MONTH) - dialect: DAX - expression: STARTOFMONTH(order_date) + expression: DATE(YEAR(order_date), MONTH(order_date), 1) ``` ### Common Dialect Variations | Function | ANSI\_SQL | Snowflake | BigQuery | Databricks | PostgreSQL | DAX | | :---- | :---- | :---- | :---- | :---- | :---- | :---- | -| Date truncation | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC(d, MONTH)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | `STARTOFMONTH(d)` | +| Date truncation | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC(d, MONTH)` | `DATE_TRUNC('month', d)` | `DATE_TRUNC('month', d)` | `DATE(YEAR(d), MONTH(d), 1)` | | Date add | `DATEADD(day, 7, d)` | `DATEADD(day, 7, d)` | `DATE_ADD(d, INTERVAL 7 DAY)` | `DATE_ADD(d, 7)` | `d + INTERVAL '7 days'` | `DATEADD(d, 7, DAY)` | | String concat | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT(a, b)` | `CONCAT_WS('', a, b)` | `CONCATENATE(a, b)` or `a & b` | | Null coalesce | `COALESCE(a, b)` | `COALESCE(a, b)` or `NVL(a, b)` | `COALESCE(a, b)` or `IFNULL(a, b)` | `COALESCE(a, b)` | `COALESCE(a, b)` | `COALESCE(a, b)` |