FAILURE MAP
← Case archive

FA-44901 / Data systems / Open access

Pivot substitutes a null element for an absent cell · case 01

Pivot substitutes a null element for an absent cell.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

categorical-pivot-lists: Pivot substitutes a null element for an absent cell.

VERIFIED REPAIR

Preserve the stated physical representation and operation order: Pivot [row-id,category,value] into [row-id,list-for-category...] using the caller category order. Each cell is an ordered bag list. Unknown categories do not populate cells but retain their row identity; absent cells are empty lists and null values remain elements.

Unsuccessful approach: A null cell is different from a present empty bag.

Case contract

Pivot [row-id,category,value] into [row-id,list-for-category...] using the caller category order. Each cell is an ordered bag list. Unknown categories do not populate cells but retain their row identity; absent cells are empty lists and null values remain elements.

Why this case matters

A bounded deterministic data engine model makes representation and changelog faults reproducible.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    try:
        rows,categories=d
        ids=list(dict.fromkeys(row[0] for row in rows))
        out=[]
        for ident in ids:
            record=[ident]
            for category in categories:
                cell=[value for i,c,value in rows if i==ident and c==category]
                record.append(cell if cell else [None])
            out.append(record)
        return out
    except (IndexError, KeyError, ValueError, StopIteration) as exc:
        return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('column order', solve([[[1, 'a', 1], [1, 'b', 2]], ['b', 'a']]), [[1, [2], [1]]])
    check('unknown-only row', solve([[[1, 'z', 1]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 1], [2, 'a', 2]], ['a']]), [[1, [1]], [2, [2]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 1], [1, 'a', 1]], ['a']]), [[1, [1, 1]]])
    check('no categories', solve([[[1, 'a', 1]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 2:
    check('column order', solve([[[1, 'a', 2], [1, 'b', 3]], ['b', 'a']]), [[1, [3], [2]]])
    check('unknown-only row', solve([[[1, 'z', 2]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 2], [2, 'a', 3]], ['a']]), [[1, [2]], [2, [3]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 2], [1, 'a', 2]], ['a']]), [[1, [2, 2]]])
    check('no categories', solve([[[1, 'a', 2]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 3:
    check('column order', solve([[[1, 'a', 3], [1, 'b', 4]], ['b', 'a']]), [[1, [4], [3]]])
    check('unknown-only row', solve([[[1, 'z', 3]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 3], [2, 'a', 4]], ['a']]), [[1, [3]], [2, [4]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 3], [1, 'a', 3]], ['a']]), [[1, [3, 3]]])
    check('no categories', solve([[[1, 'a', 3]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 4:
    check('column order', solve([[[1, 'a', 4], [1, 'b', 5]], ['b', 'a']]), [[1, [5], [4]]])
    check('unknown-only row', solve([[[1, 'z', 4]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 4], [2, 'a', 5]], ['a']]), [[1, [4]], [2, [5]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 4], [1, 'a', 4]], ['a']]), [[1, [4, 4]]])
    check('no categories', solve([[[1, 'a', 4]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 5:
    check('column order', solve([[[1, 'a', 5], [1, 'b', 6]], ['b', 'a']]), [[1, [6], [5]]])
    check('unknown-only row', solve([[[1, 'z', 5]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 5], [2, 'a', 6]], ['a']]), [[1, [5]], [2, [6]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 5], [1, 'a', 5]], ['a']]), [[1, [5, 5]]])
    check('no categories', solve([[[1, 'a', 5]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
column order[[1, [2], [1]]][[1, [2], [1]]]Passed
unknown-only row[[1, [None]]][[1, []]]Failed
two row groups[[1, [1]], [2, [2]]][[1, [1]], [2, [2]]]Passed
null fact[[1, [None]]][[1, [None]]]Passed
duplicate fact[[1, [1, 1]]][[1, [1, 1]]]Passed
no categories[[1]][[1]]Passed
no facts[][]Passed

SHA-256 / 228bc2bece54d5a70a3fce0f72e51be0da695cb6c39497f023c610b8e34c90e0

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    try:
        rows,categories=d
        ids=list(dict.fromkeys(row[0] for row in rows))
        out=[]
        for ident in ids:
            record=[ident]
            for category in categories:
                cell=[value for i,c,value in rows if i==ident and c==category]
                record.append(cell if cell else None)
            out.append(record)
        return out
    except (IndexError, KeyError, ValueError, StopIteration) as exc:
        return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('column order', solve([[[1, 'a', 1], [1, 'b', 2]], ['b', 'a']]), [[1, [2], [1]]])
    check('unknown-only row', solve([[[1, 'z', 1]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 1], [2, 'a', 2]], ['a']]), [[1, [1]], [2, [2]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 1], [1, 'a', 1]], ['a']]), [[1, [1, 1]]])
    check('no categories', solve([[[1, 'a', 1]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 2:
    check('column order', solve([[[1, 'a', 2], [1, 'b', 3]], ['b', 'a']]), [[1, [3], [2]]])
    check('unknown-only row', solve([[[1, 'z', 2]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 2], [2, 'a', 3]], ['a']]), [[1, [2]], [2, [3]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 2], [1, 'a', 2]], ['a']]), [[1, [2, 2]]])
    check('no categories', solve([[[1, 'a', 2]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 3:
    check('column order', solve([[[1, 'a', 3], [1, 'b', 4]], ['b', 'a']]), [[1, [4], [3]]])
    check('unknown-only row', solve([[[1, 'z', 3]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 3], [2, 'a', 4]], ['a']]), [[1, [3]], [2, [4]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 3], [1, 'a', 3]], ['a']]), [[1, [3, 3]]])
    check('no categories', solve([[[1, 'a', 3]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 4:
    check('column order', solve([[[1, 'a', 4], [1, 'b', 5]], ['b', 'a']]), [[1, [5], [4]]])
    check('unknown-only row', solve([[[1, 'z', 4]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 4], [2, 'a', 5]], ['a']]), [[1, [4]], [2, [5]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 4], [1, 'a', 4]], ['a']]), [[1, [4, 4]]])
    check('no categories', solve([[[1, 'a', 4]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 5:
    check('column order', solve([[[1, 'a', 5], [1, 'b', 6]], ['b', 'a']]), [[1, [6], [5]]])
    check('unknown-only row', solve([[[1, 'z', 5]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 5], [2, 'a', 6]], ['a']]), [[1, [5]], [2, [6]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 5], [1, 'a', 5]], ['a']]), [[1, [5, 5]]])
    check('no categories', solve([[[1, 'a', 5]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
column order[[1, [2], [1]]][[1, [2], [1]]]Passed
unknown-only row[[1, None]][[1, []]]Failed
two row groups[[1, [1]], [2, [2]]][[1, [1]], [2, [2]]]Passed
null fact[[1, [None]]][[1, [None]]]Passed
duplicate fact[[1, [1, 1]]][[1, [1, 1]]]Passed
no categories[[1]][[1]]Passed
no facts[][]Passed

SHA-256 / c0ebda8743e4a26817d4292079bcb32e96ba6b72aa6b034569951134ec16d992

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    try:
        rows,categories=d
        ids=list(dict.fromkeys(row[0] for row in rows))
        out=[]
        for ident in ids:
            record=[ident]
            for category in categories:
                cell=[value for i,c,value in rows if i==ident and c==category]
                record.append(cell)
            out.append(record)
        return out
    except (IndexError, KeyError, ValueError, StopIteration) as exc:
        return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('column order', solve([[[1, 'a', 1], [1, 'b', 2]], ['b', 'a']]), [[1, [2], [1]]])
    check('unknown-only row', solve([[[1, 'z', 1]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 1], [2, 'a', 2]], ['a']]), [[1, [1]], [2, [2]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 1], [1, 'a', 1]], ['a']]), [[1, [1, 1]]])
    check('no categories', solve([[[1, 'a', 1]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 2:
    check('column order', solve([[[1, 'a', 2], [1, 'b', 3]], ['b', 'a']]), [[1, [3], [2]]])
    check('unknown-only row', solve([[[1, 'z', 2]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 2], [2, 'a', 3]], ['a']]), [[1, [2]], [2, [3]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 2], [1, 'a', 2]], ['a']]), [[1, [2, 2]]])
    check('no categories', solve([[[1, 'a', 2]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 3:
    check('column order', solve([[[1, 'a', 3], [1, 'b', 4]], ['b', 'a']]), [[1, [4], [3]]])
    check('unknown-only row', solve([[[1, 'z', 3]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 3], [2, 'a', 4]], ['a']]), [[1, [3]], [2, [4]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 3], [1, 'a', 3]], ['a']]), [[1, [3, 3]]])
    check('no categories', solve([[[1, 'a', 3]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 4:
    check('column order', solve([[[1, 'a', 4], [1, 'b', 5]], ['b', 'a']]), [[1, [5], [4]]])
    check('unknown-only row', solve([[[1, 'z', 4]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 4], [2, 'a', 5]], ['a']]), [[1, [4]], [2, [5]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 4], [1, 'a', 4]], ['a']]), [[1, [4, 4]]])
    check('no categories', solve([[[1, 'a', 4]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
elif N == 5:
    check('column order', solve([[[1, 'a', 5], [1, 'b', 6]], ['b', 'a']]), [[1, [6], [5]]])
    check('unknown-only row', solve([[[1, 'z', 5]], ['a']]), [[1, []]])
    check('two row groups', solve([[[1, 'a', 5], [2, 'a', 6]], ['a']]), [[1, [5]], [2, [6]]])
    check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
    check('duplicate fact', solve([[[1, 'a', 5], [1, 'a', 5]], ['a']]), [[1, [5, 5]]])
    check('no categories', solve([[[1, 'a', 5]], []]), [[1]])
    check('no facts', solve([[], ['a']]), [])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
column order[[1, [2], [1]]][[1, [2], [1]]]Passed
unknown-only row[[1, []]][[1, []]]Passed
two row groups[[1, [1]], [2, [2]]][[1, [1]], [2, [2]]]Passed
null fact[[1, [None]]][[1, [None]]]Passed
duplicate fact[[1, [1, 1]]][[1, [1, 1]]]Passed
no categories[[1]][[1]]Passed
no facts[][]Passed

SHA-256 / 2321267ab165b73e3dfda40a3391dbb8b81872432dbbb2c0dec96f9a9147cab9

Verification & scope

Offline stipulated semantics over valid small inputs; no performance, concurrency, or production-engine conformance claim. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:44:16.786632+00:00.

Case digest / 50027559c7556a3c327f244315bb1aedde4310300ddb0025064a65920dd3a34e