You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit cd91e25
Browse filesBrowse the repository at this point in the historyBrowse files
Without @spine a fact row with a null or unmatched reference still counts: it
falls in a null group through a nullable (LEFT OUTER) reference and is dropped
through a required (INNER) one. Corrected in the CHANGELOG, reporting.md and
the spec's R8. reporting.md also notes that an @SQL or @Unmanaged report keeps
the derived read shape, so a defaulted measure and a @spine key are non-null in
every port. extractReportSpec now throws on an unresolvable spine-chain entity
instead of skipping the no-table and TPH refusals. Comment-only tidy-ups in the
Kotlin harness, the C# reporting passes and the Python validator.
Copy file name to clipboardExpand all lines: docs/features/reporting.md
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -211,6 +211,10 @@ and the one every runtime reads.
211
211
| the same, plus `@unmanaged: true`|`meta migrate` never creates or drops it (you or a migration tool own the DDL), but the runtime still reads it through the shape below. |
212
212
|`@kind: materializedView`, `storedProc` or `tableFunction`|`meta migrate` skips it, as for a projection. |
213
213
214
+
A report whose view body is your own SQL (`@sql`) or that you manage yourself (`@unmanaged`)
215
+
still gets the derived read shape below, so a defaulted measure and a `@spine` key column are
216
+
typed non-null in every port. Your SQL must keep them non-null (for example with `COALESCE`).
217
+
214
218
A **derived** report view (no `@sql`) whose `@from` entity has no table (it is abstract, or
215
219
declares no writable `source.rdb`) fails `meta migrate` with an error naming the report and the
216
220
entity, rather than emitting a view over a table that does not exist. A report with an `@sql`
@@ -335,8 +339,9 @@ program.
335
339
`@from` are aggregated. A program whose purchases are all out of scope keeps its row, with a
336
340
count of `0`. Both still name fields of `@from`.
337
341
-**A fact row with no spine row is in no row.** A purchase whose `programId` is null, or
338
-
matches no program, has no spine row to sit in. Without `@spine`, those rows form a null
339
-
group.
342
+
matches no program, has no spine row to sit in. Without `@spine`, such a row still counts: it
343
+
falls in a null group through a nullable reference (`LEFT OUTER` join) and is dropped through
344
+
a required one (`INNER` join; see [Dimensions, time grains and joins](#dimensions-time-grains-and-joins)).
340
345
-**A row with no facts** reads `0` for a `count`, and null for a `sum`, `avg`, `min`, `max`
341
346
and a ratio, unless the measure declares `@default` (next section). This holds even for a
342
347
measure whose `@filter` is `isNull: true` on a fact column: the empty row's `@of` column is
@@ -672,7 +677,7 @@ row, and a `SUM` over the result would double-count. A to-one hop cannot fan out
672
677
|**M5**| An `@segment` that names no `segment` child of the owning entity. |
673
678
|**M6**| A `measure.ratio` whose `@numerator` or `@denominator` names no measure of the entity, or names one that is not a `measure.aggregate`. |
674
679
|**M7**| A `@default` on an `@agg: count`. A count is never null, so the default could never apply. |
675
-
|**M8**| A `@default` on an `@agg: min` or `max` over a field that is not numeric (M4's set). |
680
+
|**M8**| A `@default` on an `@agg: min` or `max` over a field that is not numeric (not one of `int, long, double, float, decimal, currency`). |
676
681
677
682
A measure that breaks several of M1 to M4 reports only the first, in that order, so one
678
683
mistake gives one error. M7 and M8 run only when none of M1 to M4 fired.
Copy file name to clipboardExpand all lines: server/java/integration-tests-kotlin/src/test/kotlin/com/metaobjects/integration/kotlin/api/report/generated/GeneratedReportControllerHarness.kt
0 commit comments