in gandiva/src/main/cpp/jni_common.cc [980:1054]
JNIEXPORT jint JNICALL Java_org_apache_arrow_gandiva_evaluator_JniWrapper_evaluateFilter(
JNIEnv* env, jobject cls, jlong module_id, jint num_rows, jlongArray buf_addrs,
jlongArray buf_sizes, jint jselection_vector_type, jlong out_buf_addr,
jlong out_buf_size) {
gandiva::Status status;
std::shared_ptr<FilterHolder> holder = filter_modules_.Lookup(module_id);
if (holder == nullptr) {
env->ThrowNew(gandiva_exception_, "Unknown module id\n");
return -1;
}
int in_bufs_len = env->GetArrayLength(buf_addrs);
if (in_bufs_len != env->GetArrayLength(buf_sizes)) {
env->ThrowNew(gandiva_exception_, "mismatch in arraylen of buf_addrs and buf_sizes");
return -1;
}
jlong* in_buf_addrs = env->GetLongArrayElements(buf_addrs, 0);
jlong* in_buf_sizes = env->GetLongArrayElements(buf_sizes, 0);
std::shared_ptr<gandiva::SelectionVector> selection_vector;
do {
std::shared_ptr<arrow::RecordBatch> in_batch;
status = make_record_batch_with_buf_addrs(holder->schema(), num_rows, in_buf_addrs,
in_buf_sizes, in_bufs_len, &in_batch);
if (!status.ok()) {
break;
}
auto selection_vector_type =
static_cast<gandiva::types::SelectionVectorType>(jselection_vector_type);
auto out_buffer = std::make_shared<arrow::MutableBuffer>(
reinterpret_cast<uint8_t*>(out_buf_addr), out_buf_size);
switch (selection_vector_type) {
case gandiva::types::SV_INT16:
status =
gandiva::SelectionVector::MakeInt16(num_rows, out_buffer, &selection_vector);
break;
case gandiva::types::SV_INT32:
status =
gandiva::SelectionVector::MakeInt32(num_rows, out_buffer, &selection_vector);
break;
default:
status = gandiva::Status::Invalid("unknown selection vector type");
}
if (!status.ok()) {
break;
}
status = holder->filter()->Evaluate(*in_batch, selection_vector);
} while (0);
env->ReleaseLongArrayElements(buf_addrs, in_buf_addrs, JNI_ABORT);
env->ReleaseLongArrayElements(buf_sizes, in_buf_sizes, JNI_ABORT);
if (!status.ok()) {
std::stringstream ss;
ss << "Evaluate returned " << status.message() << "\n";
env->ThrowNew(gandiva_exception_, status.message().c_str());
return -1;
} else {
int64_t num_slots = selection_vector->GetNumSlots();
// Check integer overflow
if (num_slots > INT_MAX) {
std::stringstream ss;
ss << "The selection vector has " << num_slots
<< " slots, which is larger than the " << INT_MAX << " limit.\n";
const std::string message = ss.str();
env->ThrowNew(gandiva_exception_, message.c_str());
return -1;
}
return static_cast<int>(num_slots);
}
}