Skip to content

Add Malloy semantic model adapter support#36

Merged
nicosuave merged 3 commits intomainfrom
nicosuave/malloy-imports-exports
Jan 5, 2026
Merged

Add Malloy semantic model adapter support#36
nicosuave merged 3 commits intomainfrom
nicosuave/malloy-imports-exports

Conversation

@nicosuave
Copy link
Copy Markdown
Member

@nicosuave nicosuave commented Jan 5, 2026

Summary

  • Implements Malloy file format support for Sidemantic using ANTLR4 grammar parsing
  • Adds import support (simple, named, aliased, multi-level) with circular import cycle detection
  • Parses and preserves model/dimension/measure descriptions from Malloy annotations with roundtrip export
  • Supports both table-based and SQL-based duckdb.sql() sources with full query preservation
  • Expands test coverage from 5 to 44 tests across parsing, imports, domain fixtures, edge cases, annotations, and SQL sources
  • Extends Dimension class to support second/minute time granularities

Implements full Malloy file format support for Sidemantic with:

- **Import support**: Simple imports, named imports, aliased imports, multi-level
  imports, and circular import cycle detection
- **Annotations**: Parse and preserve model/dimension/measure descriptions from
  Malloy `# desc:` and `##` comments with full roundtrip export support
- **SQL sources**: Support for both table-based and SQL-based `duckdb.sql()` sources
  with full query preservation
- **Comprehensive test coverage**: 44 tests (vs initial 5) covering:
  - 7 import tests (simple, named, aliased, multi-level, circular, missing, directory)
  - 5 basic parsing tests (flights, ecommerce, directory, export, roundtrip)
  - 11 domain fixture tests (retail analytics, SaaS metrics)
  - 9 edge case tests (minimal sources, complex expressions, all aggregations,
    all join types, filtered sources, time granularities, booleans)
  - 5 annotation tests (model/dimension/measure annotations, roundtrip)
  - 7 SQL source tests (parsing, preservation, dimensions/measures, roundtrip)

Core implementation:
- MalloyAdapter class using ANTLR4 grammar for parsing
- MalloyModelVisitor traversing AST to extract semantic information
- Recursive file parsing with cycle detection for imports
- Type inference for dimensions (categorical, time, boolean, numeric)
- Mapping of Malloy concepts to Sidemantic: sources→models, dimensions→dimensions,
  measures→metrics, joins→relationships

Extended Dimension class to support time granularities: second, minute, hour, day,
week, month, quarter, year.

All 44 tests passing, linting clean.
@nicosuave nicosuave changed the title Add comprehensive Malloy semantic model adapter support Add Malloy semantic model adapter support Jan 5, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 495196d384

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread sidemantic/adapters/malloy.py Outdated
Comment on lines +558 to +561
if agg is None and sql:
# Check if it's a ratio or derived
if "/" in sql and not any(agg in sql.lower() for agg in ["sum(", "count(", "avg("]):
metric_type = "ratio"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid ratio metrics without numerator/denominator

When a measure expression contains / and no sum/count/avg, this branch sets metric_type to ratio but never populates numerator/denominator. The Metric validator in sidemantic/core/metric.py rejects ratio metrics without those fields, so any Malloy measure like profit_margin is revenue / cost will raise during parsing and abort the import. Consider keeping these as derived or parsing and assigning numerator/denominator before constructing the Metric.

Useful? React with 👍 / 👎.

@nicosuave nicosuave merged commit d1f2535 into main Jan 5, 2026
10 checks passed
@nicosuave nicosuave deleted the nicosuave/malloy-imports-exports branch January 5, 2026 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant