Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

       S1's root operator, i.e., an aggregate operator. Below the aggregate, there is a not-null-filter

       on variable v.

 

This is an abstract example for this rule: 

Before rewriting:

--Op1

  --Subplan{

    --AggregateOp

      --NestedOp

        .....

          --Nested-Tuple-Source

    }

    --InputOp

      .....

 

After rewriting:

--Op1

  --GroupBy v_lc_1, ..., v_lc_n Decor v_l1, ....v_ln {

            --AggregateOp

              --Select v_new!=NULL

                -- Nested-Tuple-Source

          }

     --LeftOuterJoin (v_lc_1=v_rc_1 AND .... AND v_lc_n=v_rc_n)

       (left branch)

         --InputOp

            .....

       (right branch)

         -- Assign v_new=TRUE

           --NestedOp

             .....

               --Deepcopy_The_Plan_Rooted_At_InputOp_With_New_Variables(InputOp)

 

In the plan, v_lc_1, ..., v_lc_n are live "covering" variables at InputOp,

while v_rc_1, ..., v_rc_n are their corresponding variables populated from the deepcopy of InputOp.

("Covering" variables form a set of variables that can imply all live variables.)

v_l1, ....v_ln in the decoration part of the added group-by operator are all

live variables at InputOp except the covering variables v_lc_1, ..., v_lc_n.

 

Here is a concrete example of the general case rewriting. 

Before plan:

distribute result [%0->$$27] -- |UNPARTITIONED|

  project ([$$27]) -- |UNPARTITIONED|

    assign [$$27] <- [function-call: asterix:open-record-constructor, Args:[AString: {subscription-id}, %0->$$35, AString: {execution-time}, function-call: asterix:current-datetimeArgs:[], AString: {result}, %0->$$6]] -- |UNPARTITIONED|

      unnest $$6 <- function-call: asterix:scan-collection, Args:[%0->$$26] -- |UNPARTITIONED|

        subplan {

                  aggregate [$$26] <- [function-call: asterix:listify, Args:[%0->$$22]] -- |UNPARTITIONED|

                    join (TRUE) -- |UNPARTITIONED|

                      select (%0->$$21) -- |UNPARTITIONED|

                        subplan {

                                  aggregate [$$21] <- [function-call: asterix:non-empty-stream, Args:[]] -- |UNPARTITIONED|

                                    join (function-call: algebricks:eq, Args:[%0->$$34, %0->$$7]) -- |UNPARTITIONED|

                                      nested tuple source -- |UNPARTITIONED|

                                      assign [$$34] <- [function-call: asterix:field-access-by-index, Args:[%0->$$10, AInt32: {1}]] -- |UNPARTITIONED|

                                        data-scan []<-[$$32, $$10] <- emergencyTest:userLocations -- |UNPARTITIONED|

                                          empty-tuple-source -- |UNPARTITIONED|

                               } -- |UNPARTITIONED|

                          data-scan []<-[$$31, $$8] <- emergencyTest:CHPReports -- |UNPARTITIONED|

                            nested tuple source -- |UNPARTITIONED|

                      assign [$$22] <- [function-call: asterix:open-record-constructor, Args:[AString: {shelter locations}, %0->$$25]] -- |UNPARTITIONED|

                        aggregate [$$25] <- [function-call: asterix:listify, Args:[%0->$$24]] -- |UNPARTITIONED|

                          assign [$$24] <- [function-call: asterix:field-access-by-index, Args:[%0->$$11, AInt32: {1}]] -- |UNPARTITIONED|

                            data-scan []<-[$$33, $$11] <- emergencyTest:tornadoShelters -- |UNPARTITIONED|

                              empty-tuple-source -- |UNPARTITIONED|

               } -- |UNPARTITIONED|

          assign [$$7] <- [function-call: asterix:field-access-by-index, Args:[%0->$$5, AInt32: {1}]] -- |UNPARTITIONED|

            assign [$$35] <- [function-call: asterix:field-access-by-name, Args:[%0->$$5, AString: {subscription-id}]] -- |UNPARTITIONED|

              data-scan []<-[$$30, $$5] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|

                empty-tuple-source -- |UNPARTITIONED|

 

After plan:

distribute result [%0->$$27] -- |UNPARTITIONED|

  project ([$$27]) -- |UNPARTITIONED|

    assign [$$27] <- [function-call: asterix:open-record-constructor, Args:[AString: {subscription-id}, %0->$$35, AString: {execution-time}, function-call: asterix:current-datetimeArgs:[], AString: {result}, %0->$$6]] -- |UNPARTITIONED|

      unnest $$6 <- function-call: asterix:scan-collection, Args:[%0->$$26] -- |UNPARTITIONED|

        group by ([$$44 := %0->$$30]) decor ([%0->$$35; %0->$$5; %0->$$7]) {

                  aggregate [$$26] <- [function-call: asterix:listify, Args:[%0->$$22]] -- |UNPARTITIONED|

                    select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$43]]) -- |UNPARTITIONED|

                      nested tuple source -- |UNPARTITIONED|

               } -- |UNPARTITIONED|

          left outer join (function-call: algebricks:eq, Args:[%0->$$30, %0->$$42]) -- |UNPARTITIONED|

            assign [$$7] <- [function-call: asterix:field-access-by-index, Args:[%0->$$5, AInt32: {1}]] -- |UNPARTITIONED|

              assign [$$35] <- [function-call: asterix:field-access-by-name, Args:[%0->$$5, AString: {subscription-id}]] -- |UNPARTITIONED|

                data-scan []<-[$$30, $$5] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|

                  empty-tuple-source -- |UNPARTITIONED|

            assign [$$43] <- [TRUE] -- |UNPARTITIONED|

              join (TRUE) -- |UNPARTITIONED|

                select (%0->$$21) -- |UNPARTITIONED|

                  group by ([$$37 := %0->$$31; $$42 := %0->$$41]) decor ([%0->$$40; %0->$$39; %0->$$38; %0->$$8]) {

                            aggregate [$$21] <- [function-call: asterix:non-empty-stream, Args:[]] -- |UNPARTITIONED|

                              select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$36]]) -- |UNPARTITIONED|

                                nested tuple source -- |UNPARTITIONED|

                         } -- |UNPARTITIONED|

                    left outer join (function-call: algebricks:eq, Args:[%0->$$34, %0->$$38]) -- |UNPARTITIONED|

                      data-scan []<-[$$31, $$8] <- emergencyTest:CHPReports -- |UNPARTITIONED|

                        assign [$$38] <- [function-call: asterix:field-access-by-index, Args:[%0->$$39, AInt32: {1}]] -- |UNPARTITIONED|

                          assign [$$40] <- [function-call: asterix:field-access-by-name, Args:[%0->$$39, AString: {subscription-id}]] -- |UNPARTITIONED|

                            data-scan []<-[$$41, $$39] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|

                              empty-tuple-source -- |UNPARTITIONED|

                      assign [$$36] <- [TRUE] -- |UNPARTITIONED|

                        assign [$$34] <- [function-call: asterix:field-access-by-index, Args:[%0->$$10, AInt32: {1}]] -- |UNPARTITIONED|

                          data-scan []<-[$$32, $$10] <- emergencyTest:userLocations -- |UNPARTITIONED|

                            empty-tuple-source -- |UNPARTITIONED|

                assign [$$22] <- [function-call: asterix:open-record-constructor, Args:[AString: {shelter locations}, %0->$$25]] -- |UNPARTITIONED|

                  aggregate [$$25] <- [function-call: asterix:listify, Args:[%0->$$24]] -- |UNPARTITIONED|

                    assign [$$24] <- [function-call: asterix:field-access-by-index, Args:[%0->$$11, AInt32: {1}]] -- |UNPARTITIONED|

                      data-scan []<-[$$33, $$11] <- emergencyTest:tornadoShelters -- |UNPARTITIONED|

                        empty-tuple-source -- |UNPARTITIONED|

 

 

For special cases where:

a. there is a join (let's call it J1.) in the nested plan,

...

R5'. All other NestedTupleSourceOperators in the subplan is inlined with a deep copy of the query plan rooted at O1.