v0.26.0
v0.26.0
The range starts at fb1e6aa (#254), the first commit after the v0.25.0
tag: 26 commits. Most of them are one thing done repeatedly. DAX scalars
were pinned against Power BI Desktop captures, function family by function
family, and the exercise found a parity defect that no local test could have
reported. Alongside that the Spark engine moved to Sail 0.7.0, arm-emulator
became a default service in this repo's compose, and the compute images gained
names that say what is inside them.
One of these changes what docker compose up starts, and one changes what a
DAX expression returns. Read the first section before you pull.
Behaviour changes, read this one first
-
arm-emulatornow starts withdocker compose upin this repo. Fabric
capacities are ARM resources, and without arm there was nowhere for
Microsoft.Fabric/capacitiesto go:GET /v1/capacitiesserved only the
seeded local one, which is a visibly smaller Fabric than the documentation
describes. arm is now wired exactly as the family BOM wires it, same issuer,
tenant and subscription, so the two stacks cannot disagree.FABRIC_ARM_URLuses-rather than:-, matchingKV_ARM_URLin the BOM,
so an explicitly empty value opts back out to the seeded capacity and
standalonefabric-cicdstill works. The binary default is unchanged:
still empty, still standalone. Only this compose file changed, and
docs/04-configuration.mdanddocs/07-control-plane-api.mdnow distinguish
the two rather than calling the feature opt-in. -
DIVIDE's third argument is now honoured.DIVIDE(numerator, denominator [, alternateResult])returnsalternateResultwhen the
denominator is 0. The arity guard waslen(args) < 2, so a third argument
was accepted and then never read:DIVIDE(x, 0, 0)answered BLANK where
Fabric answers 0.This is the failure direction that ships. The query parses, evaluates and
returns a plausible number, so there is no local symptom at all and nothing
to investigate until someone compares against a tenant.IF, twelve lines
below, has the same< 2guard and does readargs[2], which is what makes
this an oversight rather than a decision. The guard is now< 2 || > 3, so a
fourth argument is rejected rather than silently dropped.Provenance, stated because it differs from the goldens next door: the
alternateResultsemantics come from Microsoft's DAX reference, not from a
Desktop capture. Nobody ran the msmdsrv oracle for this, so the assertions
live indax_arity_test.goand deliberately not indesktop_goldens.json,
whose every entry means "Desktop answered this". -
The Spark engine is Sail 0.7.0, and the Connect client moves with it to
pyspark-client4.2.0. The UDF runs inside the Sail server's embedded
CPython, so server and client must agree; pysail 0.7.0's owntestextra
pins 4.2.0 where 0.6.6 pinned 4.1.1. The client is pinned in five groups,
not one (sail,sail-delta,jupyter,spark-connect,data-science-loop),
and all five move together. The JVM overlay is unaffected: it never uses
pyspark-clientat all, going through spark-submit and Livy with the image's
own pyspark.
DAX pinned against Desktop, not against our reading
The bulk of the range. Each of these is a family of scalars whose answers now
come from a Power BI Desktop capture rather than from our interpretation of the
reference:
SIGN, ASIN, ATAN, PI, SIN, COS, TAN, DEGREES, RADIANS,
DATE, YEAR, MONTH, DAY, TIME, HOUR, MINUTE, SECOND, INT,
MIN, AVERAGE, COUNT, POWER, the remaining Phase 3 scalars, and ROW.
Three additions are about the edges rather than the happy path: SWITCH with
no else branch, the 1.0 == 1 comparison, and eight BLANK and error edges that
the numeric goldens cannot express. The DIVIDE fix above also salvaged 16
Desktop probes that had been captured but were unusable while the third
argument was being dropped.
Engine claims corrected
Two notes that were true of an engine this repo no longer pins:
- The
localRelationSizeLimitpreset is dropped. On 0.7.0 evidence it capped
3 GiB to 64 MiB, so it was making things worse rather than better. (v0.27.0
revisits this: the preset was measured while a separate defect masked the
case that needed it, and the fix is to ask the engine rather than assume
either constant.) - The
VALUESbehaviour was credited to an engine that is no longer pinned.
The credit is removed rather than reassigned, because nobody re-measured it.
Compute images say what is inside them
Both sidecars now also publish under names that describe their contents rather
than the repo that builds them, tagged with the version of the dependency each
is pinned for:
ghcr.io/calvinchengx/emulator-sail:0.7.0 # the pysail pin
ghcr.io/calvinchengx/emulator-spark-agent:4.2.0 # the pyspark-client pin
The old naming conflated two things. fabric-emulator-sail carries upstream
Sail, and databricks-emulator consumes it with no Fabric in the picture at
all; and the tag was fabric's release number while the Sail inside was 0.6.6,
so 0.22.0 and 0.25.0 contained the same engine with nothing in either tag
saying so.
Tags are read from pyproject.toml by scripts/image_tags.py rather than
typed into the workflow, because a version written in release.yml is a second
copy of a number: the release that bumps pysail without editing the workflow
publishes a tag naming the version it no longer contains, and nothing fails.
This is step one, and it moves no consumer. Both names publish, and the old
names keep their release-version tags, so fabric-emulator-sail:0.26.0 and
fabric-emulator-spark-agent:0.26.0 exist as before.
Witnesses
- Microsoft's
azCLI drives git integration, CopyJob, and four pipeline
activities. tycan now see pyspark, so the statement agent is actually type-checked
rather than silently skipped.
Family alignment
entra-emulator0.8.1: the Go library, the pin, and the three composes the
pins gate cannot see.- The consumer repository is now
contoso-fabric-platform, named in
release.ymland in the acceptance dispatch.
Upgrading
docker compose up in this repo now starts arm-emulator as well. If you
want the previous shape, set FABRIC_ARM_URL= explicitly empty and capacities
fall back to the seeded local one. Running the binary is unchanged.
If you pin pyspark-client yourself, move it to 4.2.0 alongside Sail
0.7.0. Server and client share the embedded CPython and must agree. The JVM
overlay needs nothing.
If a DAX expression relies on DIVIDE ignoring its third argument, it now
returns that argument on a zero denominator. That is the direction of the
truth, and any query written against Fabric was already expecting it.
Image names are additive. Nothing that pins fabric-emulator-sail or
fabric-emulator-spark-agent by release version needs to change.