...
When we generate the sub-tree for the _id expression of $bucket we end up with a giant plan that has s6 as an undefined slot accessor, 3] mkbson s30 [_id = s27, count = s29] true false [3] project [s29 = if (! exists (s28) || typeMatch (s28, 0x00000440), 0, doubleDoubleSumFinalize (s28))] [3] group [s27] [s28 = aggDoubleDoubleSum (1)] s2 [3] project [s27 = fillEmpty (s26, null)] [3] nlj [] [] left [2] mkbson s6 s4 [num] keep [] true false [1] scan s4 s5 none none none none [] @"e7d535a3-511e-4d2e-b17a-7c62e468b67f" true false right [3] limit 1 [3] union [s26] [ [s24] [3] nlj [s11] [s11] left [3] filter {let [l15.0 = s11] exists (l15.0) && ! typeMatch (l15.0, 0x00000440) && l15.0 false != 0 && l15.0 0 != 0} [3] limit 1 [3] union [s11] [ [s9] [3] project [s9 = false] [3] filter {! let [l4.0 = let [l1.0 = s7, l1.1 = "1"] fillEmpty (l1.0 [s2] l1.1 >= 0, exists (l1.0) && typeMatch (l1.0, 0xFFFFFFBF) >= exists (l1.1) && typeMatch (l1.1, 0xFFFFFFBF))] exists (l4.0) && ! typeMatch (l4.0, 0x00000440) && l4.0 false != 0 && l4.0 0 != 0} [3] project [s7 = getField (s6, "num")] [3] limit 1 [3] coscan , [s10] [3] project [s10 = let [l3.0 = let [l2.0 = s8, l2.1 = "10"] fillEmpty (l2.0 [s2] l2.1 false != 0 && l3.0 0 != 0] [3] project [s8 = getField (s6, "num")] [3] limit 1 [3] coscan ] right [3] project [s24 = "1"] [3] limit 1 [3] coscan , [s23] [3] nlj [s16] [s16] left [3] filter {let [l14.0 = s16] exists (l14.0) && ! typeMatch (l14.0, 0x00000440) && l14.0 false != 0 && l14.0 0 != 0} [3] limit 1 [3] union [s16] [ [s14] [3] project [s14 = false] [3] filter {! let [l8.0 = let [l5.0 = s12, l5.1 = "10"] fillEmpty (l5.0 [s2] l5.1 >= 0, exists (l5.0) && typeMatch (l5.0, 0xFFFFFFBF) >= exists (l5.1) && typeMatch (l5.1, 0xFFFFFFBF))] exists (l8.0) && ! typeMatch (l8.0, 0x00000440) && l8.0 false != 0 && l8.0 0 != 0} [3] project [s12 = getField (s6, "num")] [3] limit 1 [3] coscan , [s15] [3] project [s15 = let [l7.0 = let [l6.0 = s13, l6.1 = "100"] fillEmpty (l6.0 [s2] l6.1 false != 0 && l7.0 0 != 0] [3] project [s13 = getField (s6, "num")] [3] limit 1 [3] coscan ] right [3] project [s23 = "10"] [3] limit 1 [3] coscan , [s22] [3] nlj [s21] [s21] left [3] filter {let [l13.0 = s21] exists (l13.0) && ! typeMatch (l13.0, 0x00000440) && l13.0 false != 0 && l13.0 0 != 0} [3] limit 1 [3] union [s21] [ [s19] [3] project [s19 = false] [3] filter {! let [l12.0 = let [l9.0 = s17, l9.1 = "100"] fillEmpty (l9.0 [s2] l9.1 >= 0, exists (l9.0) && typeMatch (l9.0, 0xFFFFFFBF) >= exists (l9.1) && typeMatch (l9.1, 0xFFFFFFBF))] exists (l12.0) && ! typeMatch (l12.0, 0x00000440) && l12.0 false != 0 && l12.0 0 != 0} [3] project [s17 = getField (s6, "num")] [3] limit 1 [3] coscan , [s20] [3] project [s20 = let [l11.0 = let [l10.0 = s18, l10.1 = "1000"] fillEmpty (l10.0 [s2] l10.1 false != 0 && l11.0 0 != 0] [3] project [s18 = getField (s6, "num")] [3] limit 1 [3] coscan ] right [3] project [s22 = "100"] [3] limit 1 [3] coscan , [s25] [3] project [s25 = fail ( 4934200 ,$switch could not find a matching branch for an input, and no default was specified.)] [3] limit 1 [3] coscan ] Note: I believe there's another build failure due to the same issue, it might be nice to see if this fix also fixes this failure, https://evergreen.mongodb.com/lobster/build/ca9324421d26b1c4be849f9c5d7f086f/test/61493e37be07c444b80485e2#bookmarks=0%2C105&l=1&shareLine=18
JIRAUSER1259052 commented on Wed, 6 Oct 2021 17:27:59 +0000: Updating the fixversion since branching activities occurred yesterday. This ticket will be in rc0 when it’s been triggered. For more active release information, please keep an eye on #server-release. Thank you! xgen-internal-githook commented on Thu, 23 Sep 2021 00:05:04 +0000: Author: {'name': 'Yoonsoo Kim', 'email': 'yoonsoo.kim@mongodb.com', 'username': 'yun-soo'} Message: SERVER-60152 Add the proper out slot for child eval stage Branch: master https://github.com/mongodb/mongo/commit/4ae62e32c166d8483992ff49d53c00d238ba1aea JIRAUSER1258488 commented on Wed, 22 Sep 2021 23:15:30 +0000: The root cause was generateExpression expects that EvalStage stage param has a valid outSlot but was not given. So, generated top nlj could not set up correlated slot(s) properly. JIRAUSER1258488 commented on Wed, 22 Sep 2021 22:27:14 +0000: For coll.aggregate([{$bucket: {groupBy: "$num", boundaries: ["1", "10"]}}])'s id expression, got the following plan tree. [3] project [s14 = fillEmpty (s13, null)] [3] nlj [] [] left [2] mkbson s5 s3 [num] keep [] true false [1] scan s3 s4 none none none none [] @"e841372d-2bf1-4ff4-9beb-ccb485a99202" true false right [3] limit 1 [3] union [s13] [ [s11] [3] nlj [s10] [s10] left [3] filter {let [l5.0 = s10] exists (l5.0) && ! typeMatch (l5.0, 0x00000440) && l5.0 false != 0 && l5.0 0 != 0} [3] limit 1 [3] union [s10] [ [s8] [3] project [s8 = false] [3] filter {! let [l4.0 = let [l1.0 = s6, l1.1 = "1"] fillEmpty (l1.0 l1.1 >= 0, exists (l1.0) && typeMatch (l1.0, 0xFFFFFFBF) >= exists (l1.1) && typeMatch (l1.1, 0xFFFFFFBF))] exists (l4.0) && ! typeMatch (l4.0, 0x00000440) && l4.0 false != 0 && l4.0 0 != 0} [3] project [s6 = getField (s5, "num")] [3] limit 1 [3] coscan , [s9] [3] project [s9 = let [l3.0 = let [l2.0 = s7, l2.1 = "10"] fillEmpty (l2.0 l2.1 false != 0 && l3.0 0 != 0] [3] project [s7 = getField (s5, "num")] [3] limit 1 [3] coscan ] right [3] project [s11 = "1"] [3] limit 1 [3] coscan , [s12] [3] project [s12 = fail ( 4934200 ,$switch could not find a matching branch for an input, and no default was specified.)] [3] limit 1 [3] coscan ] nlj's inner side refers to s5 but we didn't set up correlated slots properly for nlj. nlj [] [] should nlj [s5] [s5] JIRAUSER1258488 commented on Wed, 22 Sep 2021 20:19:21 +0000: It looks like there might be a bug in converting boundaries to $switch, looking at the following output: [s24] [3] project [s24 = fail ( 4934200 ,$switch could not find a matching branch for an input, and no default was specified.)] There is supposed to be a case for "1000" above. Instead, we got an error: "$switch could not find a matching branch for an input, and no default was specified". Likely we missed adding "default" case when we convert $bucket's boundaries to $switch. Update: this was not relevant to a root cause. Please, disregard this comment. JIRAUSER1258488 commented on Wed, 22 Sep 2021 20:03:04 +0000: eric.cox, thanks for the minimal repro!
Start a mongod with the `featureFlagSBEGroupPushdown` flag on, ./build/ninja/install/bin/mongod --setParameter internalQueryEnableSlotBasedExecutionEngine=true --setParameter featureFlagSBEGroupPushdown=true In the shell var coll = db.collation_bucket; coll.drop(); function insertData() { coll.insert([ {num: "1"}, {num: "2"}, {num: "5"}, {num: "10"}, {num: "20"}, {num: "50"}, {num: "100"}, {num: "200"}, {num: "500"}, ]); } insertData(); coll.aggregate([{$bucket: {groupBy: "$num", boundaries: ["1", "10", "100", "1000"]}}]); > uncaught exception: Error: command failed: {uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "undefined slot accessor:5", "code" : 4946301, "codeName" : "Location4946301"} with original command request: { "aggregate" : "collation_bucket", "pipeline" : [ { "$bucket" : { "groupBy" : "$num", "boundaries" : [ "1", "10", "100", "1000" ] } } ], "explain" : true, "cursor" : { }, "lsid" : { "id" : UUID("931d91de-ed3d-4af1-87df-66c2c15444d4") } The best place to drop the DebugPrinter statement is here, diff --git a/src/mongo/db/query/sbe_stage_builder.cpp b/src/mongo/db/query/sbe_stage_builder.cpp index 1b772d0276..bf5c7545c9 100644 --- a/src/mongo/db/query/sbe_stage_builder.cpp +++ b/src/mongo/db/query/sbe_stage_builder.cpp @@ -688,6 +688,8 @@ std::unique_ptr SlotBasedStageBuilder::build(const QuerySolution // Build the SBE plan stage tree. auto [stage, outputs] = build(root, reqs); + sbe::DebugPrinter p; + std::cerr << p.print(*stage.get()) << "\n";