// SERVER-20163 introduced the $zip expression. In this test file, we check the behavior and error // cases of the expression. import "jstests/libs/query/sbe_assert_error_override.js"; import {assertErrorCode} from "jstests/aggregation/extras/utils.js"; let coll = db.zip; coll.drop(); coll.insert({"long": [1, 2, 3], "short": ["x", "y"]}); let zipObj = 3; assertErrorCode(coll, [{$project: {zipped: {$zip: zipObj}}}], 34460, "$zip requires an object" + " as an argument."); zipObj = { inputs: [], }; assertErrorCode(coll, [{$project: {zipped: {$zip: zipObj}}}], 34465, "$zip requires at least" + " one input array"); zipObj = { inputs: {"a": "b"}, }; assertErrorCode(coll, [{$project: {zipped: {$zip: zipObj}}}], 34461, "inputs is not an array"); zipObj = { inputs: ["$a"], defaults: ["A"], }; assertErrorCode( coll, [{$project: {zipped: {$zip: zipObj}}}], 34466, "cannot specify defaults" + " unless useLongestLength is true.", ); zipObj = { inputs: ["$a"], defaults: ["A", "B"], useLongestLength: true, }; assertErrorCode( coll, [{$project: {zipped: {$zip: zipObj}}}], 34467, "inputs and defaults" + " must be the same length.", ); zipObj = { inputs: ["$a"], defaults: {"a": "b"}, }; assertErrorCode(coll, [{$project: {zipped: {$zip: zipObj}}}], 34462, "defaults is not an" + " array"); zipObj = { inputs: ["$a"], defaults: ["A"], useLongestLength: 1, }; assertErrorCode(coll, [{$project: {zipped: {$zip: zipObj}}}], 34463, "useLongestLength is not" + " a bool"); zipObj = { inputs: ["$a", "$b"], defaults: ["A"], notAField: 1, }; assertErrorCode(coll, [{$project: {zipped: {$zip: zipObj}}}], 34464, "unknown argument"); zipObj = { inputs: ["A", "B"], }; assertErrorCode(coll, [{$project: {zipped: {$zip: zipObj}}}], 34468, "an element of inputs" + " was not an array."); zipObj = { inputs: [ [1, 2, 3], ["A", "B", "C"], ], }; let res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); let output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ [1, "A"], [2, "B"], [3, "C"], ]); zipObj = { inputs: [[1, 2, 3], null], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, null); zipObj = { inputs: [null, [1, 2, 3]], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, null); zipObj = { inputs: ["$missing", [1, 2, 3]], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, null); zipObj = { inputs: [undefined, [1, 2, 3]], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, null); zipObj = { inputs: [ [1, 2, 3], ["A", "B"], ], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ [1, "A"], [2, "B"], ]); zipObj = { inputs: [ ["A", "B"], [1, 2, 3], ], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ ["A", 1], ["B", 2], ]); zipObj = { inputs: [[], []], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, []); zipObj = { inputs: [["$short"], ["$long"]], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ [ ["x", "y"], [1, 2, 3], ], ]); zipObj = { inputs: ["$short", "$long"], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ ["x", 1], ["y", 2], ]); zipObj = { inputs: [["$long"]], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [[[1, 2, 3]]]); zipObj = { inputs: [ [1, 2, 3], ["a", "b", "c"], ["c", "b", "a"], ], }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ [1, "a", "c"], [2, "b", "b"], [3, "c", "a"], ]); zipObj = { inputs: [ [1, 2, 3], ["A", "B"], ], defaults: ["C", "D"], useLongestLength: true, }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ [1, "A"], [2, "B"], [3, "D"], ]); zipObj = { inputs: [ [1, 2, 3], ["A", "B"], ], useLongestLength: true, }; res = coll.aggregate([{$project: {zipped: {$zip: zipObj}}}]); output = res.toArray(); assert.eq(1, output.length); assert.eq(output[0].zipped, [ [1, "A"], [2, "B"], [3, null], ]);