bool SeqScanPlan::SerializeTo(SerializeOutput &output) { // A placeholder for the total size written at the end int start = output.Position(); output.WriteInt(-1); // Write the SeqScanPlan type PlanNodeType plan_type = GetPlanNodeType(); output.WriteByte(static_cast<int8_t>(plan_type)); // Write database id and table id if (!GetTable()) { // The plan is not completed return false; } oid_t database_id = GetTable()->GetDatabaseOid(); oid_t table_id = GetTable()->GetOid(); output.WriteInt(static_cast<int>(database_id)); output.WriteInt(static_cast<int>(table_id)); // If column has 0 item, just write the columnid_count with 0 int columnid_count = GetColumnIds().size(); output.WriteInt(columnid_count); // If column has 0 item, nothing happens here for (int it = 0; it < columnid_count; it++) { oid_t col_id = GetColumnIds()[it]; output.WriteInt(static_cast<int>(col_id)); } // Write predicate if (GetPredicate() == nullptr) { // Write the type output.WriteByte(static_cast<int8_t>(EXPRESSION_TYPE_INVALID)); } else { // Write the expression type ExpressionType expr_type = GetPredicate()->GetExpressionType(); output.WriteByte(static_cast<int8_t>(expr_type)); } // Write parent, but parent seems never be set or used right now if (GetParent() == nullptr) { // Write the type output.WriteByte(static_cast<int8_t>(PLAN_NODE_TYPE_INVALID)); } else { // Write the parent type PlanNodeType parent_type = GetParent()->GetPlanNodeType(); output.WriteByte(static_cast<int8_t>(parent_type)); // Write parent GetParent()->SerializeTo(output); } // Write the total length int32_t sz = static_cast<int32_t>(output.Position() - start - sizeof(int)); PL_ASSERT(sz > 0); output.WriteIntAt(start, sz); return true; }
// Generate the body of the vectorized scan void TableScanTranslator::ScanConsumer::ProcessTuples( CodeGen &codegen, llvm::Value *tid_start, llvm::Value *tid_end, TileGroup::TileGroupAccess &tile_group_access) { // TODO: Should visibility check be done here or in codegen::Table/TileGroup? // 1. Filter the rows in the range [tid_start, tid_end) by txn visibility FilterRowsByVisibility(codegen, tid_start, tid_end, selection_vector_); // 2. Filter rows by the given predicate (if one exists) auto *predicate = GetPredicate(); if (predicate != nullptr) { // First perform a vectorized filter, putting TIDs into the selection vector FilterRowsByPredicate(codegen, tile_group_access, tid_start, tid_end, selection_vector_); } // 3. Setup the (filtered) row batch and setup attribute accessors RowBatch batch{translator_.GetCompilationContext(), tile_group_id_, tid_start, tid_end, selection_vector_, true}; std::vector<TableScanTranslator::AttributeAccess> attribute_accesses; SetupRowBatch(batch, tile_group_access, attribute_accesses); // 4. Push the batch into the pipeline ConsumerContext context{translator_.GetCompilationContext(), translator_.GetPipeline()}; context.Consume(batch); }
void OperatorToPlanTransformer::Visit(const PhysicalScan *op) { std::vector<oid_t> column_ids; auto predicate_prop = requirements_->GetPropertyOfType(PropertyType::PREDICATE) ->As<PropertyPredicate>(); expression::AbstractExpression *predicate = nullptr; if (predicate_prop != nullptr) { predicate = predicate_prop->GetPredicate()->Copy(); } auto column_prop = requirements_->GetPropertyOfType(PropertyType::COLUMNS) ->As<PropertyColumns>(); PL_ASSERT(column_prop != nullptr); for (size_t column_idx = 0; column_idx < column_prop->GetSize(); column_idx++) { column_ids.push_back(column_prop->GetColumn(column_idx) ->As<TableColumn>() ->ColumnIndexOid()); } output_plan_.reset( new planner::SeqScanPlan(op->table_, predicate, column_ids)); }
void LaunchSeqScan(std::unique_ptr<storage::DataTable> &hyadapt_table) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); // Column ids to be added to logical tile after scan. std::vector<oid_t> column_ids; std::vector<oid_t> hyadapt_column_ids; oid_t query_column_count = projectivity * column_count; GenerateSequence(hyadapt_column_ids, query_column_count); for (oid_t col_itr = 0; col_itr < query_column_count; col_itr++) { column_ids.push_back(hyadapt_column_ids[col_itr]); } // Create and set up seq scan executor auto predicate = GetPredicate(); planner::IndexScanPlan::IndexScanDesc dummy_index_scan_desc; planner::HybridScanPlan hybrid_scan_node(hyadapt_table.get(), predicate, column_ids, dummy_index_scan_desc, HybridScanType::SEQUENTIAL); executor::HybridScanExecutor hybrid_scan_executor(&hybrid_scan_node, context.get()); ExecuteTest(&hybrid_scan_executor); txn_manager.CommitTransaction(txn); }
void LaunchHybridScan(std::unique_ptr<storage::DataTable> &hyadapt_table) { std::vector<oid_t> column_ids; std::vector<oid_t> column_ids_second; oid_t query_column_count = projectivity * column_count; std::vector<oid_t> hyadapt_column_ids; GenerateSequence(hyadapt_column_ids, query_column_count); for (oid_t col_itr = 0; col_itr < query_column_count; col_itr++) { column_ids.push_back(hyadapt_column_ids[col_itr]); column_ids_second.push_back(hyadapt_column_ids[col_itr]); } auto index = hyadapt_table->GetIndex(0); std::vector<oid_t> key_column_ids; std::vector<ExpressionType> expr_types; std::vector<type::Value> values; std::vector<expression::AbstractExpression *> runtime_keys; CreateIndexScanPredicate(key_column_ids, expr_types, values); planner::IndexScanPlan::IndexScanDesc index_scan_desc( index, key_column_ids, expr_types, values, runtime_keys); auto predicate = GetPredicate(); planner::HybridScanPlan hybrid_scan_plan(hyadapt_table.get(), predicate, column_ids_second, index_scan_desc, HybridScanType::HYBRID); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); executor::HybridScanExecutor hybrid_scan_executor(&hybrid_scan_plan, context.get()); ExecuteTest(&hybrid_scan_executor); txn_manager.CommitTransaction(txn); }
void TableScanTranslator::ScanConsumer::FilterRowsByPredicate( CodeGen &codegen, const TileGroup::TileGroupAccess &access, llvm::Value *tid_start, llvm::Value *tid_end, Vector &selection_vector) const { // The batch we're filtering auto &compilation_ctx = translator_.GetCompilationContext(); RowBatch batch{compilation_ctx, tile_group_id_, tid_start, tid_end, selection_vector, true}; // First, check if the predicate is SIMDable const auto *predicate = GetPredicate(); LOG_DEBUG("Is Predicate SIMDable : %d", predicate->IsSIMDable()); // Determine the attributes the predicate needs std::unordered_set<const planner::AttributeInfo *> used_attributes; predicate->GetUsedAttributes(used_attributes); // Setup the row batch with attribute accessors for the predicate std::vector<AttributeAccess> attribute_accessors; for (const auto *ai : used_attributes) { attribute_accessors.emplace_back(access, ai); } for (uint32_t i = 0; i < attribute_accessors.size(); i++) { auto &accessor = attribute_accessors[i]; batch.AddAttribute(accessor.GetAttributeRef(), &accessor); } // Iterate over the batch using a scalar loop batch.Iterate(codegen, [&](RowBatch::Row &row) { // Evaluate the predicate to determine row validity codegen::Value valid_row = row.DeriveValue(codegen, *predicate); // Reify the boolean value since it may be NULL PELOTON_ASSERT(valid_row.GetType().GetSqlType() == type::Boolean::Instance()); llvm::Value *bool_val = type::Boolean::Instance().Reify(codegen, valid_row); // Set the validity of the row row.SetValidity(codegen, bool_val); }); }
void AbstractJoinPlan::PerformBinding(BindingContext &context) { const auto &children = GetChildren(); PL_ASSERT(children.size() == 2); // Let the left and right child populate bind their attributes BindingContext left_context, right_context; children[0]->PerformBinding(left_context); children[1]->PerformBinding(right_context); HandleSubplanBinding(/*is_left*/ true, left_context); HandleSubplanBinding(/*is_left*/ false, right_context); // Handle the projection std::vector<const BindingContext *> inputs = {&left_context, &right_context}; GetProjInfo()->PerformRebinding(context, inputs); // Now we pull out all the attributes coming from each of the joins children std::vector<std::vector<oid_t>> input_cols = {{}, {}}; GetProjInfo()->PartitionInputs(input_cols); // Pull out the left and right non-key attributes const auto &left_inputs = input_cols[0]; for (oid_t left_input_col : left_inputs) { left_attributes_.push_back(left_context.Find(left_input_col)); } const auto &right_inputs = input_cols[1]; for (oid_t right_input_col : right_inputs) { right_attributes_.push_back(right_context.Find(right_input_col)); } // The predicate (if one exists) operates on the __output__ of the join and, // therefore, will bind against the resulting binding context const auto *predicate = GetPredicate(); if (predicate != nullptr) { const_cast<expression::AbstractExpression *>(predicate) ->PerformBinding({&left_context, &right_context}); } }