std::shared_ptr<const Table> ShowColumns::_on_execute() { TableColumnDefinitions column_definitions; column_definitions.emplace_back("column_name", DataType::String); column_definitions.emplace_back("column_type", DataType::String); column_definitions.emplace_back("is_nullable", DataType::Int); auto out_table = std::make_shared<Table>(column_definitions, TableType::Data); const auto table = StorageManager::get().get_table(_table_name); Segments segments; const auto& column_names = table->column_names(); const auto vs_names = std::make_shared<ValueSegment<pmr_string>>( tbb::concurrent_vector<pmr_string>(column_names.begin(), column_names.end())); segments.push_back(vs_names); const auto& column_types = table->column_data_types(); auto column_types_as_string = tbb::concurrent_vector<pmr_string>{}; for (const auto column_type : column_types) { column_types_as_string.push_back(pmr_string{data_type_to_string.left.at(column_type)}); } const auto vs_types = std::make_shared<ValueSegment<pmr_string>>(std::move(column_types_as_string)); segments.push_back(vs_types); const auto& column_nullables = table->columns_are_nullable(); const auto vs_nullables = std::make_shared<ValueSegment<int32_t>>( tbb::concurrent_vector<int32_t>(column_nullables.begin(), column_nullables.end())); segments.push_back(vs_nullables); out_table->append_chunk(segments); return out_table; }
std::shared_ptr<Table> create_reference_table(std::shared_ptr<Table> referenced_table, size_t num_rows, size_t num_columns) { const auto num_rows_per_chunk = num_rows / GENERATED_TABLE_NUM_CHUNKS; TableColumnDefinitions column_definitions; for (size_t column_idx = 0; column_idx < num_columns; ++column_idx) { column_definitions.emplace_back("c" + std::to_string(column_idx), DataType::Int); } auto table = std::make_shared<Table>(column_definitions, TableType::References); for (size_t row_idx = 0; row_idx < num_rows;) { const auto num_rows_in_this_chunk = std::min(num_rows_per_chunk, num_rows - row_idx); Segments segments; for (auto column_idx = ColumnID{0}; column_idx < num_columns; ++column_idx) { /** * By specifying a chunk size of num_rows * 0.2f for the referenced table, we're emulating a referenced table * of (num_rows * 0.2f) * REFERENCED_TABLE_CHUNK_COUNT rows - i.e. twice as many rows as the referencing table * we're creating. So when creating TWO referencing tables, there should be a fair amount of overlap. */ auto pos_list = generate_pos_list(num_rows * 0.2f, num_rows_per_chunk); segments.push_back(std::make_shared<ReferenceSegment>(referenced_table, column_idx, pos_list)); } table->append_chunk(segments); row_idx += num_rows_in_this_chunk; } return table; }
std::shared_ptr<AbstractTask> IndexScan::_create_job_and_schedule(const ChunkID chunk_id, std::mutex& output_mutex) { auto job_task = std::make_shared<JobTask>([=, &output_mutex]() { const auto matches_out = std::make_shared<PosList>(_scan_chunk(chunk_id)); // The output chunk is allocated on the same NUMA node as the input chunk. const auto chunk = _in_table->get_chunk(chunk_id); Segments segments; for (ColumnID column_id{0u}; column_id < _in_table->column_count(); ++column_id) { auto ref_segment_out = std::make_shared<ReferenceSegment>(_in_table, column_id, matches_out); segments.push_back(ref_segment_out); } std::lock_guard<std::mutex> lock(output_mutex); _out_table->append_chunk(segments, nullptr, chunk->get_allocator()); }); job_task->schedule(); return job_task; }
Section & add( T const & segment ) { segments.push_back( SegmentPtr( boost::make_shared<T>( segment ) ) ); return *this; }