Skip to content

Commit 9f55611

Browse files
authored
Update OSI spec compatibility (#180)
1 parent 5068f55 commit 9f55611

13 files changed

Lines changed: 460 additions & 120 deletions

File tree

docs/compatibility/osi.md

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# OSI Compatibility
22

3-
Sidemantic's OSI adapter parses [Open Semantic Interface](https://github.com/open-semantic-interchange/OSI) YAML files and maps OSI concepts to Sidemantic's semantic model (Model, Dimension, Metric, Relationship). It also supports exporting back to OSI YAML, including multi-dialect SQL transpilation via sqlglot.
3+
Sidemantic's OSI adapter parses [Open Semantic Interchange](https://github.com/open-semantic-interchange/OSI) YAML files and maps OSI concepts to Sidemantic's semantic model (Model, Dimension, Metric, Relationship). It also supports exporting back to OSI YAML, including multi-dialect SQL transpilation via sqlglot.
44

55
Features are marked **supported**, **partial support**, or **unsupported**. Partial support entries include notes explaining the limitation. Properties that parse without error but have no Sidemantic equivalent are grouped together per section rather than listed individually.
66

@@ -12,10 +12,11 @@ Features are marked **supported**, **partial support**, or **unsupported**. Part
1212
|---------|--------|
1313
| `semantic_model` (list of models) | Supported |
1414
| Multiple semantic models in one file | Supported (each iterated independently) |
15-
| `name` (semantic model name) | Partial support: parsed but not stored. The graph has no concept of a top-level model name. Individual datasets become named Models. |
16-
| `description` (semantic model description) | Partial support: parsed but not stored on the graph. |
17-
18-
Not mapped: `version`.
15+
| `version` | Supported. Current exports emit `0.2.0.dev0`; imports preserve the source version in `SemanticGraph.metadata["osi"]["version"]`. |
16+
| `name` (semantic model name) | Supported as metadata. Stored in `SemanticGraph.metadata["osi"]["semantic_models"]` and reused on export. Individual datasets still become named Models. |
17+
| `description` (semantic model description) | Supported as graph metadata and reused on export. |
18+
| `ai_context` (semantic model level) | Supported as graph metadata and reused on export. |
19+
| `custom_extensions` (semantic model level) | Supported as graph metadata and reused on export. |
1920

2021
---
2122

@@ -32,7 +33,6 @@ Not mapped: `version`.
3233
| `fields` | Supported (mapped to Dimensions) |
3334
| `ai_context` | Supported (stored in `Model.meta["ai_context"]`) |
3435
| `custom_extensions` (dataset level) | Supported (stored in `Model.meta["custom_extensions"]`) |
35-
| `custom_extensions` (semantic_model level) | Unsupported |
3636
| Dataset without `name` | Supported (gracefully skipped) |
3737
| Multi-file directory parsing (recursive `.yml`/`.yaml` discovery) | Supported |
3838
| Default primary key when omitted | Supported (defaults to `"id"`) |
@@ -91,6 +91,9 @@ Not mapped: `type` (the OSI `type` hint on metrics, e.g. `type: count`, is ignor
9191
| `from_columns` / `to_columns` (single column) | Supported |
9292
| `from_columns` / `to_columns` (multi-column composite keys) | Supported |
9393
| Relationship type | Partial support: all relationships are imported as `many_to_one`. The OSI spec does not define cardinality on the `from`/`to` relationship format, and the adapter always assumes many-to-one. |
94+
| Relationship `name` | Supported (stored in `Relationship.metadata["osi_name"]` and reused on export) |
95+
| Relationship `ai_context` | Supported (stored in `Relationship.metadata["ai_context"]`) |
96+
| Relationship `custom_extensions` | Supported (stored in `Relationship.metadata["custom_extensions"]`) |
9497
| Missing `from_columns` | Supported (defaults foreign key to `{to_model}_id`) |
9598
| Missing `to_columns` | Supported (defaults primary key to `id`) |
9699
| Relationship with missing `from` or `to` | Supported (gracefully skipped) |
@@ -99,8 +102,6 @@ Not mapped: `type` (the OSI `type` hint on metrics, e.g. `type: count`, is ignor
99102

100103
The `left_dataset`/`right_dataset`/`cardinality` relationship format (used by some community OSI files, e.g. mdb-engine models) is not parsed. Only the `from`/`to`/`from_columns`/`to_columns` format is recognized. Files using the alternative format will parse without error, but relationships will be silently skipped.
101104

102-
Not mapped: relationship `name`, `ai_context` on relationships.
103-
104105
---
105106

106107
## Expression Dialects
@@ -112,8 +113,8 @@ Not mapped: relationship `name`, `ai_context` on relationships.
112113
| `ANSI_SQL` dialect | Supported (preferred) |
113114
| `SNOWFLAKE` dialect | Supported (second preference) |
114115
| `DATABRICKS` dialect | Supported (third preference) |
115-
| `BIGQUERY` dialect | Supported (used as fallback if preferred dialects absent) |
116-
| Other/custom dialects | Supported (used as fallback if preferred dialects absent) |
116+
| `MAQL`, `TABLEAU`, `MDX` dialects | Supported as fallback expressions if no preferred SQL dialect is present. The expression is preserved as text; it is not translated. |
117+
| Other/custom dialects | Supported on import as fallback if preferred dialects absent |
117118
| Multiple dialects per expression | Supported (single dialect selected by preference order) |
118119
| Missing `expression` block | Supported (field SQL becomes `None`) |
119120

@@ -124,9 +125,10 @@ Not mapped: relationship `name`, `ai_context` on relationships.
124125
| Export to `ANSI_SQL` | Supported (default, expression passed through as-is) |
125126
| Export to `SNOWFLAKE` | Supported (transpiled from DuckDB/ANSI via sqlglot) |
126127
| Export to `DATABRICKS` | Supported (transpiled via sqlglot) |
127-
| Export to `BIGQUERY` | Supported (transpiled via sqlglot) |
128+
| Export to `BIGQUERY` | Unsupported (not in the current OSI dialect enum) |
129+
| Export to `MAQL`, `TABLEAU`, `MDX` | Unsupported (not safely generated from Sidemantic SQL) |
128130
| Multiple dialects in single export | Supported (pass `dialects=["ANSI_SQL", "SNOWFLAKE", ...]`) |
129-
| Unknown dialect on export | Supported (falls back to original expression) |
131+
| Unknown dialect on export | Unsupported (raises `ValueError`) |
130132
| Transpilation failure | Supported (falls back to original expression) |
131133

132134
---
@@ -140,8 +142,8 @@ Not mapped: relationship `name`, `ai_context` on relationships.
140142
| Dataset `ai_context` | Supported (stored in `Model.meta["ai_context"]`) |
141143
| Field `ai_context` | Supported (stored in `Dimension.meta["ai_context"]`) |
142144
| Metric `ai_context` | Supported (stored in `Metric.meta["ai_context"]`) |
143-
| Semantic model level `ai_context` | Partial support: parsed by YAML but not stored on the graph. |
144-
| Relationship `ai_context` | Unsupported |
145+
| Semantic model level `ai_context` | Supported (stored in `SemanticGraph.metadata["osi"]["semantic_models"]`) |
146+
| Relationship `ai_context` | Supported (stored in `Relationship.metadata["ai_context"]`) |
145147

146148
Common sub-keys (`synonyms`, `instructions`, `examples`, `description_for_ai`) are all preserved as-is in the meta dictionary. No sub-key receives special handling.
147149

@@ -154,9 +156,10 @@ Common sub-keys (`synonyms`, `instructions`, `examples`, `description_for_ai`) a
154156
| Dataset `custom_extensions` | Supported (stored in `Model.meta["custom_extensions"]`) |
155157
| Field `custom_extensions` | Supported (stored in `Dimension.meta["custom_extensions"]`) |
156158
| Metric `custom_extensions` | Supported (stored in `Metric.meta["custom_extensions"]`) |
157-
| Semantic model level `custom_extensions` | Unsupported |
159+
| Relationship `custom_extensions` | Supported (stored in `Relationship.metadata["custom_extensions"]`) |
160+
| Semantic model level `custom_extensions` | Supported (stored in `SemanticGraph.metadata["osi"]["semantic_models"]`) |
158161

159-
Nested structures within `custom_extensions` (vendor configs, tag lists, etc.) are preserved verbatim as Python dicts/lists.
162+
Current OSI schema represents `custom_extensions` as a list of `{vendor_name, data}` objects where `data` is a JSON string. Sidemantic still imports legacy dict/list extension shapes. On export, non-standard extension payloads are wrapped as a `SIDEMANTIC` extension with stringified JSON so emitted OSI stays schema-shaped.
160163

161164
---
162165

@@ -166,6 +169,8 @@ Sidemantic can export its semantic model back to OSI YAML format.
166169

167170
| Feature | Status |
168171
|---------|--------|
172+
| Current OSI version | Supported (`version: "0.2.0.dev0"` emitted at file root) |
173+
| Semantic-model-level metadata | Supported (`name`, `description`, `ai_context`, `custom_extensions`) |
169174
| Datasets with `source` (table name) | Supported |
170175
| Datasets with `sql` (derived/subquery source) | Supported (wrapped in parentheses) |
171176
| Fields (dimensions) | Supported |
@@ -182,6 +187,7 @@ Sidemantic can export its semantic model back to OSI YAML format.
182187
| Model-level metrics | Supported (promoted to semantic_model-level metrics, field refs qualified with model name) |
183188
| Graph-level metrics | Supported |
184189
| Relationships (`many_to_one` only) | Supported |
190+
| Relationship `name`, `ai_context`, `custom_extensions` | Supported |
185191
| Non-`many_to_one` relationships | Unsupported (silently omitted from export) |
186192
| Multi-column relationship keys | Supported |
187193
| Related model PK lookup on export | Supported (when `rel.primary_key` is None, the related model's actual PK columns are used for `to_columns`) |
@@ -195,7 +201,19 @@ Sidemantic can export its semantic model back to OSI YAML format.
195201

196202
## Version Field
197203

198-
Unsupported. The `version: "1.0"` key at the file root is ignored on import and not emitted on export.
204+
Supported. Imports preserve the source value in graph metadata. Exports always emit the current supported OSI draft version, `0.2.0.dev0`.
205+
206+
---
207+
208+
## Ontology Files
209+
210+
OSI's ontology spec defines conceptual `ontology` entries plus `ontology_mappings` that embed logical semantic models. Sidemantic does not implement ontology reasoning, but it does:
211+
212+
| Feature | Status |
213+
|---------|--------|
214+
| Top-level `ontology` | Partial support: preserved in `SemanticGraph.metadata["osi"]["ontology"]`; not converted to Models. |
215+
| `ontology_mappings[].semantic_model` | Supported: parsed into Sidemantic Models, Relationships, and Metrics. |
216+
| `ontology_mappings[].concept_mappings` | Partial support: preserved in graph metadata; not used for query planning. |
199217

200218
---
201219

examples/osi_demo/adtech_semantic_model.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
version: "0.2.0.dev0"
2+
13
semantic_model:
24
- name: adtech_performance
35
description: Complex adtech semantic layer with multi-hop joins and cross-model metrics

0 commit comments

Comments
 (0)