diff --git a/be/src/exec/analytic-eval-node.cc b/be/src/exec/analytic-eval-node.cc index 3a3f0e25e..3a244dab3 100644 --- a/be/src/exec/analytic-eval-node.cc +++ b/be/src/exec/analytic-eval-node.cc @@ -131,6 +131,7 @@ Status AnalyticEvalNode::Prepare(RuntimeState* state) { curr_tuple_pool_.reset(new MemPool(mem_tracker())); prev_tuple_pool_.reset(new MemPool(mem_tracker())); mem_pool_.reset(new MemPool(mem_tracker())); + fn_pool_.reset(new MemPool(mem_tracker())); evaluation_timer_ = ADD_TIMER(runtime_profile(), "EvaluationTime"); DCHECK_EQ(result_tuple_desc_->slots().size(), evaluators_.size()); @@ -138,7 +139,7 @@ Status AnalyticEvalNode::Prepare(RuntimeState* state) { impala_udf::FunctionContext* ctx; RETURN_IF_ERROR(evaluators_[i]->Prepare(state, child(0)->row_desc(), intermediate_tuple_desc_->slots()[i], result_tuple_desc_->slots()[i], - mem_pool_.get(), &ctx)); + fn_pool_.get(), &ctx)); fn_ctxs_.push_back(ctx); state->obj_pool()->Add(ctx); } @@ -172,11 +173,10 @@ Status AnalyticEvalNode::Open(RuntimeState* state) { RETURN_IF_ERROR(QueryMaintenance(state)); RETURN_IF_ERROR(child(0)->Open(state)); DCHECK(client_ != NULL); - // TODO: Set delete_on_read to false if this node is inside a subplan. input_stream_.reset(new BufferedTupleStream(state, child(0)->row_desc(), state->block_mgr(), client_, false /* initial_small_buffers */, - true /* delete_on_read */, + !IsInSubplan() /* delete_on_read */, true /* read_write */)); RETURN_IF_ERROR(input_stream_->Init(id(), runtime_profile(), true)); @@ -810,6 +810,7 @@ void AnalyticEvalNode::Close(RuntimeState* state) { if (curr_tuple_pool_.get() != NULL) curr_tuple_pool_->FreeAll(); if (prev_tuple_pool_.get() != NULL) prev_tuple_pool_->FreeAll(); if (mem_pool_.get() != NULL) mem_pool_->FreeAll(); + if (fn_pool_.get() != NULL) fn_pool_->FreeAll(); ExecNode::Close(state); } diff --git a/be/src/exec/analytic-eval-node.h b/be/src/exec/analytic-eval-node.h index aad2948ca..d2e09407a 100644 --- a/be/src/exec/analytic-eval-node.h +++ b/be/src/exec/analytic-eval-node.h @@ -230,6 +230,11 @@ class AnalyticEvalNode : public ExecNode { /// functions is allocated via these contexts. std::vector fn_ctxs_; + /// Mem pool backing allocations from fn_ctxs_. This pool must not be Reset() because + /// the memory is managed by the FreePools of the function contexts which do their own + /// bookkeeping using a pointer-based structure stored in the memory blocks themselves. + boost::scoped_ptr fn_pool_; + /// Pools used to allocate result tuples (added to result_tuples_ and later returned) /// and window tuples (added to window_tuples_ to buffer the current window). Resources /// are transferred from curr_tuple_pool_ to prev_tuple_pool_ once it is at least diff --git a/testdata/workloads/functional-query/queries/QueryTest/nested-types-subplan.test b/testdata/workloads/functional-query/queries/QueryTest/nested-types-subplan.test index f19672daf..f6dca865b 100644 --- a/testdata/workloads/functional-query/queries/QueryTest/nested-types-subplan.test +++ b/testdata/workloads/functional-query/queries/QueryTest/nested-types-subplan.test @@ -200,6 +200,59 @@ where c_custkey < 4 bigint,string,bigint,decimal,decimal,string,string ==== ---- QUERY +# Test analytic functions without partition by and order by inside a subplan. +select c_custkey, v.* from customer c, + (select count(o_orderkey) over() c, sum(o_totalprice) over() s, + avg(o_totalprice) over() a, max(o_orderstatus) over() mx, + min(o_orderdate) over() mn + from c.c_orders) v +where c_custkey < 4 +---- RESULTS +1,6,587762.91,97960.48,'O','1992-04-19' +1,6,587762.91,97960.48,'O','1992-04-19' +1,6,587762.91,97960.48,'O','1992-04-19' +1,6,587762.91,97960.48,'O','1992-04-19' +1,6,587762.91,97960.48,'O','1992-04-19' +1,6,587762.91,97960.48,'O','1992-04-19' +2,7,1028273.43,146896.20,'P','1992-04-05' +2,7,1028273.43,146896.20,'P','1992-04-05' +2,7,1028273.43,146896.20,'P','1992-04-05' +2,7,1028273.43,146896.20,'P','1992-04-05' +2,7,1028273.43,146896.20,'P','1992-04-05' +2,7,1028273.43,146896.20,'P','1992-04-05' +2,7,1028273.43,146896.20,'P','1992-04-05' +---- TYPES +bigint,bigint,decimal,decimal,string,string +==== +---- QUERY +# Test analytic functions with partition by inside a subplan. +select c_custkey, v.* from customer c, +(select o_orderstatus, + count(o_orderkey) over(partition by o_orderstatus) c, + sum(o_totalprice) over(partition by o_orderstatus) s, + avg(o_totalprice) over(partition by o_orderstatus) a, + max(o_orderstatus) over(partition by o_orderstatus) mx, + min(o_orderdate) over(partition by o_orderstatus) mn +from c.c_orders) v +where c_custkey < 4 +---- RESULTS +1,'F',2,197679.65,98839.82,'F','1992-04-19' +1,'F',2,197679.65,98839.82,'F','1992-04-19' +1,'O',4,390083.26,97520.81,'O','1996-06-29' +1,'O',4,390083.26,97520.81,'O','1996-06-29' +1,'O',4,390083.26,97520.81,'O','1996-06-29' +1,'O',4,390083.26,97520.81,'O','1996-06-29' +2,'F',4,319892.45,79973.11,'F','1992-04-05' +2,'F',4,319892.45,79973.11,'F','1992-04-05' +2,'F',4,319892.45,79973.11,'F','1992-04-05' +2,'F',4,319892.45,79973.11,'F','1992-04-05' +2,'O',2,486983.63,243491.81,'O','1996-08-05' +2,'O',2,486983.63,243491.81,'O','1996-08-05' +2,'P',1,221397.35,221397.35,'P','1995-03-10' +---- TYPES +bigint,string,bigint,decimal,decimal,string,string +==== +---- QUERY # Test left outer join of a relative table ref. select c_custkey, c_mktsegment, o_orderkey, o_orderdate from customer c left outer join c.c_orders