Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/reference/expression-coverage-scoped.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Scoped deviations — dialect, parameter, option, value-class; function-level coverage and matrices live in [`expression-coverage.md`](expression-coverage.md).

Declarations: 43 · Facts: 1462 · Registered operations: 326 · Implementation records: 978
Declarations: 43 · Facts: 1466 · Registered operations: 326 · Implementation records: 978

Legend — scoped deviations:

Expand Down Expand Up @@ -141,6 +141,7 @@ Legend — scoped deviations:
| Dialect | Param | Option values | Value class | Level | Enforcement | Boundary | Condition | Message | Workaround | Upstream | Since | Native errors | Probe-exempt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ibis-polars | unit | 1mo, 1q, 1y, month, quarter, year | — | unsupported | gate | build | — | ibis's polars sub-backend translates interval addition via polars.duration(), which has no months/years kwarg -- round/ceil cannot compute the next calendar boundary (truncate/floor, which only need FLOOR, are unaffected); verified 2026-08-16, ibis 12.0.0 | — | — | 2026-08-16 | — | — |
| ibis-sqlite | unit | — | duration_multiplier | unsupported | gate | build | — | ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0 | — | — | 2026-08-18 | — | — |
| ibis-sqlite | unit | 1h, 1m, 1ms, 1q, 1s, 1us, hour, microsecond, millisecond, minute, quarter, second | — | unsupported | gate | build | — | ibis-sqlite has no TimestampTruncate support for units finer than DAY, and no TimestampBucket compilation rule (blocks multiple>1 bucketing, which quarter needs); verified 2026-08-16, ibis 12.0.0 | — | — | 2026-08-16 | — | — |

### `FLOOR` × narwhals (FKEY_MOUNTAINASH_SCALAR_DATETIME)
Expand All @@ -156,6 +157,7 @@ Legend — scoped deviations:

| Dialect | Param | Option values | Value class | Level | Enforcement | Boundary | Condition | Message | Workaround | Upstream | Since | Native errors | Probe-exempt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ibis-sqlite | unit | — | duration_multiplier | unsupported | gate | build | — | ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0 | — | — | 2026-08-18 | — | — |
| ibis-sqlite | unit | 1h, 1m, 1ms, 1q, 1s, 1us, hour, microsecond, millisecond, minute, quarter, second | — | unsupported | gate | build | — | ibis-sqlite has no TimestampTruncate support for units finer than DAY, and no TimestampBucket compilation rule (blocks multiple>1 bucketing, which quarter needs); verified 2026-08-16, ibis 12.0.0 | — | — | 2026-08-16 | — | — |

### `IS_DST` × ibis (FKEY_MOUNTAINASH_SCALAR_DATETIME)
Expand All @@ -179,6 +181,7 @@ Legend — scoped deviations:
| Dialect | Param | Option values | Value class | Level | Enforcement | Boundary | Condition | Message | Workaround | Upstream | Since | Native errors | Probe-exempt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ibis-polars | unit | 1mo, 1q, 1y, month, quarter, year | — | unsupported | gate | build | — | ibis's polars sub-backend translates interval addition via polars.duration(), which has no months/years kwarg -- round/ceil cannot compute the next calendar boundary (truncate/floor, which only need FLOOR, are unaffected); verified 2026-08-16, ibis 12.0.0 | — | — | 2026-08-16 | — | — |
| ibis-sqlite | unit | — | duration_multiplier | unsupported | gate | build | — | ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0 | — | — | 2026-08-18 | — | — |
| ibis-sqlite | unit | 1h, 1m, 1ms, 1q, 1s, 1us, hour, microsecond, millisecond, minute, quarter, second | — | unsupported | gate | build | — | ibis-sqlite has no TimestampTruncate support for units finer than DAY, and no TimestampBucket compilation rule (blocks multiple>1 bucketing, which quarter needs); verified 2026-08-16, ibis 12.0.0 | — | — | 2026-08-16 | — | — |

### `TO_TIMEZONE` × ibis (FKEY_MOUNTAINASH_SCALAR_DATETIME)
Expand All @@ -201,6 +204,7 @@ Legend — scoped deviations:

| Dialect | Param | Option values | Value class | Level | Enforcement | Boundary | Condition | Message | Workaround | Upstream | Since | Native errors | Probe-exempt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ibis-sqlite | unit | — | duration_multiplier | unsupported | gate | build | — | ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0 | — | — | 2026-08-18 | — | — |
| ibis-sqlite | unit | 1h, 1m, 1ms, 1q, 1s, 1us, hour, microsecond, millisecond, minute, quarter, second | — | unsupported | gate | build | — | ibis-sqlite has no TimestampTruncate support for units finer than DAY, and no TimestampBucket compilation rule (blocks multiple>1 bucketing, which quarter needs); verified 2026-08-16, ibis 12.0.0 | — | — | 2026-08-16 | — | — |

### `CONTAINS` × narwhals (FKEY_MOUNTAINASH_SCALAR_LIST)
Expand Down
158 changes: 140 additions & 18 deletions docs/reference/expression-coverage.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"stamp": {
"declarations": 43,
"facts": 1462,
"facts": 1466,
"operations": 326,
"implementation_records": 978
},
Expand Down Expand Up @@ -50,19 +50,19 @@
"expr_capable": 149,
"literal_only": 65,
"polymorphic": 9,
"unsupported": 1239
"unsupported": 1243
},
"facts_by_enforcement": {
"gate": 1455,
"gate": 1459,
"router_metadata": 3,
"materialize_residue": 4
},
"facts_by_backend": {
"polars": 265,
"narwhals": 586,
"ibis": 611
"ibis": 615
},
"facts_total": 1462
"facts_total": 1466
},
"families": [
{
Expand Down Expand Up @@ -1804,7 +1804,7 @@
"selector_counts": {
"params": 1,
"option_selectors": 16,
"value_classes": 0,
"value_classes": 1,
"dialects": 2
},
"constraints": [
Expand Down Expand Up @@ -1904,6 +1904,22 @@
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
Expand Down Expand Up @@ -3848,10 +3864,26 @@
"selector_counts": {
"params": 1,
"option_selectors": 12,
"value_classes": 0,
"value_classes": 1,
"dialects": 1
},
"constraints": [
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
Expand Down Expand Up @@ -4594,7 +4626,7 @@
"selector_counts": {
"params": 1,
"option_selectors": 16,
"value_classes": 0,
"value_classes": 1,
"dialects": 2
},
"constraints": [
Expand Down Expand Up @@ -4694,6 +4726,22 @@
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
Expand Down Expand Up @@ -5696,10 +5744,26 @@
"selector_counts": {
"params": 1,
"option_selectors": 12,
"value_classes": 0,
"value_classes": 1,
"dialects": 1
},
"constraints": [
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
Expand Down Expand Up @@ -45289,7 +45353,8 @@
"probe_date": "2026-08-16",
"library_versions": [],
"fixtures": [
"ibis-duckdb"
"ibis-duckdb",
"ibis-sqlite"
]
},
"facts": [
Expand Down Expand Up @@ -45356,6 +45421,70 @@
"since": "2026-08-16",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
},
{
"dialect": "ibis-sqlite",
"param": "unit",
"option_value": null,
"value_class": "duration_multiplier",
"level": "unsupported",
"enforcement": "gate",
"boundary": "build",
"condition": null,
"message": "ibis-sqlite has no TimestampBucket compilation rule -- a multiplied MA duration (e.g. dt.truncate('2d')) is unsupported there; verified 2026-08-18, ibis 12.0.0",
"workaround": null,
"upstream_ref": null,
"since": "2026-08-18",
"native_errors": [],
"probe_exempt": null
}
]
},
Expand Down Expand Up @@ -71095,13 +71224,6 @@
"since": "2026-08-06"
}
],
"gaps": [
{
"gap_kind": "other",
"reason": "ibis-sqlite's TimestampBucket has no compilation rule, so a multi-digit MA-wrapper duration string (e.g. dt.truncate('2d')) on ibis-sqlite raises a raw native OperationNotDefinedError rather than a clean BackendCapabilityError. A DURATION_MULTIPLIER-class fact for this would need a corresponding class-backed OptionCell, which the 4-fixture argument-type matrix cannot instantiate for ibis-sqlite (same structural limit as test_option_fact_integrity.py's _MATRIX_UNREACHABLE_DIALECT_FACTS) -- see backlog item 99.",
"since": "2026-08-16",
"review_due": "2027-02-15"
}
],
"gaps": [],
"retired": []
}
22 changes: 10 additions & 12 deletions docs/reference/expression-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- GENERATED FILE — do not edit by hand. -->
<!-- Regenerate: hatch -e test run python -m mountainash.core.capabilities.render_markdown -->

Declarations: 43 · Facts: 1462 · Registered operations: 326 · Implementation records: 978
Declarations: 43 · Facts: 1466 · Registered operations: 326 · Implementation records: 978

Scoped deviations (dialect/param/option/value-class) live in [`expression-coverage-scoped.md`](expression-coverage-scoped.md).

Expand Down Expand Up @@ -61,9 +61,9 @@ audited_unknown: 0

| Axis | Breakdown |
| --- | --- |
| Level | expr_capable 149, literal_only 65, polymorphic 9, unsupported 1239 |
| Enforcement | gate 1455, router_metadata 3, materialize_residue 4 |
| Backend | polars 265, narwhals 586, ibis 611 |
| Level | expr_capable 149, literal_only 65, polymorphic 9, unsupported 1243 |
| Enforcement | gate 1459, router_metadata 3, materialize_residue 4 |
| Backend | polars 265, narwhals 586, ibis 615 |

`pandas` / `pyarrow` are routed input types (they execute via the narwhals path) and are not independent coverage columns.

Expand All @@ -72,7 +72,7 @@ audited_unknown: 0
| Backend | Source | Domain | Probe date | Library versions | Fixtures |
| --- | --- | --- | --- | --- | --- |
| ibis | mountainash | datetime | 2026-07-05 | | |
| ibis | mountainash | datetime | 2026-08-16 | | ibis-duckdb |
| ibis | mountainash | datetime | 2026-08-16 | | ibis-duckdb, ibis-sqlite |
| ibis | mountainash | datetime | 2026-08-16 | | ibis-sqlite, ibis-polars, narwhals-polars, narwhals-pandas |
| ibis | mountainash | relation | 2026-07-05 | | |
| ibis | mountainash | set | — | — | — |
Expand Down Expand Up @@ -135,7 +135,7 @@ audited_unknown: 0
| `ADD_MONTHS` | ✓ | ◐ partial (1 params, 0 option-selectors, 0 value-classes, 0 dialects) | ◐ partial (1 params, 0 option-selectors, 0 value-classes, 0 dialects) |
| `ADD_SECONDS` | ✓ | ◐ partial (1 params, 0 option-selectors, 0 value-classes, 0 dialects) | ◐ partial (1 params, 0 option-selectors, 0 value-classes, 0 dialects) |
| `ADD_YEARS` | ✓ | ◐ partial (1 params, 0 option-selectors, 0 value-classes, 0 dialects) | ◐ partial (1 params, 0 option-selectors, 0 value-classes, 0 dialects) |
| `CEIL` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 16 option-selectors, 0 value-classes, 2 dialects) |
| `CEIL` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 16 option-selectors, 1 value-classes, 2 dialects) |
| `DATE` | ✓ | ✓ audited | ✓ audited |
| `DAYS_IN_MONTH` | ✓ | ✓ audited | ✓ audited |
| `DIFF_DAYS` | ✓ | ✓ audited | ✓ audited |
Expand All @@ -161,14 +161,14 @@ audited_unknown: 0
| `EXTRACT_WEEK` | ✓ | ✓ audited | ✓ audited |
| `EXTRACT_WEEKDAY` | ✓ | ✓ audited | ✓ audited |
| `EXTRACT_YEAR` | ✓ | ✓ audited | ✓ audited |
| `FLOOR` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 12 option-selectors, 0 value-classes, 1 dialects) |
| `FLOOR` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 12 option-selectors, 1 value-classes, 1 dialects) |
| `IS_DST` | ✓ | ✓ audited | ◐ partial (1 params, 0 option-selectors, 1 value-classes, 1 dialects) |
| `IS_LEAP_YEAR` | ✓ | ✓ audited | ✓ audited |
| `MONTH_END` | ✓ | ✓ audited | ✓ audited |
| `MONTH_START` | ✓ | ✓ audited | ✓ audited |
| `NOW` | ✓ | ✓ audited | ✓ audited |
| `OFFSET_BY` | ✓ | ✓ audited | ✓ audited |
| `ROUND` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 16 option-selectors, 0 value-classes, 2 dialects) |
| `ROUND` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 16 option-selectors, 1 value-classes, 2 dialects) |
| `TIME` | ✓ | ✓ audited | ✓ audited |
| `TODAY` | ✓ | ✓ audited | ✓ audited |
| `TOTAL_DAYS` | ✓ | ✓ audited | ✓ audited |
Expand All @@ -179,7 +179,7 @@ audited_unknown: 0
| `TOTAL_NANOSECONDS` | ✓ | ✓ audited | ✓ audited |
| `TOTAL_SECONDS` | ✓ | ✓ audited | ✓ audited |
| `TO_TIMEZONE` | ✓ | ✓ audited | ◐ partial (1 params, 0 option-selectors, 1 value-classes, 1 dialects) |
| `TRUNCATE` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 12 option-selectors, 0 value-classes, 1 dialects) |
| `TRUNCATE` | ✓ | ◐ partial (1 params, 2 option-selectors, 0 value-classes, 2 dialects) | ◐ partial (1 params, 12 option-selectors, 1 value-classes, 1 dialects) |

### `FKEY_MOUNTAINASH_SCALAR_LIST` (mountainash / list)

Expand Down Expand Up @@ -591,9 +591,7 @@ Cells whose facts are all scoped (dialect / parameter / option / value-class) ha

## Known gaps

| Kind | Reason | Since | Review due |
| --- | --- | --- | --- |
| other | ibis-sqlite's TimestampBucket has no compilation rule, so a multi-digit MA-wrapper duration string (e.g. dt.truncate('2d')) on ibis-sqlite raises a raw native OperationNotDefinedError rather than a clean BackendCapabilityError. A DURATION_MULTIPLIER-class fact for this would need a corresponding class-backed OptionCell, which the 4-fixture argument-type matrix cannot instantiate for ibis-sqlite (same structural limit as test_option_fact_integrity.py's _MATRIX_UNREACHABLE_DIALECT_FACTS) -- see backlog item 99. | 2026-08-16 | 2027-02-15 |
None recorded.

## Retirement changelog

Expand Down
Loading
Loading