[SERVER-71717] Remove MakeObjSpec and model projections with 'keep/dropField' in sbe_stage_builder_projection.cpp Created: 30/Nov/22  Updated: 19/May/23

Status: Open
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Mihai Andrei Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 0
Labels: pm2697-m4
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Query Execution
Sprint: QE 2023-05-15
Participants:
Story Points: 10

 Description   

Consider the projection {_id: 0, "a.b.c": 1}. Currently, the projection stage builder will produce the following plan:

[2] project [s6 = traverseP(s4, lambda(l1.0) {
    if isObject(l1.0)
    then makeBsonObj(MakeObjSpec(keep, [], ["a"]), l1.0, traverseP(getField(l1.0, "a"), lambda(l2.0) {
        if isObject(l2.0)
        then makeBsonObj(MakeObjSpec(keep, [], ["b"]), l2.0, traverseP(getField(l2.0, "b"), lambda(l3.0) {
            if isObject(l3.0)
            then makeBsonObj(MakeObjSpec(keep, ["c"], []), l3.0)
            else Nothing
        }, Nothing))
        else Nothing
    }, Nothing))
    else Nothing
}, Nothing)]
[1] scan s4 s5 none none none none [] @"9b7f08cc-f7c3-4d13-957a-a824db1bb046" true false

This plan makes use of the `makeBsonObj` vm instruction. Compare this to the plan generated by the optimizer, which uses keep/dropFields to implement the projection:

plan : [2] project [s2 =
    let [
        l101.0 =
            if isObject(s1)
            then keepFields(s1, "a")
            else s1
    ]
    in
        let [
            l102.0 = traverseP(getField(l101.0, "a"), lambda(l103.0) {
                let [
                    l104.0 =
                        let [
                            l105.0 =
                                if isObject(l103.0)
                                then move(l103.0)
                                else Nothing
                        ]
                        in
                            if isObject(l105.0)
                            then keepFields(move(l105.0), "b")
                            else move(l105.0)
                ]
                in
                    let [
                        l106.0 = traverseP(getField(l104.0, "b"), lambda(l107.0) {
                            let [
                                l108.0 =
                                    if isObject(l107.0)
                                    then move(l107.0)
                                    else Nothing
                            ]
                            in
                                if isObject(l108.0)
                                then keepFields(move(l108.0), "c")
                                else move(l108.0)
                        }, Nothing)
                    ]
                    in
                        if (exists(l106.0) || isObject(l104.0))
                        then setField(move(l104.0), "b", move(l106.0))
                        else move(l104.0)
            }, Nothing)
        ]
        in
            if (exists(l102.0) || isObject(l101.0))
            then setField(move(l101.0), "a", move(l102.0))
            else move(l101.0)

This ticket tracks the work to replace MakeObjSpec with keep/dropFields and to remove MakeObjSpec



 Comments   
Comment by David Storch [ 19/May/23 ]

Thanks kyle.suarez@mongodb.com that sounds right to me!

Comment by Kyle Suarez [ 18/May/23 ]

andrew.paroski@mongodb.com, mihai.andrei@mongodb.com, david.storch@mongodb.com, since this ticket is in the SBE post-7.0 project I am unassigning this from Drew and removing it from the sprint. Please let me know if this actually has to be prioritized soon – I am assuming not. CC amr.elhelw@mongodb.com

Generated at Thu Feb 08 06:19:47 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.