An example of the generated code the following query: RF001[min_max] -> a.smallint_col set minmax_filter_threshold=1.0; set minmax_filtering_level=PAGE; select straight_join count(a.id) from alltypes a join [SHUFFLE] alltypes b on a.smallint_col = b.bigint_col; ; Function Attrs: noinline nounwind define internal fastcc void @InsertRuntimeFilters(%"struct.impala::FilterContext" nocapture readonl
| 379 | // ret void |
| 380 | // } |
| 381 | Status FilterContext::CodegenInsert(LlvmCodeGen* codegen, ScalarExpr* filter_expr, |
| 382 | const TRuntimeFilterDesc& filter_desc, llvm::Function** fn) { |
| 383 | llvm::LLVMContext& context = codegen->context(); |
| 384 | LlvmBuilder builder(context); |
| 385 | |
| 386 | *fn = nullptr; |
| 387 | llvm::PointerType* this_type = codegen->GetStructPtrType<FilterContext>(); |
| 388 | llvm::PointerType* tuple_row_ptr_type = codegen->GetStructPtrType<TupleRow>(); |
| 389 | LlvmCodeGen::FnPrototype prototype( |
| 390 | codegen, "FilterContextInsert", codegen->void_type()); |
| 391 | prototype.AddArgument(LlvmCodeGen::NamedVariable("this", this_type)); |
| 392 | prototype.AddArgument(LlvmCodeGen::NamedVariable("row", tuple_row_ptr_type)); |
| 393 | |
| 394 | llvm::Value* args[2]; |
| 395 | llvm::Function* insert_filter_fn = prototype.GeneratePrototype(&builder, args); |
| 396 | llvm::Value* this_arg = args[0]; |
| 397 | llvm::Value* row_arg = args[1]; |
| 398 | |
| 399 | llvm::Value* local_filter_arg; |
| 400 | // The function for inserting into the in-list filter. |
| 401 | llvm::Function* insert_in_list_filter_fn = nullptr; |
| 402 | if (filter_desc.type == TRuntimeFilterType::BLOOM) { |
| 403 | // Load 'local_bloom_filter' from 'this_arg' FilterContext object. |
| 404 | llvm::Value* local_bloom_filter_ptr = |
| 405 | builder.CreateStructGEP(nullptr, this_arg, 3, "local_bloom_filter_ptr"); |
| 406 | local_filter_arg = |
| 407 | builder.CreateLoad(local_bloom_filter_ptr, "local_bloom_filter_arg"); |
| 408 | } else if (filter_desc.type == TRuntimeFilterType::MIN_MAX) { |
| 409 | // Load 'local_min_max_filter' from 'this_arg' FilterContext object. |
| 410 | llvm::Value* local_min_max_filter_ptr = |
| 411 | builder.CreateStructGEP(nullptr, this_arg, 4, "local_min_max_filter_ptr"); |
| 412 | llvm::PointerType* min_max_filter_type = |
| 413 | codegen->GetNamedPtrType(MinMaxFilter::GetLlvmClassName( |
| 414 | filter_expr->type().type))->getPointerTo(); |
| 415 | local_min_max_filter_ptr = builder.CreatePointerCast( |
| 416 | local_min_max_filter_ptr, min_max_filter_type, "cast_min_max_filter_ptr"); |
| 417 | local_filter_arg = |
| 418 | builder.CreateLoad(local_min_max_filter_ptr, "local_min_max_filter_arg"); |
| 419 | } else { |
| 420 | DCHECK(filter_desc.type == TRuntimeFilterType::IN_LIST); |
| 421 | // Load 'local_in_list_filter' from 'this_arg' FilterContext object. |
| 422 | llvm::Value* local_in_list_filter_ptr = |
| 423 | builder.CreateStructGEP(nullptr, this_arg, 5, "local_in_list_filter_ptr"); |
| 424 | switch (filter_expr->type().type) { |
| 425 | case TYPE_TINYINT: |
| 426 | insert_in_list_filter_fn = codegen->GetFunction( |
| 427 | IRFunction::TINYINT_IN_LIST_FILTER_INSERT, false); |
| 428 | break; |
| 429 | case TYPE_SMALLINT: |
| 430 | insert_in_list_filter_fn = codegen->GetFunction( |
| 431 | IRFunction::SMALLINT_IN_LIST_FILTER_INSERT, false); |
| 432 | break; |
| 433 | case TYPE_INT: |
| 434 | insert_in_list_filter_fn = codegen->GetFunction( |
| 435 | IRFunction::INT_IN_LIST_FILTER_INSERT, false); |
| 436 | break; |
| 437 | case TYPE_BIGINT: |
| 438 | insert_in_list_filter_fn = codegen->GetFunction( |
nothing calls this directly
no test coverage detected