/* * Helper method responsible for inserting the results of the aggregation * into a new tuple in the output tile group as well as passing through any * additional columns from the input tile group. * * Output tuple is projected from two tuples: * Left is the 'delegate' tuple, which is usually the first tuple in the group, * used to retrieve pass-through values; * Right is the tuple holding all aggregated values. */ bool Helper(const planner::AggregatePlan *node, AbstractAttributeAggregator **aggregates, storage::AbstractTable *output_table, const AbstractTuple *delegate_tuple, executor::ExecutorContext *econtext) { auto schema = output_table->GetSchema(); std::unique_ptr<storage::Tuple> tuple(new storage::Tuple(schema, true)); /* * 1) Construct a vector of aggregated values */ std::vector<type::Value> aggregate_values; auto &aggregate_terms = node->GetUniqueAggTerms(); for (oid_t column_itr = 0; column_itr < aggregate_terms.size(); column_itr++) { if (aggregates[column_itr] != nullptr) { type::Value final_val = aggregates[column_itr]->Finalize(); aggregate_values.push_back(final_val); } } /* * 2) Evaluate filter predicate; * if fail, just return */ std::unique_ptr<ContainerTuple<std::vector<type::Value>>> aggref_tuple(new ContainerTuple<std::vector<type::Value>>( &aggregate_values)); auto predicate = node->GetPredicate(); if (nullptr != predicate && (predicate->Evaluate(delegate_tuple, aggref_tuple.get(), econtext)) .IsFalse()) { return true; // Qual fails, do nothing } /* * 3) Construct the tuple to insert using projectInfo */ node->GetProjectInfo()->Evaluate(tuple.get(), delegate_tuple, aggref_tuple.get(), econtext); LOG_TRACE("Tuple to Output :"); LOG_TRACE("GROUP TUPLE :: %s", tuple->GetInfo().c_str()); // IMPORTANT: The output table *has* to set the tuple as active. // Otherwise the LogicalTileWrapper will think that it has no tuples. // Note that only TempTable does this. DataTable does not. auto location = output_table->InsertTuple(tuple.get()); if (location.block == INVALID_OID) { LOG_ERROR("Failed to insert tuple "); return false; } return true; }
/* * Helper method responsible for inserting the results of the aggregation * into a new tuple in the output tile group as well as passing through any * additional columns from the input tile group. * * Output tuple is projected from two tuples: * Left is the 'delegate' tuple, which is usually the first tuple in the group, * used to retrieve pass-through values; * Right is the tuple holding all aggregated values. */ bool Helper(const planner::AggregatePlan *node, Agg **aggregates, storage::DataTable *output_table, const AbstractTuple *delegate_tuple, executor::ExecutorContext *econtext) { auto schema = output_table->GetSchema(); std::unique_ptr<storage::Tuple> tuple(new storage::Tuple(schema, true)); /* * 1) Construct a vector of aggregated values */ std::vector<common::Value> aggregate_values; auto &aggregate_terms = node->GetUniqueAggTerms(); for (oid_t column_itr = 0; column_itr < aggregate_terms.size(); column_itr++) { if (aggregates[column_itr] != nullptr) { common::Value final_val = aggregates[column_itr]->Finalize(); aggregate_values.push_back(final_val); } } /* * 2) Evaluate filter predicate; * if fail, just return */ std::unique_ptr<expression::ContainerTuple<std::vector<common::Value>>> aggref_tuple( new expression::ContainerTuple<std::vector<common::Value>>(&aggregate_values)); auto predicate = node->GetPredicate(); if (nullptr != predicate && (predicate->Evaluate(delegate_tuple, aggref_tuple.get(), econtext)).IsFalse()) { return true; // Qual fails, do nothing } /* * 3) Construct the tuple to insert using projectInfo */ node->GetProjectInfo()->Evaluate(tuple.get(), delegate_tuple, aggref_tuple.get(), econtext); LOG_TRACE("Tuple to Output :"); LOG_TRACE("GROUP TUPLE :: %s", tuple->GetInfo().c_str()); auto location = output_table->InsertTuple(tuple.get()); if (location.block == INVALID_OID) { LOG_ERROR("Failed to insert tuple "); return false; } else { auto &manager = catalog::Manager::GetInstance(); auto tile_group_header = manager.GetTileGroup(location.block)->GetHeader(); tile_group_header->SetTransactionId(location.offset, INITIAL_TXN_ID); } return true; }