Доступ к результату фильтра Gadiva по индексу в Apache Arrow

Может быть, мне не хватает чего-то очевидного, но, хоть убей, я не могу понять, как я могу получить доступ к элементам массива после операции фильтра Gandiva.

Я связал минимальный пример, который я компилирую следующим образом:

$ /usr/lib64/ccache/g++ -g -Wall -m64 -std=c++17 -pthread -fPIC \
      -I/opt/data-an/include  mwe.cc -o mwe \
      -L/opt/data-an/lib64 -lgandiva -larrow

а затем я запускаю двоичный файл следующим образом:

$ LD_LIBRARY_PATH=/opt/data-an/lib64 ./mwe

В общем, это то, что я пытался (с последующими выдержками из MWE):

  1. создать 5-элементный вектор: 1, 3, 2, 4, 5

    int num_records = 5;
    arrow::Int64Builder i64builder;
    ArrayPtr array0;
    
    EXPECT_OK(i64builder.AppendValues({1, 3, 2, 4, 5}));
    EXPECT_OK(i64builder.Finish(&array0));
    
  2. используйте Gandiva, чтобы получить четные элементы, индексы: 2, 3

    // schema for input fields
    auto field0 = field("f0", arrow::int64());
    auto schema = arrow::schema({field0});
    
    // even: f0 % 2 == 0
    auto field0_node = TreeExprBuilder::MakeField(field0);
    auto lit_2 = TreeExprBuilder::MakeLiteral(int64_t(2));
    auto remainder = TreeExprBuilder::MakeFunction("mod", {field0_node, lit_2}, int64());
    auto lit_0 = TreeExprBuilder::MakeLiteral(int64_t(0));
    auto even = TreeExprBuilder::MakeFunction("equal", {remainder, lit_0}, boolean());
    auto condition = TreeExprBuilder::MakeCondition(even);
    
    // input record batch
    auto in_batch = arrow::RecordBatch::Make(schema, num_records, {array0});
    
    // filter
    std::shared_ptr<Filter> filter;
    EXPECT_OK(Filter::Make(schema, condition, &filter));
    
    std::shared_ptr<SelectionVector> selected;
    EXPECT_OK(SelectionVector::MakeInt16(num_records, pool_, &selected));
    EXPECT_OK(filter->Evaluate(*in_batch, selected));
    
  3. получить доступ к четным элементам в исходном массиве, используя вектор выбора из фильтра Gandiva в качестве массива индексов

    // std::cout << "array0[0]: " << array0->Value(0); // doesn't compile
    // error: ‘using element_type = class arrow::Array’ {aka ‘class
    // arrow::Array’} has no member named ‘Value’
    
    // downcast it to the correct derived class
    auto array0_cast = std::dynamic_pointer_cast<NumericArray<Int64Type>>(array0);
    std::cout << "array0[0]: " << array0_cast->Value(0) << std::endl;
    

Но я не могу получить доступ к элементам вектора выбора. Поскольку он был объявлен как std::shared_ptr<arrow::Array>, метод Value(..) не найден. Так как я заполнил его SelectionVector::MakeInt16(..), я попытался понизить до arrow::NumericArray<Int16Type>, но это не удалось! Я не уверен, что ошибаюсь.

auto idx_arr_cast = std::dynamic_pointer_cast<NumericArray<Int16Type>>(idx_arr);
if (idx_arr_cast) {
  std::cout << "idx_arr[0]: " << idx_arr_cast->Value(0) << std::endl;
} else {
  std::cerr << "idx_arr_cast is a nullptr!" << std::endl;
}

У меня тоже есть связанный, но более общий вопрос. Учитывая массив, я не могу найти способ получить доступ к элементам (или перебрать их), если я не знаю точного типа. Если я знаю тип, я могу понижать значение и использовать подобные Value(..), GetValue(..), GetString(..) и т.д. Что мне не хватает?

Примечание. Полный MWE вместе с Makefile можно клонировать из этой сути.


person suvayu    schedule 12.12.2018    source источник
comment
Я настоятельно рекомендую задать этот вопрос (и будущие вопросы) в списке рассылки dev @ вместо StackOverflow. Не многие разработчики Arrow следят за тегами здесь.   -  person Wes McKinney    schedule 13.12.2018
comment
Хорошо спасибо. Я сделаю репост в списке разработчиков.   -  person suvayu    schedule 13.12.2018


Ответы (1)


SelectionVector хранит индексы, поэтому тип unsigned, работает следующее:

auto arr = std::dynamic_pointer_cast<NumericArray<UInt16Type>>(selected->ToArray());

Спасибо Равиндре из списка разработчиков Arrow за ответ.

person suvayu    schedule 14.12.2018