// Constructor TableScanTranslator::TableScanTranslator(const planner::SeqScanPlan &scan, CompilationContext &context, Pipeline &pipeline) : OperatorTranslator(context, pipeline), scan_(scan), table_(*scan_.GetTable()) { LOG_DEBUG("Constructing TableScanTranslator ..."); // The restriction, if one exists const auto *predicate = GetScanPlan().GetPredicate(); if (predicate != nullptr) { // If there is a predicate, prepare a translator for it context.Prepare(*predicate); // If the scan's predicate is SIMDable, install a boundary at the output if (predicate->IsSIMDable()) { pipeline.InstallBoundaryAtOutput(this); } } auto &codegen = GetCodeGen(); auto &runtime_state = context.GetRuntimeState(); selection_vector_id_ = runtime_state.RegisterState( "scanSelVec", codegen.VectorType(codegen.Int32Type(), Vector::kDefaultVectorSize), true); LOG_DEBUG("Finished constructing TableScanTranslator ..."); }
void DeleteTranslator::Consume(ConsumerContext &, RowBatch::Row &row) const { CodeGen &codegen = GetCodeGen(); // Call Deleter::Delete(tile_group_id, tuple_offset) auto *deleter = LoadStatePtr(deleter_state_id_); codegen.Call(DeleterProxy::Delete, {deleter, row.GetTileGroupID(), row.GetTID(codegen)}); }
DeleteTranslator::DeleteTranslator(const planner::DeletePlan &delete_plan, CompilationContext &context, Pipeline &pipeline) : OperatorTranslator(delete_plan, context, pipeline), table_(*delete_plan.GetTable()) { pipeline.SetSerial(); // Also create the translator for our child. context.Prepare(*delete_plan.GetChild(0), pipeline); // Register the deleter deleter_state_id_ = context.GetQueryState().RegisterState( "deleter", DeleterProxy::GetType(GetCodeGen())); }
void DeleteTranslator::InitializeQueryState() { CodeGen &codegen = GetCodeGen(); const planner::DeletePlan &plan = GetPlanAs<planner::DeletePlan>(); // Get the table pointer storage::DataTable *table = plan.GetTable(); llvm::Value *table_ptr = codegen.Call( StorageManagerProxy::GetTableWithOid, {GetStorageManagerPtr(), codegen.Const32(table->GetDatabaseOid()), codegen.Const32(table->GetOid())}); // Call Deleter.Init(txn, table) llvm::Value *deleter = LoadStatePtr(deleter_state_id_); codegen.Call(DeleterProxy::Init, {deleter, table_ptr, GetExecutorContextPtr()}); }
// Pass this row to the next operator in the pipeline void ConsumerContext::Consume(RowBatch::Row &row) { // If we're at a stage boundary in the pipeline, it means the next operator // in the pipeline wants to operate on a batch of rows. To facilitate this, // we mark the given row as valid in this batch and return immediately. if (pipeline_.AtStageBoundary()) { auto &codegen = GetCodeGen(); row.SetValidity(codegen, codegen.ConstBool(true)); return; } // Otherwise, we move along to the next operator in the pipeline and deliver // the row there. auto *translator = pipeline_.NextStep(); if (translator != nullptr) { translator->Consume(*this, row); return; } // We're at the end of the query pipeline, we now send the output tuples // to the result consumer configured in the compilation context auto &consumer = compilation_context_.GetExecutionConsumer(); consumer.ConsumeResult(*this, row); }
// Produce! void TableScanTranslator::Produce() const { auto &codegen = GetCodeGen(); auto &table = GetTable(); LOG_DEBUG("TableScan on [%u] starting to produce tuples ...", table.GetOid()); // Get the table instance from the database llvm::Value *catalog_ptr = GetCatalogPtr(); llvm::Value *table_ptr = codegen.CallFunc(CatalogProxy::_GetTableWithOid::GetFunction(codegen), {catalog_ptr, codegen.Const32(table.GetDatabaseOid()), codegen.Const32(table.GetOid())}); // The selection vector for the scan Vector sel_vec{LoadStateValue(selection_vector_id_), Vector::kDefaultVectorSize, codegen.Int32Type()}; // Generate the scan ScanConsumer scan_consumer{*this, sel_vec}; table_.GenerateScan(codegen, table_ptr, sel_vec.GetCapacity(), scan_consumer); LOG_DEBUG("TableScan on [%u] finished producing tuples ...", table.GetOid()); }
// Produce! void TableScanTranslator::Produce() const { auto &codegen = GetCodeGen(); auto &table = GetTable(); LOG_TRACE("TableScan on [%u] starting to produce tuples ...", table.GetOid()); // Get the table instance from the database llvm::Value *storage_manager_ptr = GetStorageManagerPtr(); llvm::Value *db_oid = codegen.Const32(table.GetDatabaseOid()); llvm::Value *table_oid = codegen.Const32(table.GetOid()); llvm::Value *table_ptr = codegen.Call(StorageManagerProxy::GetTableWithOid, {storage_manager_ptr, db_oid, table_oid}); // The selection vector for the scan auto *raw_vec = codegen.AllocateBuffer( codegen.Int32Type(), Vector::kDefaultVectorSize, "scanSelVector"); Vector sel_vec{raw_vec, Vector::kDefaultVectorSize, codegen.Int32Type()}; auto predicate = const_cast<expression::AbstractExpression *>( GetScanPlan().GetPredicate()); llvm::Value *predicate_ptr = codegen->CreateIntToPtr( codegen.Const64((int64_t)predicate), AbstractExpressionProxy::GetType(codegen)->getPointerTo()); size_t num_preds = 0; auto *zone_map_manager = storage::ZoneMapManager::GetInstance(); if (predicate != nullptr && zone_map_manager->ZoneMapTableExists()) { if (predicate->IsZoneMappable()) { num_preds = predicate->GetNumberofParsedPredicates(); } } ScanConsumer scan_consumer{*this, sel_vec}; table_.GenerateScan(codegen, table_ptr, sel_vec.GetCapacity(), scan_consumer, predicate_ptr, num_preds); LOG_TRACE("TableScan on [%u] finished producing tuples ...", table.GetOid()); }
void OperatorTranslator::Consume(ConsumerContext &context, RowBatch &batch) const { batch.Iterate(GetCodeGen(), [this, &context](RowBatch::Row &row) { Consume(context, row); }); }
llvm::Value *OperatorTranslator::LoadStateValue( const QueryState::Id &state_id) const { QueryState &query_state = context_.GetQueryState(); return query_state.LoadStateValue(GetCodeGen(), state_id); }