Пример #1
0
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;
}
Пример #2
0
// 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));
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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);
  });
}
Пример #7
0
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});
  }
}