in gandiva/src/main/cpp/jni_common.cc [604:698]
JNIEXPORT jlong JNICALL Java_org_apache_arrow_gandiva_evaluator_JniWrapper_buildProjector(
JNIEnv* env, jobject obj, jbyteArray schema_arr, jbyteArray exprs_arr,
jint selection_vector_type, jlong configuration_id) {
jlong module_id = 0LL;
std::shared_ptr<Projector> projector;
std::shared_ptr<ProjectorHolder> holder;
gandiva::types::Schema schema;
jsize schema_len = env->GetArrayLength(schema_arr);
jbyte* schema_bytes = env->GetByteArrayElements(schema_arr, 0);
gandiva::types::ExpressionList exprs;
jsize exprs_len = env->GetArrayLength(exprs_arr);
jbyte* exprs_bytes = env->GetByteArrayElements(exprs_arr, 0);
ExpressionVector expr_vector;
SchemaPtr schema_ptr;
FieldVector ret_types;
gandiva::Status status;
auto mode = gandiva::SelectionVector::MODE_NONE;
std::shared_ptr<Configuration> config = ConfigHolder::MapLookup(configuration_id);
std::stringstream ss;
if (config == nullptr) {
ss << "configuration is mandatory.";
releaseProjectorInput(schema_arr, schema_bytes, exprs_arr, exprs_bytes, env);
goto err_out;
}
if (!ParseProtobuf(reinterpret_cast<uint8_t*>(schema_bytes), schema_len, &schema)) {
ss << "Unable to parse schema protobuf\n";
releaseProjectorInput(schema_arr, schema_bytes, exprs_arr, exprs_bytes, env);
goto err_out;
}
if (!ParseProtobuf(reinterpret_cast<uint8_t*>(exprs_bytes), exprs_len, &exprs)) {
releaseProjectorInput(schema_arr, schema_bytes, exprs_arr, exprs_bytes, env);
ss << "Unable to parse expressions protobuf\n";
goto err_out;
}
// convert gandiva::types::Schema to arrow::Schema
schema_ptr = ProtoTypeToSchema(schema);
if (schema_ptr == nullptr) {
ss << "Unable to construct arrow schema object from schema protobuf\n";
releaseProjectorInput(schema_arr, schema_bytes, exprs_arr, exprs_bytes, env);
goto err_out;
}
// create Expression out of the list of exprs
for (int i = 0; i < exprs.exprs_size(); i++) {
ExpressionPtr root = ProtoTypeToExpression(exprs.exprs(i));
if (root == nullptr) {
ss << "Unable to construct expression object from expression protobuf\n";
releaseProjectorInput(schema_arr, schema_bytes, exprs_arr, exprs_bytes, env);
goto err_out;
}
expr_vector.push_back(root);
ret_types.push_back(root->result());
}
switch (selection_vector_type) {
case gandiva::types::SV_NONE:
mode = gandiva::SelectionVector::MODE_NONE;
break;
case gandiva::types::SV_INT16:
mode = gandiva::SelectionVector::MODE_UINT16;
break;
case gandiva::types::SV_INT32:
mode = gandiva::SelectionVector::MODE_UINT32;
break;
}
// good to invoke the evaluator now
status = Projector::Make(schema_ptr, expr_vector, mode, config, &projector);
if (!status.ok()) {
ss << "Failed to make LLVM module due to " << status.message() << "\n";
releaseProjectorInput(schema_arr, schema_bytes, exprs_arr, exprs_bytes, env);
goto err_out;
}
// store the result in a map
holder = std::shared_ptr<ProjectorHolder>(
new ProjectorHolder(schema_ptr, ret_types, std::move(projector)));
module_id = projector_modules_.Insert(holder);
releaseProjectorInput(schema_arr, schema_bytes, exprs_arr, exprs_bytes, env);
return module_id;
err_out:
env->ThrowNew(gandiva_exception_, ss.str().c_str());
return module_id;
}