| 106 | } |
| 107 | |
| 108 | AnalyticEvalNode::AnalyticEvalNode(ObjectPool* pool, const AnalyticEvalPlanNode& pnode, |
| 109 | const TAnalyticNode& analytic_node, const DescriptorTbl& descs) |
| 110 | : ExecNode(pool, pnode, descs), |
| 111 | window_(analytic_node.window), |
| 112 | intermediate_tuple_desc_( |
| 113 | descs.GetTupleDescriptor(analytic_node.intermediate_tuple_id)), |
| 114 | result_tuple_desc_(descs.GetTupleDescriptor(analytic_node.output_tuple_id)), |
| 115 | partition_by_eq_expr_(pnode.partition_by_eq_expr_), |
| 116 | order_by_eq_expr_(pnode.order_by_eq_expr_), |
| 117 | analytic_fns_(pnode.analytic_fns_), |
| 118 | is_lead_fn_(pnode.is_lead_fn_) { |
| 119 | if (analytic_node.__isset.buffered_tuple_id) { |
| 120 | buffered_tuple_desc_ = |
| 121 | descs.GetTupleDescriptor(analytic_node.buffered_tuple_id); |
| 122 | } |
| 123 | if (!analytic_node.__isset.window) { |
| 124 | fn_scope_ = AnalyticEvalNode::PARTITION; |
| 125 | } else if (analytic_node.window.type == TAnalyticWindowType::RANGE) { |
| 126 | fn_scope_ = AnalyticEvalNode::RANGE; |
| 127 | DCHECK(!window_.__isset.window_start) |
| 128 | << "RANGE windows must have UNBOUNDED PRECEDING"; |
| 129 | DCHECK(!window_.__isset.window_end |
| 130 | || window_.window_end.type == TAnalyticWindowBoundaryType::CURRENT_ROW) |
| 131 | << "RANGE window end bound must be CURRENT ROW or UNBOUNDED FOLLOWING"; |
| 132 | } else { |
| 133 | DCHECK_EQ(analytic_node.window.type, TAnalyticWindowType::ROWS); |
| 134 | fn_scope_ = AnalyticEvalNode::ROWS; |
| 135 | if (window_.__isset.window_start) { |
| 136 | TAnalyticWindowBoundary b = window_.window_start; |
| 137 | if (b.__isset.rows_offset_value) { |
| 138 | rows_start_offset_ = b.rows_offset_value; |
| 139 | if (b.type == TAnalyticWindowBoundaryType::PRECEDING) rows_start_offset_ *= -1; |
| 140 | } else { |
| 141 | DCHECK_EQ(b.type, TAnalyticWindowBoundaryType::CURRENT_ROW); |
| 142 | rows_start_offset_ = 0; |
| 143 | } |
| 144 | } |
| 145 | if (window_.__isset.window_end) { |
| 146 | TAnalyticWindowBoundary b = window_.window_end; |
| 147 | if (b.__isset.rows_offset_value) { |
| 148 | rows_end_offset_ = b.rows_offset_value; |
| 149 | if (b.type == TAnalyticWindowBoundaryType::PRECEDING) rows_end_offset_ *= -1; |
| 150 | } else { |
| 151 | DCHECK_EQ(b.type, TAnalyticWindowBoundaryType::CURRENT_ROW); |
| 152 | rows_end_offset_ = 0; |
| 153 | } |
| 154 | } |
| 155 | } |
| 156 | VLOG_FILE << id() << " Window=" << DebugWindowString(); |
| 157 | } |
| 158 | |
| 159 | AnalyticEvalNode::~AnalyticEvalNode() { |
| 160 | // Check that we didn't leak any memory. |
nothing calls this directly
no test coverage detected