()
| 1857 | |
| 1858 | #[mz_ore::test] |
| 1859 | fn test_nested_union_partial_overlap() { |
| 1860 | // `Nested(map)` constrains a key only when the key is present in `map`; absent |
| 1861 | // keys mean "anything". So the union of two Nested specs must drop any key |
| 1862 | // that's missing from one side, because `x ∪ anything = anything`. Only keys |
| 1863 | // present in *both* sides survive (with their per-key specs unioned). |
| 1864 | let a = ResultSpec::map_spec( |
| 1865 | [ |
| 1866 | ("x".into(), ResultSpec::value(Datum::String("a"))), |
| 1867 | ("y".into(), ResultSpec::value(Datum::String("b"))), |
| 1868 | ("c".into(), ResultSpec::value(Datum::String("c"))), |
| 1869 | ] |
| 1870 | .into_iter() |
| 1871 | .collect(), |
| 1872 | ); |
| 1873 | let b = ResultSpec::map_spec( |
| 1874 | [ |
| 1875 | ("x".into(), ResultSpec::value(Datum::String("a2"))), |
| 1876 | ("y".into(), ResultSpec::value(Datum::String("b2"))), |
| 1877 | ("z".into(), ResultSpec::value(Datum::String("z"))), |
| 1878 | ] |
| 1879 | .into_iter() |
| 1880 | .collect(), |
| 1881 | ); |
| 1882 | |
| 1883 | let unioned = a.union(b); |
| 1884 | |
| 1885 | // Push the unioned spec through `->> <key>`: keys only in one side must |
| 1886 | // admit NULL (the other side is unconstrained, so the field could be absent |
| 1887 | // there); shared keys must include both observed values. |
| 1888 | let arena = RowArena::new(); |
| 1889 | let relation = ReprRelationType::new(vec![ReprScalarType::Jsonb.nullable(false)]); |
| 1890 | |
| 1891 | // Key only in `a`: the union must admit NULL. |
| 1892 | { |
| 1893 | let mut interpreter = ColumnSpecs::new(&relation, &arena); |
| 1894 | interpreter.push_column(0, unioned.clone()); |
| 1895 | let expr = MirScalarExpr::column(0).call_binary( |
| 1896 | MirScalarExpr::literal_ok(Datum::from("c"), ReprScalarType::String), |
| 1897 | JsonbGetStringStringify, |
| 1898 | ); |
| 1899 | assert!(interpreter.expr(&expr).range.may_contain(Datum::Null)); |
| 1900 | } |
| 1901 | |
| 1902 | // Key only in `b`: symmetric. |
| 1903 | { |
| 1904 | let mut interpreter = ColumnSpecs::new(&relation, &arena); |
| 1905 | interpreter.push_column(0, unioned.clone()); |
| 1906 | let expr = MirScalarExpr::column(0).call_binary( |
| 1907 | MirScalarExpr::literal_ok(Datum::from("z"), ReprScalarType::String), |
| 1908 | JsonbGetStringStringify, |
| 1909 | ); |
| 1910 | assert!(interpreter.expr(&expr).range.may_contain(Datum::Null)); |
| 1911 | } |
| 1912 | |
| 1913 | // Key in both: result must include both observed values. |
| 1914 | { |
| 1915 | let mut interpreter = ColumnSpecs::new(&relation, &arena); |
| 1916 | interpreter.push_column(0, unioned); |
nothing calls this directly
no test coverage detected