Coverage Report

Created: 2026-10-19 04:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/ai/ai_functions.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <gen_cpp/FrontendService.h>
21
#include <gen_cpp/PaloInternalService_types.h>
22
#include <glog/logging.h>
23
24
#include <algorithm>
25
#include <cstdlib>
26
#include <memory>
27
#include <string>
28
#include <type_traits>
29
#include <utility>
30
#include <vector>
31
32
#include "common/config.h"
33
#include "common/status.h"
34
#include "core/column/column_array.h"
35
#include "core/column/column_const.h"
36
#include "core/column/column_nullable.h"
37
#include "core/cow.h"
38
#include "core/data_type/data_type_array.h"
39
#include "core/data_type/data_type_nullable.h"
40
#include "core/data_type/data_type_number.h"
41
#include "core/data_type/define_primitive_type.h"
42
#include "core/data_type/primitive_type.h"
43
#include "exec/common/util.hpp"
44
#include "exprs/function/ai/ai_adapter.h"
45
#include "exprs/function/ai/ai_request_executor.h"
46
#include "exprs/function/function.h"
47
#include "runtime/query_context.h"
48
#include "runtime/runtime_state.h"
49
#include "util/string_util.h"
50
#include "util/threadpool.h"
51
52
namespace doris {
53
54
// Base class for AI-based functions
55
template <typename Derived>
56
class AIFunction : public IFunction {
57
public:
58
18
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_17FunctionAIExtractEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_14FunctionAIMaskEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAITranslateEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE8get_nameB5cxx11Ev
Line
Count
Source
58
6
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE8get_nameB5cxx11Ev
Line
Count
Source
58
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE8get_nameB5cxx11Ev
Line
Count
Source
58
2
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
59
60
    // If the user doesn't provide the first arg, `resource_name`
61
    // FE will add the `resource_name` to the arguments list using the Session Variable.
62
    // So the value here should be the maximum number that the function can accept.
63
12
    size_t get_number_of_arguments() const override {
64
12
        return assert_cast<const Derived&>(*this).number_of_arguments;
65
12
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE23get_number_of_argumentsEv
Line
Count
Source
63
2
    size_t get_number_of_arguments() const override {
64
2
        return assert_cast<const Derived&>(*this).number_of_arguments;
65
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE23get_number_of_argumentsEv
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE23get_number_of_argumentsEv
Line
Count
Source
63
4
    size_t get_number_of_arguments() const override {
64
4
        return assert_cast<const Derived&>(*this).number_of_arguments;
65
4
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE23get_number_of_argumentsEv
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE23get_number_of_argumentsEv
Line
Count
Source
63
1
    size_t get_number_of_arguments() const override {
64
1
        return assert_cast<const Derived&>(*this).number_of_arguments;
65
1
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE23get_number_of_argumentsEv
Line
Count
Source
63
1
    size_t get_number_of_arguments() const override {
64
1
        return assert_cast<const Derived&>(*this).number_of_arguments;
65
1
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE23get_number_of_argumentsEv
Line
Count
Source
63
4
    size_t get_number_of_arguments() const override {
64
4
        return assert_cast<const Derived&>(*this).number_of_arguments;
65
4
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE23get_number_of_argumentsEv
66
67
0
    bool is_blockable() const override { return true; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE12is_blockableEv
68
69
1
    Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override {
70
1
        if (scope == FunctionContext::FunctionStateScope::THREAD_LOCAL) {
71
            // Release this execution context's cached clients.
72
1
            context->set_function_state(scope, nullptr);
73
1
        }
74
1
        return Status::OK();
75
1
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_18FunctionAIClassifyEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_17FunctionAIExtractEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAISentimentEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
_ZN5doris10AIFunctionINS_19FunctionAISummarizeEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Line
Count
Source
69
1
    Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override {
70
1
        if (scope == FunctionContext::FunctionStateScope::THREAD_LOCAL) {
71
            // Release this execution context's cached clients.
72
1
            context->set_function_state(scope, nullptr);
73
1
        }
74
1
        return Status::OK();
75
1
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_14FunctionAIMaskEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_18FunctionAIGenerateEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_20FunctionAIFixGrammarEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAITranslateEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_20FunctionAISimilarityEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_16FunctionAIFilterEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_13FunctionEmbedEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE5closeEPNS_15FunctionContextENS3_18FunctionStateScopeE
76
77
24
    bool use_default_implementation_for_nulls() const final { return false; }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE36use_default_implementation_for_nullsEv
Line
Count
Source
77
4
    bool use_default_implementation_for_nulls() const final { return false; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE36use_default_implementation_for_nullsEv
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE36use_default_implementation_for_nullsEv
Line
Count
Source
77
8
    bool use_default_implementation_for_nulls() const final { return false; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE36use_default_implementation_for_nullsEv
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE36use_default_implementation_for_nullsEv
Line
Count
Source
77
2
    bool use_default_implementation_for_nulls() const final { return false; }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE36use_default_implementation_for_nullsEv
Line
Count
Source
77
2
    bool use_default_implementation_for_nulls() const final { return false; }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE36use_default_implementation_for_nullsEv
Line
Count
Source
77
8
    bool use_default_implementation_for_nulls() const final { return false; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE36use_default_implementation_for_nullsEv
78
79
23
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
23
        bool has_nullable_argument = std::ranges::any_of(
81
25
                arguments, [](const auto& argument) { return argument->is_nullable(); });
_ZZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
81
6
                arguments, [](const auto& argument) { return argument->is_nullable(); });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_17FunctionAIExtractEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAISentimentEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_14FunctionAIMaskEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
_ZZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
81
7
                arguments, [](const auto& argument) { return argument->is_nullable(); });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAITranslateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
_ZZNK5doris10AIFunctionINS_20FunctionAISimilarityEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
81
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
_ZZNK5doris10AIFunctionINS_16FunctionAIFilterEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
81
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
_ZZNK5doris10AIFunctionINS_13FunctionEmbedEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
81
8
                arguments, [](const auto& argument) { return argument->is_nullable(); });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
82
23
        DataTypePtr return_type =
83
23
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
23
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
23
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
3
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
3
        bool has_nullable_argument = std::ranges::any_of(
81
3
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
3
        DataTypePtr return_type =
83
3
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
3
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
3
    }
_ZNK5doris10AIFunctionINS_17FunctionAIExtractEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
1
        bool has_nullable_argument = std::ranges::any_of(
81
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
1
        DataTypePtr return_type =
83
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
1
    }
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
1
        bool has_nullable_argument = std::ranges::any_of(
81
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
1
        DataTypePtr return_type =
83
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
1
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
1
        bool has_nullable_argument = std::ranges::any_of(
81
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
1
        DataTypePtr return_type =
83
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
1
    }
_ZNK5doris10AIFunctionINS_14FunctionAIMaskEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
1
        bool has_nullable_argument = std::ranges::any_of(
81
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
1
        DataTypePtr return_type =
83
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
1
    }
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
5
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
5
        bool has_nullable_argument = std::ranges::any_of(
81
5
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
5
        DataTypePtr return_type =
83
5
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
5
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
5
    }
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
1
        bool has_nullable_argument = std::ranges::any_of(
81
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
1
        DataTypePtr return_type =
83
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
1
    }
_ZNK5doris10AIFunctionINS_19FunctionAITranslateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
1
        bool has_nullable_argument = std::ranges::any_of(
81
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
1
        DataTypePtr return_type =
83
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
1
    }
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
2
        bool has_nullable_argument = std::ranges::any_of(
81
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
2
        DataTypePtr return_type =
83
2
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
2
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
2
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
2
        bool has_nullable_argument = std::ranges::any_of(
81
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
2
        DataTypePtr return_type =
83
2
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
2
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
2
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
79
5
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
80
5
        bool has_nullable_argument = std::ranges::any_of(
81
5
                arguments, [](const auto& argument) { return argument->is_nullable(); });
82
5
        DataTypePtr return_type =
83
5
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
84
5
        return has_nullable_argument ? make_nullable(return_type) : return_type;
85
5
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
86
87
    using PreparedFunctionImpl::execute;
88
89
    virtual Status build_prompt(const Columns& prompt_columns, size_t row_num,
90
107
                                std::string& prompt) const {
91
107
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
92
107
        prompt = std::string(text_ref.data, text_ref.size);
93
94
107
        return Status::OK();
95
107
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
90
5
                                std::string& prompt) const {
91
5
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
92
5
        prompt = std::string(text_ref.data, text_ref.size);
93
94
5
        return Status::OK();
95
5
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
90
11
                                std::string& prompt) const {
91
11
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
92
11
        prompt = std::string(text_ref.data, text_ref.size);
93
94
11
        return Status::OK();
95
11
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
90
1
                                std::string& prompt) const {
91
1
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
92
1
        prompt = std::string(text_ref.data, text_ref.size);
93
94
1
        return Status::OK();
95
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
90
65
                                std::string& prompt) const {
91
65
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
92
65
        prompt = std::string(text_ref.data, text_ref.size);
93
94
65
        return Status::OK();
95
65
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
90
25
                                std::string& prompt) const {
91
25
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
92
25
        prompt = std::string(text_ref.data, text_ref.size);
93
94
25
        return Status::OK();
95
25
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
96
97
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
98
92
                        uint32_t result, size_t input_rows_count) const override {
99
92
        if (block.get_by_position(arguments[0]).column->only_null()) {
100
1
            block.get_by_position(result).column =
101
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
102
1
                                                                            Field());
103
1
            return Status::OK();
104
1
        }
105
106
91
        AIResource config;
107
91
        std::shared_ptr<AIAdapter> adapter;
108
91
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
109
91
            !status.ok()) {
110
0
            return status;
111
0
        }
112
113
91
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
114
91
                                                          input_rows_count, config, adapter);
115
91
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
98
2
                        uint32_t result, size_t input_rows_count) const override {
99
2
        if (block.get_by_position(arguments[0]).column->only_null()) {
100
0
            block.get_by_position(result).column =
101
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
102
0
                                                                            Field());
103
0
            return Status::OK();
104
0
        }
105
106
2
        AIResource config;
107
2
        std::shared_ptr<AIAdapter> adapter;
108
2
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
109
2
            !status.ok()) {
110
0
            return status;
111
0
        }
112
113
2
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
114
2
                                                          input_rows_count, config, adapter);
115
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
98
2
                        uint32_t result, size_t input_rows_count) const override {
99
2
        if (block.get_by_position(arguments[0]).column->only_null()) {
100
0
            block.get_by_position(result).column =
101
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
102
0
                                                                            Field());
103
0
            return Status::OK();
104
0
        }
105
106
2
        AIResource config;
107
2
        std::shared_ptr<AIAdapter> adapter;
108
2
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
109
2
            !status.ok()) {
110
0
            return status;
111
0
        }
112
113
2
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
114
2
                                                          input_rows_count, config, adapter);
115
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
98
4
                        uint32_t result, size_t input_rows_count) const override {
99
4
        if (block.get_by_position(arguments[0]).column->only_null()) {
100
1
            block.get_by_position(result).column =
101
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
102
1
                                                                            Field());
103
1
            return Status::OK();
104
1
        }
105
106
3
        AIResource config;
107
3
        std::shared_ptr<AIAdapter> adapter;
108
3
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
109
3
            !status.ok()) {
110
0
            return status;
111
0
        }
112
113
3
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
114
3
                                                          input_rows_count, config, adapter);
115
3
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
98
22
                        uint32_t result, size_t input_rows_count) const override {
99
22
        if (block.get_by_position(arguments[0]).column->only_null()) {
100
0
            block.get_by_position(result).column =
101
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
102
0
                                                                            Field());
103
0
            return Status::OK();
104
0
        }
105
106
22
        AIResource config;
107
22
        std::shared_ptr<AIAdapter> adapter;
108
22
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
109
22
            !status.ok()) {
110
0
            return status;
111
0
        }
112
113
22
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
114
22
                                                          input_rows_count, config, adapter);
115
22
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
98
47
                        uint32_t result, size_t input_rows_count) const override {
99
47
        if (block.get_by_position(arguments[0]).column->only_null()) {
100
0
            block.get_by_position(result).column =
101
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
102
0
                                                                            Field());
103
0
            return Status::OK();
104
0
        }
105
106
47
        AIResource config;
107
47
        std::shared_ptr<AIAdapter> adapter;
108
47
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
109
47
            !status.ok()) {
110
0
            return status;
111
0
        }
112
113
47
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
114
47
                                                          input_rows_count, config, adapter);
115
47
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
98
15
                        uint32_t result, size_t input_rows_count) const override {
99
15
        if (block.get_by_position(arguments[0]).column->only_null()) {
100
0
            block.get_by_position(result).column =
101
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
102
0
                                                                            Field());
103
0
            return Status::OK();
104
0
        }
105
106
15
        AIResource config;
107
15
        std::shared_ptr<AIAdapter> adapter;
108
15
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
109
15
            !status.ok()) {
110
0
            return status;
111
0
        }
112
113
15
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
114
15
                                                          input_rows_count, config, adapter);
115
15
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
116
117
protected:
118
    // Reads the shared AI context window size from query options. String AI batch functions and
119
    // ai_agg both use the same byte-based session variable so batching behavior stays consistent.
120
91
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
91
        DORIS_CHECK(context != nullptr);
122
91
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
91
        DORIS_CHECK(query_ctx != nullptr);
124
125
91
        return query_ctx->query_options().ai_context_window_size;
126
91
    }
_ZN5doris10AIFunctionINS_18FunctionAIClassifyEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
120
2
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
2
        DORIS_CHECK(context != nullptr);
122
2
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
2
        DORIS_CHECK(query_ctx != nullptr);
124
125
2
        return query_ctx->query_options().ai_context_window_size;
126
2
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_17FunctionAIExtractEE26get_ai_context_window_sizeEPNS_15FunctionContextE
_ZN5doris10AIFunctionINS_19FunctionAISentimentEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
120
2
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
2
        DORIS_CHECK(context != nullptr);
122
2
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
2
        DORIS_CHECK(query_ctx != nullptr);
124
125
2
        return query_ctx->query_options().ai_context_window_size;
126
2
    }
_ZN5doris10AIFunctionINS_19FunctionAISummarizeEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
120
5
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
5
        DORIS_CHECK(context != nullptr);
122
5
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
5
        DORIS_CHECK(query_ctx != nullptr);
124
125
5
        return query_ctx->query_options().ai_context_window_size;
126
5
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_14FunctionAIMaskEE26get_ai_context_window_sizeEPNS_15FunctionContextE
_ZN5doris10AIFunctionINS_18FunctionAIGenerateEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
120
2
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
2
        DORIS_CHECK(context != nullptr);
122
2
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
2
        DORIS_CHECK(query_ctx != nullptr);
124
125
2
        return query_ctx->query_options().ai_context_window_size;
126
2
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_20FunctionAIFixGrammarEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAITranslateEE26get_ai_context_window_sizeEPNS_15FunctionContextE
_ZN5doris10AIFunctionINS_20FunctionAISimilarityEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
120
22
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
22
        DORIS_CHECK(context != nullptr);
122
22
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
22
        DORIS_CHECK(query_ctx != nullptr);
124
125
22
        return query_ctx->query_options().ai_context_window_size;
126
22
    }
_ZN5doris10AIFunctionINS_16FunctionAIFilterEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
120
47
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
47
        DORIS_CHECK(context != nullptr);
122
47
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
47
        DORIS_CHECK(query_ctx != nullptr);
124
125
47
        return query_ctx->query_options().ai_context_window_size;
126
47
    }
_ZN5doris10AIFunctionINS_13FunctionEmbedEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
120
11
    static int64_t get_ai_context_window_size(FunctionContext* context) {
121
11
        DORIS_CHECK(context != nullptr);
122
11
        QueryContext* query_ctx = context->state()->get_query_ctx();
123
11
        DORIS_CHECK(query_ctx != nullptr);
124
125
11
        return query_ctx->query_options().ai_context_window_size;
126
11
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE26get_ai_context_window_sizeEPNS_15FunctionContextE
127
128
11
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20create_result_columnEv
Line
Count
Source
128
2
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE20create_result_columnEv
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE20create_result_columnEv
Line
Count
Source
128
2
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20create_result_columnEv
Line
Count
Source
128
5
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE20create_result_columnEv
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20create_result_columnEv
Line
Count
Source
128
2
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20create_result_columnEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE20create_result_columnEv
129
130
    // Provider-reusable hook for AI functions(string) -> string.
131
    Status append_batch_results(const std::vector<std::string>& batch_results,
132
16
                                IColumn& col_result) const {
133
16
        auto& string_col = assert_cast<ColumnString&>(col_result);
134
21
        for (const auto& batch_result : batch_results) {
135
21
            string_col.insert_data(batch_result.data(), batch_result.size());
136
21
        }
137
16
        return Status::OK();
138
16
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Line
Count
Source
132
2
                                IColumn& col_result) const {
133
2
        auto& string_col = assert_cast<ColumnString&>(col_result);
134
2
        for (const auto& batch_result : batch_results) {
135
2
            string_col.insert_data(batch_result.data(), batch_result.size());
136
2
        }
137
2
        return Status::OK();
138
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Line
Count
Source
132
2
                                IColumn& col_result) const {
133
2
        auto& string_col = assert_cast<ColumnString&>(col_result);
134
4
        for (const auto& batch_result : batch_results) {
135
4
            string_col.insert_data(batch_result.data(), batch_result.size());
136
4
        }
137
2
        return Status::OK();
138
2
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Line
Count
Source
132
10
                                IColumn& col_result) const {
133
10
        auto& string_col = assert_cast<ColumnString&>(col_result);
134
10
        for (const auto& batch_result : batch_results) {
135
10
            string_col.insert_data(batch_result.data(), batch_result.size());
136
10
        }
137
10
        return Status::OK();
138
10
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Line
Count
Source
132
2
                                IColumn& col_result) const {
133
2
        auto& string_col = assert_cast<ColumnString&>(col_result);
134
5
        for (const auto& batch_result : batch_results) {
135
5
            string_col.insert_data(batch_result.data(), batch_result.size());
136
5
        }
137
2
        return Status::OK();
138
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
139
140
98
    static void normalize_endpoint(AIResource& config) {
141
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
142
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
143
        //    for other AI scalar functions.
144
        // 2. `:embedContent` -> `:batchEmbedContents`
145
98
        if (iequal(config.provider_type, "GEMINI")) {
146
4
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
147
1
                static constexpr std::string_view legacy_suffix = ":embedContent";
148
1
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
149
1
                                        legacy_suffix.size(), ":batchEmbedContents");
150
1
                return;
151
1
            }
152
153
3
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
154
1
                return;
155
1
            }
156
157
2
            std::string model_name = config.model_name;
158
2
            if (!model_name.starts_with("models/")) {
159
2
                model_name = "models/" + model_name;
160
2
            }
161
162
2
            config.endpoint += "/";
163
2
            config.endpoint += model_name;
164
2
            config.endpoint +=
165
2
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
166
2
            return;
167
3
        }
168
169
        // The endpoint `v1/completions` does not support `system_prompt`.
170
        // To ensure a clear structure and stable AI results.
171
        // Convert from `v1/completions` to `v1/chat/completions`
172
94
        if (config.endpoint.ends_with("v1/completions")) {
173
1
            static constexpr std::string_view legacy_suffix = "v1/completions";
174
1
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
175
1
                                    legacy_suffix.size(), "v1/chat/completions");
176
1
        }
177
94
    }
_ZN5doris10AIFunctionINS_18FunctionAIClassifyEE18normalize_endpointERNS_10AIResourceE
Line
Count
Source
140
2
    static void normalize_endpoint(AIResource& config) {
141
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
142
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
143
        //    for other AI scalar functions.
144
        // 2. `:embedContent` -> `:batchEmbedContents`
145
2
        if (iequal(config.provider_type, "GEMINI")) {
146
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
147
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
148
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
149
0
                                        legacy_suffix.size(), ":batchEmbedContents");
150
0
                return;
151
0
            }
152
153
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
154
0
                return;
155
0
            }
156
157
0
            std::string model_name = config.model_name;
158
0
            if (!model_name.starts_with("models/")) {
159
0
                model_name = "models/" + model_name;
160
0
            }
161
162
0
            config.endpoint += "/";
163
0
            config.endpoint += model_name;
164
0
            config.endpoint +=
165
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
166
0
            return;
167
0
        }
168
169
        // The endpoint `v1/completions` does not support `system_prompt`.
170
        // To ensure a clear structure and stable AI results.
171
        // Convert from `v1/completions` to `v1/chat/completions`
172
2
        if (config.endpoint.ends_with("v1/completions")) {
173
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
174
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
175
0
                                    legacy_suffix.size(), "v1/chat/completions");
176
0
        }
177
2
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_17FunctionAIExtractEE18normalize_endpointERNS_10AIResourceE
_ZN5doris10AIFunctionINS_19FunctionAISentimentEE18normalize_endpointERNS_10AIResourceE
Line
Count
Source
140
7
    static void normalize_endpoint(AIResource& config) {
141
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
142
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
143
        //    for other AI scalar functions.
144
        // 2. `:embedContent` -> `:batchEmbedContents`
145
7
        if (iequal(config.provider_type, "GEMINI")) {
146
2
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
147
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
148
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
149
0
                                        legacy_suffix.size(), ":batchEmbedContents");
150
0
                return;
151
0
            }
152
153
2
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
154
1
                return;
155
1
            }
156
157
1
            std::string model_name = config.model_name;
158
1
            if (!model_name.starts_with("models/")) {
159
1
                model_name = "models/" + model_name;
160
1
            }
161
162
1
            config.endpoint += "/";
163
1
            config.endpoint += model_name;
164
1
            config.endpoint +=
165
1
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
166
1
            return;
167
2
        }
168
169
        // The endpoint `v1/completions` does not support `system_prompt`.
170
        // To ensure a clear structure and stable AI results.
171
        // Convert from `v1/completions` to `v1/chat/completions`
172
5
        if (config.endpoint.ends_with("v1/completions")) {
173
1
            static constexpr std::string_view legacy_suffix = "v1/completions";
174
1
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
175
1
                                    legacy_suffix.size(), "v1/chat/completions");
176
1
        }
177
5
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAISummarizeEE18normalize_endpointERNS_10AIResourceE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_14FunctionAIMaskEE18normalize_endpointERNS_10AIResourceE
_ZN5doris10AIFunctionINS_18FunctionAIGenerateEE18normalize_endpointERNS_10AIResourceE
Line
Count
Source
140
3
    static void normalize_endpoint(AIResource& config) {
141
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
142
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
143
        //    for other AI scalar functions.
144
        // 2. `:embedContent` -> `:batchEmbedContents`
145
3
        if (iequal(config.provider_type, "GEMINI")) {
146
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
147
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
148
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
149
0
                                        legacy_suffix.size(), ":batchEmbedContents");
150
0
                return;
151
0
            }
152
153
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
154
0
                return;
155
0
            }
156
157
0
            std::string model_name = config.model_name;
158
0
            if (!model_name.starts_with("models/")) {
159
0
                model_name = "models/" + model_name;
160
0
            }
161
162
0
            config.endpoint += "/";
163
0
            config.endpoint += model_name;
164
0
            config.endpoint +=
165
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
166
0
            return;
167
0
        }
168
169
        // The endpoint `v1/completions` does not support `system_prompt`.
170
        // To ensure a clear structure and stable AI results.
171
        // Convert from `v1/completions` to `v1/chat/completions`
172
3
        if (config.endpoint.ends_with("v1/completions")) {
173
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
174
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
175
0
                                    legacy_suffix.size(), "v1/chat/completions");
176
0
        }
177
3
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_20FunctionAIFixGrammarEE18normalize_endpointERNS_10AIResourceE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAITranslateEE18normalize_endpointERNS_10AIResourceE
_ZN5doris10AIFunctionINS_20FunctionAISimilarityEE18normalize_endpointERNS_10AIResourceE
Line
Count
Source
140
22
    static void normalize_endpoint(AIResource& config) {
141
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
142
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
143
        //    for other AI scalar functions.
144
        // 2. `:embedContent` -> `:batchEmbedContents`
145
22
        if (iequal(config.provider_type, "GEMINI")) {
146
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
147
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
148
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
149
0
                                        legacy_suffix.size(), ":batchEmbedContents");
150
0
                return;
151
0
            }
152
153
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
154
0
                return;
155
0
            }
156
157
0
            std::string model_name = config.model_name;
158
0
            if (!model_name.starts_with("models/")) {
159
0
                model_name = "models/" + model_name;
160
0
            }
161
162
0
            config.endpoint += "/";
163
0
            config.endpoint += model_name;
164
0
            config.endpoint +=
165
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
166
0
            return;
167
0
        }
168
169
        // The endpoint `v1/completions` does not support `system_prompt`.
170
        // To ensure a clear structure and stable AI results.
171
        // Convert from `v1/completions` to `v1/chat/completions`
172
22
        if (config.endpoint.ends_with("v1/completions")) {
173
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
174
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
175
0
                                    legacy_suffix.size(), "v1/chat/completions");
176
0
        }
177
22
    }
_ZN5doris10AIFunctionINS_16FunctionAIFilterEE18normalize_endpointERNS_10AIResourceE
Line
Count
Source
140
47
    static void normalize_endpoint(AIResource& config) {
141
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
142
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
143
        //    for other AI scalar functions.
144
        // 2. `:embedContent` -> `:batchEmbedContents`
145
47
        if (iequal(config.provider_type, "GEMINI")) {
146
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
147
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
148
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
149
0
                                        legacy_suffix.size(), ":batchEmbedContents");
150
0
                return;
151
0
            }
152
153
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
154
0
                return;
155
0
            }
156
157
0
            std::string model_name = config.model_name;
158
0
            if (!model_name.starts_with("models/")) {
159
0
                model_name = "models/" + model_name;
160
0
            }
161
162
0
            config.endpoint += "/";
163
0
            config.endpoint += model_name;
164
0
            config.endpoint +=
165
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
166
0
            return;
167
0
        }
168
169
        // The endpoint `v1/completions` does not support `system_prompt`.
170
        // To ensure a clear structure and stable AI results.
171
        // Convert from `v1/completions` to `v1/chat/completions`
172
47
        if (config.endpoint.ends_with("v1/completions")) {
173
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
174
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
175
0
                                    legacy_suffix.size(), "v1/chat/completions");
176
0
        }
177
47
    }
_ZN5doris10AIFunctionINS_13FunctionEmbedEE18normalize_endpointERNS_10AIResourceE
Line
Count
Source
140
17
    static void normalize_endpoint(AIResource& config) {
141
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
142
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
143
        //    for other AI scalar functions.
144
        // 2. `:embedContent` -> `:batchEmbedContents`
145
17
        if (iequal(config.provider_type, "GEMINI")) {
146
2
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
147
1
                static constexpr std::string_view legacy_suffix = ":embedContent";
148
1
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
149
1
                                        legacy_suffix.size(), ":batchEmbedContents");
150
1
                return;
151
1
            }
152
153
1
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
154
0
                return;
155
0
            }
156
157
1
            std::string model_name = config.model_name;
158
1
            if (!model_name.starts_with("models/")) {
159
1
                model_name = "models/" + model_name;
160
1
            }
161
162
1
            config.endpoint += "/";
163
1
            config.endpoint += model_name;
164
1
            config.endpoint +=
165
1
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
166
1
            return;
167
1
        }
168
169
        // The endpoint `v1/completions` does not support `system_prompt`.
170
        // To ensure a clear structure and stable AI results.
171
        // Convert from `v1/completions` to `v1/chat/completions`
172
15
        if (config.endpoint.ends_with("v1/completions")) {
173
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
174
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
175
0
                                    legacy_suffix.size(), "v1/chat/completions");
176
0
        }
177
15
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE18normalize_endpointERNS_10AIResourceE
178
179
    Status send_request_to_llm(const std::string& request_body, std::string& response,
180
                               const AIResource& config, std::shared_ptr<AIAdapter>& adapter,
181
51
                               FunctionContext* context) const {
182
        // Retain the cache across batches/Blocks.
183
51
        auto* executor = static_cast<AIRequestExecutor*>(
184
51
                context->get_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL));
185
51
        if (executor == nullptr) {
186
13
            auto state = std::make_shared<AIRequestExecutor>();
187
13
            executor = state.get();
188
13
            context->set_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL,
189
13
                                        std::move(state));
190
13
        }
191
51
        return executor->execute(request_body, response, config, *adapter,
192
51
                                 context->state()->get_query_ctx());
193
51
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
181
3
                               FunctionContext* context) const {
182
        // Retain the cache across batches/Blocks.
183
3
        auto* executor = static_cast<AIRequestExecutor*>(
184
3
                context->get_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL));
185
3
        if (executor == nullptr) {
186
3
            auto state = std::make_shared<AIRequestExecutor>();
187
3
            executor = state.get();
188
3
            context->set_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL,
189
3
                                        std::move(state));
190
3
        }
191
3
        return executor->execute(request_body, response, config, *adapter,
192
3
                                 context->state()->get_query_ctx());
193
3
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
181
15
                               FunctionContext* context) const {
182
        // Retain the cache across batches/Blocks.
183
15
        auto* executor = static_cast<AIRequestExecutor*>(
184
15
                context->get_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL));
185
15
        if (executor == nullptr) {
186
2
            auto state = std::make_shared<AIRequestExecutor>();
187
2
            executor = state.get();
188
2
            context->set_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL,
189
2
                                        std::move(state));
190
2
        }
191
15
        return executor->execute(request_body, response, config, *adapter,
192
15
                                 context->state()->get_query_ctx());
193
15
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
181
31
                               FunctionContext* context) const {
182
        // Retain the cache across batches/Blocks.
183
31
        auto* executor = static_cast<AIRequestExecutor*>(
184
31
                context->get_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL));
185
31
        if (executor == nullptr) {
186
6
            auto state = std::make_shared<AIRequestExecutor>();
187
6
            executor = state.get();
188
6
            context->set_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL,
189
6
                                        std::move(state));
190
6
        }
191
31
        return executor->execute(request_body, response, config, *adapter,
192
31
                                 context->state()->get_query_ctx());
193
31
    }
_ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
181
2
                               FunctionContext* context) const {
182
        // Retain the cache across batches/Blocks.
183
2
        auto* executor = static_cast<AIRequestExecutor*>(
184
2
                context->get_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL));
185
2
        if (executor == nullptr) {
186
2
            auto state = std::make_shared<AIRequestExecutor>();
187
2
            executor = state.get();
188
2
            context->set_function_state(FunctionContext::FunctionStateScope::THREAD_LOCAL,
189
2
                                        std::move(state));
190
2
        }
191
2
        return executor->execute(request_body, response, config, *adapter,
192
2
                                 context->state()->get_query_ctx());
193
2
    }
194
195
    // Provider-reusable helper for string-returning functions.
196
    // Estimates one batch entry size using the raw prompt length plus the fixed JSON wrapper cost.
197
110
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
198
110
        static constexpr size_t json_wrapper_size = 20;
199
110
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
200
110
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
197
2
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
198
2
        static constexpr size_t json_wrapper_size = 20;
199
2
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
200
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
197
4
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
198
4
        static constexpr size_t json_wrapper_size = 20;
199
4
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
200
4
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
197
10
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
198
10
        static constexpr size_t json_wrapper_size = 20;
199
10
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
200
10
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
197
5
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
198
5
        static constexpr size_t json_wrapper_size = 20;
199
5
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
200
5
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
197
25
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
198
25
        static constexpr size_t json_wrapper_size = 20;
199
25
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
200
25
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
197
64
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
198
64
        static constexpr size_t json_wrapper_size = 20;
199
64
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
200
64
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
201
202
    // Provider-reusable helper for string-returning functions.
203
    // Executes one batch request and parses the provider result into one string per input row.
204
    Status execute_batch_request(const std::vector<std::string>& batch_prompts,
205
                                 std::vector<std::string>& results, const AIResource& config,
206
                                 std::shared_ptr<AIAdapter>& adapter,
207
91
                                 FunctionContext* context) const {
208
91
#ifdef BE_TEST
209
91
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
91
        if (test_result != nullptr) {
211
78
            std::vector<std::string> parsed_test_response;
212
78
            RETURN_IF_ERROR(
213
78
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
77
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
77
            if (parsed_test_response.size() != batch_prompts.size()) {
218
5
                return Status::RuntimeError(
219
5
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
5
                        batch_prompts.size(), parsed_test_response.size());
221
5
            }
222
72
            results = std::move(parsed_test_response);
223
72
            return Status::OK();
224
77
        }
225
13
        if (config.provider_type == "MOCK") {
226
1
            results.clear();
227
1
            results.reserve(batch_prompts.size());
228
1
            for (const auto& prompt : batch_prompts) {
229
1
                results.emplace_back("this is a mock response. " + prompt);
230
1
            }
231
1
            return Status::OK();
232
1
        }
233
12
#endif
234
235
12
        std::string batch_prompt;
236
12
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
12
        std::vector<std::string> inputs = {batch_prompt};
239
12
        std::vector<std::string> parsed_response;
240
241
12
        std::string request_body;
242
12
        RETURN_IF_ERROR(adapter->build_request_payload(
243
12
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
12
        std::string response;
246
12
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
12
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
12
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
12
        if (parsed_response.size() != batch_prompts.size()) {
252
1
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
1
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
1
                         << ", expected_rows=" << batch_prompts.size()
255
1
                         << ", actual_rows=" << parsed_response.size()
256
1
                         << ", response_body=" << response;
257
1
            return Status::RuntimeError(
258
1
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
1
                    batch_prompts.size(), parsed_response.size());
260
1
        }
261
11
        results = std::move(parsed_response);
262
11
        return Status::OK();
263
12
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
207
2
                                 FunctionContext* context) const {
208
2
#ifdef BE_TEST
209
2
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
2
        if (test_result != nullptr) {
211
2
            std::vector<std::string> parsed_test_response;
212
2
            RETURN_IF_ERROR(
213
2
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
2
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
2
            if (parsed_test_response.size() != batch_prompts.size()) {
218
0
                return Status::RuntimeError(
219
0
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
0
                        batch_prompts.size(), parsed_test_response.size());
221
0
            }
222
2
            results = std::move(parsed_test_response);
223
2
            return Status::OK();
224
2
        }
225
0
        if (config.provider_type == "MOCK") {
226
0
            results.clear();
227
0
            results.reserve(batch_prompts.size());
228
0
            for (const auto& prompt : batch_prompts) {
229
0
                results.emplace_back("this is a mock response. " + prompt);
230
0
            }
231
0
            return Status::OK();
232
0
        }
233
0
#endif
234
235
0
        std::string batch_prompt;
236
0
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
0
        std::vector<std::string> inputs = {batch_prompt};
239
0
        std::vector<std::string> parsed_response;
240
241
0
        std::string request_body;
242
0
        RETURN_IF_ERROR(adapter->build_request_payload(
243
0
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
0
        std::string response;
246
0
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
0
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
0
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
0
        if (parsed_response.size() != batch_prompts.size()) {
252
0
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
0
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
0
                         << ", expected_rows=" << batch_prompts.size()
255
0
                         << ", actual_rows=" << parsed_response.size()
256
0
                         << ", response_body=" << response;
257
0
            return Status::RuntimeError(
258
0
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
0
                    batch_prompts.size(), parsed_response.size());
260
0
        }
261
0
        results = std::move(parsed_response);
262
0
        return Status::OK();
263
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
207
2
                                 FunctionContext* context) const {
208
2
#ifdef BE_TEST
209
2
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
2
        if (test_result != nullptr) {
211
1
            std::vector<std::string> parsed_test_response;
212
1
            RETURN_IF_ERROR(
213
1
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
1
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
1
            if (parsed_test_response.size() != batch_prompts.size()) {
218
0
                return Status::RuntimeError(
219
0
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
0
                        batch_prompts.size(), parsed_test_response.size());
221
0
            }
222
1
            results = std::move(parsed_test_response);
223
1
            return Status::OK();
224
1
        }
225
1
        if (config.provider_type == "MOCK") {
226
1
            results.clear();
227
1
            results.reserve(batch_prompts.size());
228
1
            for (const auto& prompt : batch_prompts) {
229
1
                results.emplace_back("this is a mock response. " + prompt);
230
1
            }
231
1
            return Status::OK();
232
1
        }
233
0
#endif
234
235
0
        std::string batch_prompt;
236
0
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
0
        std::vector<std::string> inputs = {batch_prompt};
239
0
        std::vector<std::string> parsed_response;
240
241
0
        std::string request_body;
242
0
        RETURN_IF_ERROR(adapter->build_request_payload(
243
0
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
0
        std::string response;
246
0
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
0
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
0
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
0
        if (parsed_response.size() != batch_prompts.size()) {
252
0
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
0
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
0
                         << ", expected_rows=" << batch_prompts.size()
255
0
                         << ", actual_rows=" << parsed_response.size()
256
0
                         << ", response_body=" << response;
257
0
            return Status::RuntimeError(
258
0
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
0
                    batch_prompts.size(), parsed_response.size());
260
0
        }
261
0
        results = std::move(parsed_response);
262
0
        return Status::OK();
263
0
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
207
10
                                 FunctionContext* context) const {
208
10
#ifdef BE_TEST
209
10
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
10
        if (test_result != nullptr) {
211
0
            std::vector<std::string> parsed_test_response;
212
0
            RETURN_IF_ERROR(
213
0
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
0
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
0
            if (parsed_test_response.size() != batch_prompts.size()) {
218
0
                return Status::RuntimeError(
219
0
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
0
                        batch_prompts.size(), parsed_test_response.size());
221
0
            }
222
0
            results = std::move(parsed_test_response);
223
0
            return Status::OK();
224
0
        }
225
10
        if (config.provider_type == "MOCK") {
226
0
            results.clear();
227
0
            results.reserve(batch_prompts.size());
228
0
            for (const auto& prompt : batch_prompts) {
229
0
                results.emplace_back("this is a mock response. " + prompt);
230
0
            }
231
0
            return Status::OK();
232
0
        }
233
10
#endif
234
235
10
        std::string batch_prompt;
236
10
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
10
        std::vector<std::string> inputs = {batch_prompt};
239
10
        std::vector<std::string> parsed_response;
240
241
10
        std::string request_body;
242
10
        RETURN_IF_ERROR(adapter->build_request_payload(
243
10
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
10
        std::string response;
246
10
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
10
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
10
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
10
        if (parsed_response.size() != batch_prompts.size()) {
252
0
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
0
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
0
                         << ", expected_rows=" << batch_prompts.size()
255
0
                         << ", actual_rows=" << parsed_response.size()
256
0
                         << ", response_body=" << response;
257
0
            return Status::RuntimeError(
258
0
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
0
                    batch_prompts.size(), parsed_response.size());
260
0
        }
261
10
        results = std::move(parsed_response);
262
10
        return Status::OK();
263
10
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
207
2
                                 FunctionContext* context) const {
208
2
#ifdef BE_TEST
209
2
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
2
        if (test_result != nullptr) {
211
2
            std::vector<std::string> parsed_test_response;
212
2
            RETURN_IF_ERROR(
213
2
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
2
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
2
            if (parsed_test_response.size() != batch_prompts.size()) {
218
0
                return Status::RuntimeError(
219
0
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
0
                        batch_prompts.size(), parsed_test_response.size());
221
0
            }
222
2
            results = std::move(parsed_test_response);
223
2
            return Status::OK();
224
2
        }
225
0
        if (config.provider_type == "MOCK") {
226
0
            results.clear();
227
0
            results.reserve(batch_prompts.size());
228
0
            for (const auto& prompt : batch_prompts) {
229
0
                results.emplace_back("this is a mock response. " + prompt);
230
0
            }
231
0
            return Status::OK();
232
0
        }
233
0
#endif
234
235
0
        std::string batch_prompt;
236
0
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
0
        std::vector<std::string> inputs = {batch_prompt};
239
0
        std::vector<std::string> parsed_response;
240
241
0
        std::string request_body;
242
0
        RETURN_IF_ERROR(adapter->build_request_payload(
243
0
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
0
        std::string response;
246
0
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
0
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
0
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
0
        if (parsed_response.size() != batch_prompts.size()) {
252
0
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
0
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
0
                         << ", expected_rows=" << batch_prompts.size()
255
0
                         << ", actual_rows=" << parsed_response.size()
256
0
                         << ", response_body=" << response;
257
0
            return Status::RuntimeError(
258
0
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
0
                    batch_prompts.size(), parsed_response.size());
260
0
        }
261
0
        results = std::move(parsed_response);
262
0
        return Status::OK();
263
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
207
22
                                 FunctionContext* context) const {
208
22
#ifdef BE_TEST
209
22
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
22
        if (test_result != nullptr) {
211
22
            std::vector<std::string> parsed_test_response;
212
22
            RETURN_IF_ERROR(
213
22
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
22
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
22
            if (parsed_test_response.size() != batch_prompts.size()) {
218
0
                return Status::RuntimeError(
219
0
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
0
                        batch_prompts.size(), parsed_test_response.size());
221
0
            }
222
22
            results = std::move(parsed_test_response);
223
22
            return Status::OK();
224
22
        }
225
0
        if (config.provider_type == "MOCK") {
226
0
            results.clear();
227
0
            results.reserve(batch_prompts.size());
228
0
            for (const auto& prompt : batch_prompts) {
229
0
                results.emplace_back("this is a mock response. " + prompt);
230
0
            }
231
0
            return Status::OK();
232
0
        }
233
0
#endif
234
235
0
        std::string batch_prompt;
236
0
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
0
        std::vector<std::string> inputs = {batch_prompt};
239
0
        std::vector<std::string> parsed_response;
240
241
0
        std::string request_body;
242
0
        RETURN_IF_ERROR(adapter->build_request_payload(
243
0
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
0
        std::string response;
246
0
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
0
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
0
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
0
        if (parsed_response.size() != batch_prompts.size()) {
252
0
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
0
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
0
                         << ", expected_rows=" << batch_prompts.size()
255
0
                         << ", actual_rows=" << parsed_response.size()
256
0
                         << ", response_body=" << response;
257
0
            return Status::RuntimeError(
258
0
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
0
                    batch_prompts.size(), parsed_response.size());
260
0
        }
261
0
        results = std::move(parsed_response);
262
0
        return Status::OK();
263
0
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
207
51
                                 FunctionContext* context) const {
208
51
#ifdef BE_TEST
209
51
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
51
        if (test_result != nullptr) {
211
51
            std::vector<std::string> parsed_test_response;
212
51
            RETURN_IF_ERROR(
213
51
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
50
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
50
            if (parsed_test_response.size() != batch_prompts.size()) {
218
5
                return Status::RuntimeError(
219
5
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
5
                        batch_prompts.size(), parsed_test_response.size());
221
5
            }
222
45
            results = std::move(parsed_test_response);
223
45
            return Status::OK();
224
50
        }
225
0
        if (config.provider_type == "MOCK") {
226
0
            results.clear();
227
0
            results.reserve(batch_prompts.size());
228
0
            for (const auto& prompt : batch_prompts) {
229
0
                results.emplace_back("this is a mock response. " + prompt);
230
0
            }
231
0
            return Status::OK();
232
0
        }
233
0
#endif
234
235
0
        std::string batch_prompt;
236
0
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
0
        std::vector<std::string> inputs = {batch_prompt};
239
0
        std::vector<std::string> parsed_response;
240
241
0
        std::string request_body;
242
0
        RETURN_IF_ERROR(adapter->build_request_payload(
243
0
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
0
        std::string response;
246
0
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
0
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
0
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
0
        if (parsed_response.size() != batch_prompts.size()) {
252
0
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
0
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
0
                         << ", expected_rows=" << batch_prompts.size()
255
0
                         << ", actual_rows=" << parsed_response.size()
256
0
                         << ", response_body=" << response;
257
0
            return Status::RuntimeError(
258
0
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
0
                    batch_prompts.size(), parsed_response.size());
260
0
        }
261
0
        results = std::move(parsed_response);
262
0
        return Status::OK();
263
0
    }
_ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
207
2
                                 FunctionContext* context) const {
208
2
#ifdef BE_TEST
209
2
        const char* test_result = std::getenv("AI_TEST_RESULT");
210
2
        if (test_result != nullptr) {
211
0
            std::vector<std::string> parsed_test_response;
212
0
            RETURN_IF_ERROR(
213
0
                    adapter->parse_response(std::string(test_result), parsed_test_response));
214
0
            if (parsed_test_response.empty()) {
215
0
                return Status::InternalError("AI returned empty result");
216
0
            }
217
0
            if (parsed_test_response.size() != batch_prompts.size()) {
218
0
                return Status::RuntimeError(
219
0
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
220
0
                        batch_prompts.size(), parsed_test_response.size());
221
0
            }
222
0
            results = std::move(parsed_test_response);
223
0
            return Status::OK();
224
0
        }
225
2
        if (config.provider_type == "MOCK") {
226
0
            results.clear();
227
0
            results.reserve(batch_prompts.size());
228
0
            for (const auto& prompt : batch_prompts) {
229
0
                results.emplace_back("this is a mock response. " + prompt);
230
0
            }
231
0
            return Status::OK();
232
0
        }
233
2
#endif
234
235
2
        std::string batch_prompt;
236
2
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
237
238
2
        std::vector<std::string> inputs = {batch_prompt};
239
2
        std::vector<std::string> parsed_response;
240
241
2
        std::string request_body;
242
2
        RETURN_IF_ERROR(adapter->build_request_payload(
243
2
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
244
245
2
        std::string response;
246
2
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
247
2
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
248
2
        if (parsed_response.empty()) {
249
0
            return Status::InternalError("AI returned empty result");
250
0
        }
251
2
        if (parsed_response.size() != batch_prompts.size()) {
252
1
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
253
1
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
254
1
                         << ", expected_rows=" << batch_prompts.size()
255
1
                         << ", actual_rows=" << parsed_response.size()
256
1
                         << ", response_body=" << response;
257
1
            return Status::RuntimeError(
258
1
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
259
1
                    batch_prompts.size(), parsed_response.size());
260
1
        }
261
1
        results = std::move(parsed_response);
262
1
        return Status::OK();
263
2
    }
264
265
    // Provider-reusable helper for string-returning functions.
266
    // Runs the common batch execution flow; derived classes only need to define how one batch of
267
    // string results is inserted into the final output column.
268
    Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
269
                   uint32_t result, size_t input_rows_count, const AIResource& config,
270
81
                   std::shared_ptr<AIAdapter>& adapter) const {
271
81
        Columns prompt_columns;
272
81
        prompt_columns.reserve(arguments.size() - 1);
273
81
        ColumnUInt8::MutablePtr result_null_map;
274
186
        for (size_t i = 1; i < arguments.size(); ++i) {
275
105
            const auto& argument = block.get_by_position(arguments[i]);
276
105
            if (argument.type->is_nullable()) {
277
12
                const auto& [column, is_const] = unpack_if_const(argument.column);
278
12
                const auto& nullable =
279
12
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
280
12
                if (!result_null_map) {
281
11
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
282
11
                }
283
12
                VectorizedUtils::update_null_map(result_null_map->get_data(),
284
12
                                                 nullable.get_null_map_data(), is_const);
285
12
            }
286
105
            prompt_columns.emplace_back(
287
105
                    argument.unnest_nullable(argument.type->is_nullable()
288
105
                                                     ? argument.get_nullable_column_info()
289
105
                                                     : NullableColumnInfo {},
290
105
                                             false)
291
105
                            .column);
292
105
        }
293
294
81
        if (result_null_map &&
295
81
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
296
1
            block.get_by_position(result).column =
297
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
298
1
                                                                            Field());
299
1
            return Status::OK();
300
1
        }
301
302
80
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
303
80
        std::vector<std::string> batch_prompts;
304
80
        size_t current_batch_size = 2; // []
305
80
        const size_t max_batch_prompt_size =
306
80
                static_cast<size_t>(get_ai_context_window_size(context));
307
80
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
308
309
204
        for (size_t i = 0; i < input_rows_count; ++i) {
310
124
            if (null_map && (*null_map)[i]) {
311
14
                continue;
312
14
            }
313
314
110
            std::string prompt;
315
110
            RETURN_IF_ERROR(
316
110
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
317
318
110
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
319
110
            if (entry_size > max_batch_prompt_size) {
320
14
                if (!batch_prompts.empty()) {
321
1
                    std::vector<std::string> batch_results;
322
1
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
323
1
                                                                config, adapter, context));
324
1
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
325
1
                            batch_results, *col_result));
326
1
                    batch_prompts.clear();
327
1
                    current_batch_size = 2;
328
1
                }
329
330
14
                std::vector<std::string> single_prompts;
331
14
                single_prompts.emplace_back(std::move(prompt));
332
14
                std::vector<std::string> single_results;
333
14
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
334
14
                                                            adapter, context));
335
14
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
336
14
                        single_results, *col_result));
337
14
                continue;
338
14
            }
339
340
96
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
341
96
            if (!batch_prompts.empty() &&
342
96
                current_batch_size + additional_size > max_batch_prompt_size) {
343
2
                std::vector<std::string> batch_results;
344
2
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
345
2
                                                            adapter, context));
346
2
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
347
2
                        batch_results, *col_result));
348
2
                batch_prompts.clear();
349
2
                current_batch_size = 2;
350
2
                additional_size = entry_size;
351
2
            }
352
353
96
            batch_prompts.emplace_back(std::move(prompt));
354
96
            current_batch_size += additional_size;
355
96
        }
356
357
80
        if (!batch_prompts.empty()) {
358
72
            std::vector<std::string> batch_results;
359
72
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
360
72
                                                        adapter, context));
361
66
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
362
66
                                                                                    *col_result));
363
66
        }
364
365
47
        if (!result_null_map) {
366
37
            block.replace_by_position(result, std::move(col_result));
367
37
            return Status::OK();
368
37
        }
369
370
10
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
371
1
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
372
1
                                                                     std::move(result_null_map)));
373
1
            return Status::OK();
374
1
        }
375
376
9
        auto nested_result = col_result->clone_empty();
377
9
        size_t result_row = 0;
378
31
        for (UInt8 is_null : result_null_map->get_data()) {
379
31
            if (is_null) {
380
14
                nested_result->insert_default();
381
17
            } else {
382
17
                nested_result->insert_from(*col_result, result_row++);
383
17
            }
384
31
        }
385
386
9
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
387
9
                                                                 std::move(result_null_map)));
388
9
        return Status::OK();
389
10
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
270
2
                   std::shared_ptr<AIAdapter>& adapter) const {
271
2
        Columns prompt_columns;
272
2
        prompt_columns.reserve(arguments.size() - 1);
273
2
        ColumnUInt8::MutablePtr result_null_map;
274
6
        for (size_t i = 1; i < arguments.size(); ++i) {
275
4
            const auto& argument = block.get_by_position(arguments[i]);
276
4
            if (argument.type->is_nullable()) {
277
1
                const auto& [column, is_const] = unpack_if_const(argument.column);
278
1
                const auto& nullable =
279
1
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
280
1
                if (!result_null_map) {
281
1
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
282
1
                }
283
1
                VectorizedUtils::update_null_map(result_null_map->get_data(),
284
1
                                                 nullable.get_null_map_data(), is_const);
285
1
            }
286
4
            prompt_columns.emplace_back(
287
4
                    argument.unnest_nullable(argument.type->is_nullable()
288
4
                                                     ? argument.get_nullable_column_info()
289
4
                                                     : NullableColumnInfo {},
290
4
                                             false)
291
4
                            .column);
292
4
        }
293
294
2
        if (result_null_map &&
295
2
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
296
0
            block.get_by_position(result).column =
297
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
298
0
                                                                            Field());
299
0
            return Status::OK();
300
0
        }
301
302
2
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
303
2
        std::vector<std::string> batch_prompts;
304
2
        size_t current_batch_size = 2; // []
305
2
        const size_t max_batch_prompt_size =
306
2
                static_cast<size_t>(get_ai_context_window_size(context));
307
2
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
308
309
6
        for (size_t i = 0; i < input_rows_count; ++i) {
310
4
            if (null_map && (*null_map)[i]) {
311
2
                continue;
312
2
            }
313
314
2
            std::string prompt;
315
2
            RETURN_IF_ERROR(
316
2
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
317
318
2
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
319
2
            if (entry_size > max_batch_prompt_size) {
320
0
                if (!batch_prompts.empty()) {
321
0
                    std::vector<std::string> batch_results;
322
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
323
0
                                                                config, adapter, context));
324
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
325
0
                            batch_results, *col_result));
326
0
                    batch_prompts.clear();
327
0
                    current_batch_size = 2;
328
0
                }
329
330
0
                std::vector<std::string> single_prompts;
331
0
                single_prompts.emplace_back(std::move(prompt));
332
0
                std::vector<std::string> single_results;
333
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
334
0
                                                            adapter, context));
335
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
336
0
                        single_results, *col_result));
337
0
                continue;
338
0
            }
339
340
2
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
341
2
            if (!batch_prompts.empty() &&
342
2
                current_batch_size + additional_size > max_batch_prompt_size) {
343
0
                std::vector<std::string> batch_results;
344
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
345
0
                                                            adapter, context));
346
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
347
0
                        batch_results, *col_result));
348
0
                batch_prompts.clear();
349
0
                current_batch_size = 2;
350
0
                additional_size = entry_size;
351
0
            }
352
353
2
            batch_prompts.emplace_back(std::move(prompt));
354
2
            current_batch_size += additional_size;
355
2
        }
356
357
2
        if (!batch_prompts.empty()) {
358
2
            std::vector<std::string> batch_results;
359
2
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
360
2
                                                        adapter, context));
361
2
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
362
2
                                                                                    *col_result));
363
2
        }
364
365
2
        if (!result_null_map) {
366
1
            block.replace_by_position(result, std::move(col_result));
367
1
            return Status::OK();
368
1
        }
369
370
1
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
371
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
372
0
                                                                     std::move(result_null_map)));
373
0
            return Status::OK();
374
0
        }
375
376
1
        auto nested_result = col_result->clone_empty();
377
1
        size_t result_row = 0;
378
3
        for (UInt8 is_null : result_null_map->get_data()) {
379
3
            if (is_null) {
380
2
                nested_result->insert_default();
381
2
            } else {
382
1
                nested_result->insert_from(*col_result, result_row++);
383
1
            }
384
3
        }
385
386
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
387
1
                                                                 std::move(result_null_map)));
388
1
        return Status::OK();
389
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
270
2
                   std::shared_ptr<AIAdapter>& adapter) const {
271
2
        Columns prompt_columns;
272
2
        prompt_columns.reserve(arguments.size() - 1);
273
2
        ColumnUInt8::MutablePtr result_null_map;
274
4
        for (size_t i = 1; i < arguments.size(); ++i) {
275
2
            const auto& argument = block.get_by_position(arguments[i]);
276
2
            if (argument.type->is_nullable()) {
277
0
                const auto& [column, is_const] = unpack_if_const(argument.column);
278
0
                const auto& nullable =
279
0
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
280
0
                if (!result_null_map) {
281
0
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
282
0
                }
283
0
                VectorizedUtils::update_null_map(result_null_map->get_data(),
284
0
                                                 nullable.get_null_map_data(), is_const);
285
0
            }
286
2
            prompt_columns.emplace_back(
287
2
                    argument.unnest_nullable(argument.type->is_nullable()
288
2
                                                     ? argument.get_nullable_column_info()
289
2
                                                     : NullableColumnInfo {},
290
2
                                             false)
291
2
                            .column);
292
2
        }
293
294
2
        if (result_null_map &&
295
2
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
296
0
            block.get_by_position(result).column =
297
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
298
0
                                                                            Field());
299
0
            return Status::OK();
300
0
        }
301
302
2
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
303
2
        std::vector<std::string> batch_prompts;
304
2
        size_t current_batch_size = 2; // []
305
2
        const size_t max_batch_prompt_size =
306
2
                static_cast<size_t>(get_ai_context_window_size(context));
307
2
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
308
309
6
        for (size_t i = 0; i < input_rows_count; ++i) {
310
4
            if (null_map && (*null_map)[i]) {
311
0
                continue;
312
0
            }
313
314
4
            std::string prompt;
315
4
            RETURN_IF_ERROR(
316
4
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
317
318
4
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
319
4
            if (entry_size > max_batch_prompt_size) {
320
0
                if (!batch_prompts.empty()) {
321
0
                    std::vector<std::string> batch_results;
322
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
323
0
                                                                config, adapter, context));
324
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
325
0
                            batch_results, *col_result));
326
0
                    batch_prompts.clear();
327
0
                    current_batch_size = 2;
328
0
                }
329
330
0
                std::vector<std::string> single_prompts;
331
0
                single_prompts.emplace_back(std::move(prompt));
332
0
                std::vector<std::string> single_results;
333
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
334
0
                                                            adapter, context));
335
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
336
0
                        single_results, *col_result));
337
0
                continue;
338
0
            }
339
340
4
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
341
4
            if (!batch_prompts.empty() &&
342
4
                current_batch_size + additional_size > max_batch_prompt_size) {
343
0
                std::vector<std::string> batch_results;
344
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
345
0
                                                            adapter, context));
346
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
347
0
                        batch_results, *col_result));
348
0
                batch_prompts.clear();
349
0
                current_batch_size = 2;
350
0
                additional_size = entry_size;
351
0
            }
352
353
4
            batch_prompts.emplace_back(std::move(prompt));
354
4
            current_batch_size += additional_size;
355
4
        }
356
357
2
        if (!batch_prompts.empty()) {
358
2
            std::vector<std::string> batch_results;
359
2
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
360
2
                                                        adapter, context));
361
2
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
362
2
                                                                                    *col_result));
363
2
        }
364
365
2
        if (!result_null_map) {
366
2
            block.replace_by_position(result, std::move(col_result));
367
2
            return Status::OK();
368
2
        }
369
370
0
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
371
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
372
0
                                                                     std::move(result_null_map)));
373
0
            return Status::OK();
374
0
        }
375
376
0
        auto nested_result = col_result->clone_empty();
377
0
        size_t result_row = 0;
378
0
        for (UInt8 is_null : result_null_map->get_data()) {
379
0
            if (is_null) {
380
0
                nested_result->insert_default();
381
0
            } else {
382
0
                nested_result->insert_from(*col_result, result_row++);
383
0
            }
384
0
        }
385
386
0
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
387
0
                                                                 std::move(result_null_map)));
388
0
        return Status::OK();
389
0
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
270
5
                   std::shared_ptr<AIAdapter>& adapter) const {
271
5
        Columns prompt_columns;
272
5
        prompt_columns.reserve(arguments.size() - 1);
273
5
        ColumnUInt8::MutablePtr result_null_map;
274
10
        for (size_t i = 1; i < arguments.size(); ++i) {
275
5
            const auto& argument = block.get_by_position(arguments[i]);
276
5
            if (argument.type->is_nullable()) {
277
5
                const auto& [column, is_const] = unpack_if_const(argument.column);
278
5
                const auto& nullable =
279
5
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
280
5
                if (!result_null_map) {
281
5
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
282
5
                }
283
5
                VectorizedUtils::update_null_map(result_null_map->get_data(),
284
5
                                                 nullable.get_null_map_data(), is_const);
285
5
            }
286
5
            prompt_columns.emplace_back(
287
5
                    argument.unnest_nullable(argument.type->is_nullable()
288
5
                                                     ? argument.get_nullable_column_info()
289
5
                                                     : NullableColumnInfo {},
290
5
                                             false)
291
5
                            .column);
292
5
        }
293
294
5
        if (result_null_map &&
295
5
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
296
0
            block.get_by_position(result).column =
297
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
298
0
                                                                            Field());
299
0
            return Status::OK();
300
0
        }
301
302
5
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
303
5
        std::vector<std::string> batch_prompts;
304
5
        size_t current_batch_size = 2; // []
305
5
        const size_t max_batch_prompt_size =
306
5
                static_cast<size_t>(get_ai_context_window_size(context));
307
5
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
308
309
20
        for (size_t i = 0; i < input_rows_count; ++i) {
310
15
            if (null_map && (*null_map)[i]) {
311
5
                continue;
312
5
            }
313
314
10
            std::string prompt;
315
10
            RETURN_IF_ERROR(
316
10
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
317
318
10
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
319
10
            if (entry_size > max_batch_prompt_size) {
320
10
                if (!batch_prompts.empty()) {
321
0
                    std::vector<std::string> batch_results;
322
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
323
0
                                                                config, adapter, context));
324
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
325
0
                            batch_results, *col_result));
326
0
                    batch_prompts.clear();
327
0
                    current_batch_size = 2;
328
0
                }
329
330
10
                std::vector<std::string> single_prompts;
331
10
                single_prompts.emplace_back(std::move(prompt));
332
10
                std::vector<std::string> single_results;
333
10
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
334
10
                                                            adapter, context));
335
10
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
336
10
                        single_results, *col_result));
337
10
                continue;
338
10
            }
339
340
0
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
341
0
            if (!batch_prompts.empty() &&
342
0
                current_batch_size + additional_size > max_batch_prompt_size) {
343
0
                std::vector<std::string> batch_results;
344
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
345
0
                                                            adapter, context));
346
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
347
0
                        batch_results, *col_result));
348
0
                batch_prompts.clear();
349
0
                current_batch_size = 2;
350
0
                additional_size = entry_size;
351
0
            }
352
353
0
            batch_prompts.emplace_back(std::move(prompt));
354
0
            current_batch_size += additional_size;
355
0
        }
356
357
5
        if (!batch_prompts.empty()) {
358
0
            std::vector<std::string> batch_results;
359
0
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
360
0
                                                        adapter, context));
361
0
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
362
0
                                                                                    *col_result));
363
0
        }
364
365
5
        if (!result_null_map) {
366
0
            block.replace_by_position(result, std::move(col_result));
367
0
            return Status::OK();
368
0
        }
369
370
5
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
371
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
372
0
                                                                     std::move(result_null_map)));
373
0
            return Status::OK();
374
0
        }
375
376
5
        auto nested_result = col_result->clone_empty();
377
5
        size_t result_row = 0;
378
15
        for (UInt8 is_null : result_null_map->get_data()) {
379
15
            if (is_null) {
380
5
                nested_result->insert_default();
381
10
            } else {
382
10
                nested_result->insert_from(*col_result, result_row++);
383
10
            }
384
15
        }
385
386
5
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
387
5
                                                                 std::move(result_null_map)));
388
5
        return Status::OK();
389
5
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
270
3
                   std::shared_ptr<AIAdapter>& adapter) const {
271
3
        Columns prompt_columns;
272
3
        prompt_columns.reserve(arguments.size() - 1);
273
3
        ColumnUInt8::MutablePtr result_null_map;
274
6
        for (size_t i = 1; i < arguments.size(); ++i) {
275
3
            const auto& argument = block.get_by_position(arguments[i]);
276
3
            if (argument.type->is_nullable()) {
277
3
                const auto& [column, is_const] = unpack_if_const(argument.column);
278
3
                const auto& nullable =
279
3
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
280
3
                if (!result_null_map) {
281
3
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
282
3
                }
283
3
                VectorizedUtils::update_null_map(result_null_map->get_data(),
284
3
                                                 nullable.get_null_map_data(), is_const);
285
3
            }
286
3
            prompt_columns.emplace_back(
287
3
                    argument.unnest_nullable(argument.type->is_nullable()
288
3
                                                     ? argument.get_nullable_column_info()
289
3
                                                     : NullableColumnInfo {},
290
3
                                             false)
291
3
                            .column);
292
3
        }
293
294
3
        if (result_null_map &&
295
3
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
296
1
            block.get_by_position(result).column =
297
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
298
1
                                                                            Field());
299
1
            return Status::OK();
300
1
        }
301
302
2
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
303
2
        std::vector<std::string> batch_prompts;
304
2
        size_t current_batch_size = 2; // []
305
2
        const size_t max_batch_prompt_size =
306
2
                static_cast<size_t>(get_ai_context_window_size(context));
307
2
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
308
309
10
        for (size_t i = 0; i < input_rows_count; ++i) {
310
8
            if (null_map && (*null_map)[i]) {
311
3
                continue;
312
3
            }
313
314
5
            std::string prompt;
315
5
            RETURN_IF_ERROR(
316
5
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
317
318
5
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
319
5
            if (entry_size > max_batch_prompt_size) {
320
0
                if (!batch_prompts.empty()) {
321
0
                    std::vector<std::string> batch_results;
322
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
323
0
                                                                config, adapter, context));
324
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
325
0
                            batch_results, *col_result));
326
0
                    batch_prompts.clear();
327
0
                    current_batch_size = 2;
328
0
                }
329
330
0
                std::vector<std::string> single_prompts;
331
0
                single_prompts.emplace_back(std::move(prompt));
332
0
                std::vector<std::string> single_results;
333
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
334
0
                                                            adapter, context));
335
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
336
0
                        single_results, *col_result));
337
0
                continue;
338
0
            }
339
340
5
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
341
5
            if (!batch_prompts.empty() &&
342
5
                current_batch_size + additional_size > max_batch_prompt_size) {
343
0
                std::vector<std::string> batch_results;
344
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
345
0
                                                            adapter, context));
346
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
347
0
                        batch_results, *col_result));
348
0
                batch_prompts.clear();
349
0
                current_batch_size = 2;
350
0
                additional_size = entry_size;
351
0
            }
352
353
5
            batch_prompts.emplace_back(std::move(prompt));
354
5
            current_batch_size += additional_size;
355
5
        }
356
357
2
        if (!batch_prompts.empty()) {
358
2
            std::vector<std::string> batch_results;
359
2
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
360
2
                                                        adapter, context));
361
2
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
362
2
                                                                                    *col_result));
363
2
        }
364
365
2
        if (!result_null_map) {
366
0
            block.replace_by_position(result, std::move(col_result));
367
0
            return Status::OK();
368
0
        }
369
370
2
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
371
1
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
372
1
                                                                     std::move(result_null_map)));
373
1
            return Status::OK();
374
1
        }
375
376
1
        auto nested_result = col_result->clone_empty();
377
1
        size_t result_row = 0;
378
5
        for (UInt8 is_null : result_null_map->get_data()) {
379
5
            if (is_null) {
380
3
                nested_result->insert_default();
381
3
            } else {
382
2
                nested_result->insert_from(*col_result, result_row++);
383
2
            }
384
5
        }
385
386
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
387
1
                                                                 std::move(result_null_map)));
388
1
        return Status::OK();
389
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
270
22
                   std::shared_ptr<AIAdapter>& adapter) const {
271
22
        Columns prompt_columns;
272
22
        prompt_columns.reserve(arguments.size() - 1);
273
22
        ColumnUInt8::MutablePtr result_null_map;
274
66
        for (size_t i = 1; i < arguments.size(); ++i) {
275
44
            const auto& argument = block.get_by_position(arguments[i]);
276
44
            if (argument.type->is_nullable()) {
277
2
                const auto& [column, is_const] = unpack_if_const(argument.column);
278
2
                const auto& nullable =
279
2
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
280
2
                if (!result_null_map) {
281
1
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
282
1
                }
283
2
                VectorizedUtils::update_null_map(result_null_map->get_data(),
284
2
                                                 nullable.get_null_map_data(), is_const);
285
2
            }
286
44
            prompt_columns.emplace_back(
287
44
                    argument.unnest_nullable(argument.type->is_nullable()
288
44
                                                     ? argument.get_nullable_column_info()
289
44
                                                     : NullableColumnInfo {},
290
44
                                             false)
291
44
                            .column);
292
44
        }
293
294
22
        if (result_null_map &&
295
22
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
296
0
            block.get_by_position(result).column =
297
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
298
0
                                                                            Field());
299
0
            return Status::OK();
300
0
        }
301
302
22
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
303
22
        std::vector<std::string> batch_prompts;
304
22
        size_t current_batch_size = 2; // []
305
22
        const size_t max_batch_prompt_size =
306
22
                static_cast<size_t>(get_ai_context_window_size(context));
307
22
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
308
309
49
        for (size_t i = 0; i < input_rows_count; ++i) {
310
27
            if (null_map && (*null_map)[i]) {
311
2
                continue;
312
2
            }
313
314
25
            std::string prompt;
315
25
            RETURN_IF_ERROR(
316
25
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
317
318
25
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
319
25
            if (entry_size > max_batch_prompt_size) {
320
0
                if (!batch_prompts.empty()) {
321
0
                    std::vector<std::string> batch_results;
322
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
323
0
                                                                config, adapter, context));
324
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
325
0
                            batch_results, *col_result));
326
0
                    batch_prompts.clear();
327
0
                    current_batch_size = 2;
328
0
                }
329
330
0
                std::vector<std::string> single_prompts;
331
0
                single_prompts.emplace_back(std::move(prompt));
332
0
                std::vector<std::string> single_results;
333
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
334
0
                                                            adapter, context));
335
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
336
0
                        single_results, *col_result));
337
0
                continue;
338
0
            }
339
340
25
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
341
25
            if (!batch_prompts.empty() &&
342
25
                current_batch_size + additional_size > max_batch_prompt_size) {
343
0
                std::vector<std::string> batch_results;
344
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
345
0
                                                            adapter, context));
346
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
347
0
                        batch_results, *col_result));
348
0
                batch_prompts.clear();
349
0
                current_batch_size = 2;
350
0
                additional_size = entry_size;
351
0
            }
352
353
25
            batch_prompts.emplace_back(std::move(prompt));
354
25
            current_batch_size += additional_size;
355
25
        }
356
357
22
        if (!batch_prompts.empty()) {
358
22
            std::vector<std::string> batch_results;
359
22
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
360
22
                                                        adapter, context));
361
22
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
362
22
                                                                                    *col_result));
363
22
        }
364
365
16
        if (!result_null_map) {
366
15
            block.replace_by_position(result, std::move(col_result));
367
15
            return Status::OK();
368
15
        }
369
370
1
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
371
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
372
0
                                                                     std::move(result_null_map)));
373
0
            return Status::OK();
374
0
        }
375
376
1
        auto nested_result = col_result->clone_empty();
377
1
        size_t result_row = 0;
378
4
        for (UInt8 is_null : result_null_map->get_data()) {
379
4
            if (is_null) {
380
2
                nested_result->insert_default();
381
2
            } else {
382
2
                nested_result->insert_from(*col_result, result_row++);
383
2
            }
384
4
        }
385
386
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
387
1
                                                                 std::move(result_null_map)));
388
1
        return Status::OK();
389
1
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
270
47
                   std::shared_ptr<AIAdapter>& adapter) const {
271
47
        Columns prompt_columns;
272
47
        prompt_columns.reserve(arguments.size() - 1);
273
47
        ColumnUInt8::MutablePtr result_null_map;
274
94
        for (size_t i = 1; i < arguments.size(); ++i) {
275
47
            const auto& argument = block.get_by_position(arguments[i]);
276
47
            if (argument.type->is_nullable()) {
277
1
                const auto& [column, is_const] = unpack_if_const(argument.column);
278
1
                const auto& nullable =
279
1
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
280
1
                if (!result_null_map) {
281
1
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
282
1
                }
283
1
                VectorizedUtils::update_null_map(result_null_map->get_data(),
284
1
                                                 nullable.get_null_map_data(), is_const);
285
1
            }
286
47
            prompt_columns.emplace_back(
287
47
                    argument.unnest_nullable(argument.type->is_nullable()
288
47
                                                     ? argument.get_nullable_column_info()
289
47
                                                     : NullableColumnInfo {},
290
47
                                             false)
291
47
                            .column);
292
47
        }
293
294
47
        if (result_null_map &&
295
47
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
296
0
            block.get_by_position(result).column =
297
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
298
0
                                                                            Field());
299
0
            return Status::OK();
300
0
        }
301
302
47
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
303
47
        std::vector<std::string> batch_prompts;
304
47
        size_t current_batch_size = 2; // []
305
47
        const size_t max_batch_prompt_size =
306
47
                static_cast<size_t>(get_ai_context_window_size(context));
307
47
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
308
309
113
        for (size_t i = 0; i < input_rows_count; ++i) {
310
66
            if (null_map && (*null_map)[i]) {
311
2
                continue;
312
2
            }
313
314
64
            std::string prompt;
315
64
            RETURN_IF_ERROR(
316
64
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
317
318
64
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
319
64
            if (entry_size > max_batch_prompt_size) {
320
4
                if (!batch_prompts.empty()) {
321
1
                    std::vector<std::string> batch_results;
322
1
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
323
1
                                                                config, adapter, context));
324
1
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
325
1
                            batch_results, *col_result));
326
1
                    batch_prompts.clear();
327
1
                    current_batch_size = 2;
328
1
                }
329
330
4
                std::vector<std::string> single_prompts;
331
4
                single_prompts.emplace_back(std::move(prompt));
332
4
                std::vector<std::string> single_results;
333
4
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
334
4
                                                            adapter, context));
335
4
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
336
4
                        single_results, *col_result));
337
4
                continue;
338
4
            }
339
340
60
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
341
60
            if (!batch_prompts.empty() &&
342
60
                current_batch_size + additional_size > max_batch_prompt_size) {
343
2
                std::vector<std::string> batch_results;
344
2
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
345
2
                                                            adapter, context));
346
2
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
347
2
                        batch_results, *col_result));
348
2
                batch_prompts.clear();
349
2
                current_batch_size = 2;
350
2
                additional_size = entry_size;
351
2
            }
352
353
60
            batch_prompts.emplace_back(std::move(prompt));
354
60
            current_batch_size += additional_size;
355
60
        }
356
357
47
        if (!batch_prompts.empty()) {
358
44
            std::vector<std::string> batch_results;
359
44
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
360
44
                                                        adapter, context));
361
38
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
362
38
                                                                                    *col_result));
363
38
        }
364
365
20
        if (!result_null_map) {
366
19
            block.replace_by_position(result, std::move(col_result));
367
19
            return Status::OK();
368
19
        }
369
370
1
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
371
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
372
0
                                                                     std::move(result_null_map)));
373
0
            return Status::OK();
374
0
        }
375
376
1
        auto nested_result = col_result->clone_empty();
377
1
        size_t result_row = 0;
378
4
        for (UInt8 is_null : result_null_map->get_data()) {
379
4
            if (is_null) {
380
2
                nested_result->insert_default();
381
2
            } else {
382
2
                nested_result->insert_from(*col_result, result_row++);
383
2
            }
384
4
        }
385
386
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
387
1
                                                                 std::move(result_null_map)));
388
1
        return Status::OK();
389
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
390
391
private:
392
    // The ai resource must be literal
393
    Status _init_from_resource(FunctionContext* context, const Block& block,
394
                               const ColumnNumbers& arguments, AIResource& config,
395
91
                               std::shared_ptr<AIAdapter>& adapter) const {
396
91
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
397
91
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
398
91
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
399
400
91
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
401
91
                context->state()->get_query_ctx()->get_ai_resources();
402
91
        DORIS_CHECK(ai_resources);
403
91
        auto it = ai_resources->find(resource_name);
404
91
        DORIS_CHECK(it != ai_resources->end());
405
91
        PrimitiveType input_type = INVALID_TYPE;
406
91
        if (arguments.size() > 1) {
407
90
            input_type =
408
90
                    remove_nullable(block.get_by_position(arguments[1]).type)->get_primitive_type();
409
90
        }
410
91
        config = assert_cast<const Derived&>(*this).select_ai_resource(it->second, input_type);
411
412
91
        normalize_endpoint(config);
413
414
91
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
415
91
        DORIS_CHECK(adapter);
416
417
91
        adapter->init(config);
418
91
        return Status::OK();
419
91
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
395
2
                               std::shared_ptr<AIAdapter>& adapter) const {
396
2
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
397
2
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
398
2
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
399
400
2
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
401
2
                context->state()->get_query_ctx()->get_ai_resources();
402
2
        DORIS_CHECK(ai_resources);
403
2
        auto it = ai_resources->find(resource_name);
404
2
        DORIS_CHECK(it != ai_resources->end());
405
2
        PrimitiveType input_type = INVALID_TYPE;
406
2
        if (arguments.size() > 1) {
407
2
            input_type =
408
2
                    remove_nullable(block.get_by_position(arguments[1]).type)->get_primitive_type();
409
2
        }
410
2
        config = assert_cast<const Derived&>(*this).select_ai_resource(it->second, input_type);
411
412
2
        normalize_endpoint(config);
413
414
2
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
415
2
        DORIS_CHECK(adapter);
416
417
2
        adapter->init(config);
418
2
        return Status::OK();
419
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
395
2
                               std::shared_ptr<AIAdapter>& adapter) const {
396
2
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
397
2
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
398
2
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
399
400
2
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
401
2
                context->state()->get_query_ctx()->get_ai_resources();
402
2
        DORIS_CHECK(ai_resources);
403
2
        auto it = ai_resources->find(resource_name);
404
2
        DORIS_CHECK(it != ai_resources->end());
405
2
        PrimitiveType input_type = INVALID_TYPE;
406
2
        if (arguments.size() > 1) {
407
2
            input_type =
408
2
                    remove_nullable(block.get_by_position(arguments[1]).type)->get_primitive_type();
409
2
        }
410
2
        config = assert_cast<const Derived&>(*this).select_ai_resource(it->second, input_type);
411
412
2
        normalize_endpoint(config);
413
414
2
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
415
2
        DORIS_CHECK(adapter);
416
417
2
        adapter->init(config);
418
2
        return Status::OK();
419
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
395
3
                               std::shared_ptr<AIAdapter>& adapter) const {
396
3
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
397
3
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
398
3
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
399
400
3
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
401
3
                context->state()->get_query_ctx()->get_ai_resources();
402
3
        DORIS_CHECK(ai_resources);
403
3
        auto it = ai_resources->find(resource_name);
404
3
        DORIS_CHECK(it != ai_resources->end());
405
3
        PrimitiveType input_type = INVALID_TYPE;
406
3
        if (arguments.size() > 1) {
407
3
            input_type =
408
3
                    remove_nullable(block.get_by_position(arguments[1]).type)->get_primitive_type();
409
3
        }
410
3
        config = assert_cast<const Derived&>(*this).select_ai_resource(it->second, input_type);
411
412
3
        normalize_endpoint(config);
413
414
3
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
415
3
        DORIS_CHECK(adapter);
416
417
3
        adapter->init(config);
418
3
        return Status::OK();
419
3
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
395
22
                               std::shared_ptr<AIAdapter>& adapter) const {
396
22
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
397
22
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
398
22
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
399
400
22
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
401
22
                context->state()->get_query_ctx()->get_ai_resources();
402
22
        DORIS_CHECK(ai_resources);
403
22
        auto it = ai_resources->find(resource_name);
404
22
        DORIS_CHECK(it != ai_resources->end());
405
22
        PrimitiveType input_type = INVALID_TYPE;
406
22
        if (arguments.size() > 1) {
407
22
            input_type =
408
22
                    remove_nullable(block.get_by_position(arguments[1]).type)->get_primitive_type();
409
22
        }
410
22
        config = assert_cast<const Derived&>(*this).select_ai_resource(it->second, input_type);
411
412
22
        normalize_endpoint(config);
413
414
22
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
415
22
        DORIS_CHECK(adapter);
416
417
22
        adapter->init(config);
418
22
        return Status::OK();
419
22
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
395
47
                               std::shared_ptr<AIAdapter>& adapter) const {
396
47
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
397
47
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
398
47
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
399
400
47
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
401
47
                context->state()->get_query_ctx()->get_ai_resources();
402
47
        DORIS_CHECK(ai_resources);
403
47
        auto it = ai_resources->find(resource_name);
404
47
        DORIS_CHECK(it != ai_resources->end());
405
47
        PrimitiveType input_type = INVALID_TYPE;
406
47
        if (arguments.size() > 1) {
407
47
            input_type =
408
47
                    remove_nullable(block.get_by_position(arguments[1]).type)->get_primitive_type();
409
47
        }
410
47
        config = assert_cast<const Derived&>(*this).select_ai_resource(it->second, input_type);
411
412
47
        normalize_endpoint(config);
413
414
47
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
415
47
        DORIS_CHECK(adapter);
416
417
47
        adapter->init(config);
418
47
        return Status::OK();
419
47
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
395
15
                               std::shared_ptr<AIAdapter>& adapter) const {
396
15
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
397
15
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
398
15
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
399
400
15
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
401
15
                context->state()->get_query_ctx()->get_ai_resources();
402
15
        DORIS_CHECK(ai_resources);
403
15
        auto it = ai_resources->find(resource_name);
404
15
        DORIS_CHECK(it != ai_resources->end());
405
15
        PrimitiveType input_type = INVALID_TYPE;
406
15
        if (arguments.size() > 1) {
407
14
            input_type =
408
14
                    remove_nullable(block.get_by_position(arguments[1]).type)->get_primitive_type();
409
14
        }
410
15
        config = assert_cast<const Derived&>(*this).select_ai_resource(it->second, input_type);
411
412
15
        normalize_endpoint(config);
413
414
15
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
415
15
        DORIS_CHECK(adapter);
416
417
15
        adapter->init(config);
418
15
        return Status::OK();
419
15
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_10AIResourceERSt10shared_ptrINS_9AIAdapterEE
420
421
76
    AIResource select_ai_resource(const TAIResource& resource, PrimitiveType /*input_type*/) const {
422
76
        return AIResource(resource);
423
76
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
Line
Count
Source
421
2
    AIResource select_ai_resource(const TAIResource& resource, PrimitiveType /*input_type*/) const {
422
2
        return AIResource(resource);
423
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
Line
Count
Source
421
2
    AIResource select_ai_resource(const TAIResource& resource, PrimitiveType /*input_type*/) const {
422
2
        return AIResource(resource);
423
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
Line
Count
Source
421
3
    AIResource select_ai_resource(const TAIResource& resource, PrimitiveType /*input_type*/) const {
422
3
        return AIResource(resource);
423
3
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
Line
Count
Source
421
22
    AIResource select_ai_resource(const TAIResource& resource, PrimitiveType /*input_type*/) const {
422
22
        return AIResource(resource);
423
22
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
Line
Count
Source
421
47
    AIResource select_ai_resource(const TAIResource& resource, PrimitiveType /*input_type*/) const {
422
47
        return AIResource(resource);
423
47
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE18select_ai_resourceERKNS_11TAIResourceENS_13PrimitiveTypeE
424
425
    // Serializes one text batch into the shared JSON-array prompt format consumed by LLM
426
    // providers for batch string functions.
427
    Status build_batch_prompt(const std::vector<std::string>& batch_prompts,
428
12
                              std::string& prompt) const {
429
12
        rapidjson::StringBuffer buffer;
430
12
        rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
431
432
12
        writer.StartArray();
433
26
        for (size_t i = 0; i < batch_prompts.size(); ++i) {
434
14
            writer.StartObject();
435
14
            writer.Key("idx");
436
14
            writer.Uint64(i);
437
14
            writer.Key("input");
438
14
            writer.String(batch_prompts[i].data(),
439
14
                          static_cast<rapidjson::SizeType>(batch_prompts[i].size()));
440
14
            writer.EndObject();
441
14
        }
442
12
        writer.EndArray();
443
444
12
        prompt = buffer.GetString();
445
12
        return Status::OK();
446
12
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Line
Count
Source
428
10
                              std::string& prompt) const {
429
10
        rapidjson::StringBuffer buffer;
430
10
        rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
431
432
10
        writer.StartArray();
433
20
        for (size_t i = 0; i < batch_prompts.size(); ++i) {
434
10
            writer.StartObject();
435
10
            writer.Key("idx");
436
10
            writer.Uint64(i);
437
10
            writer.Key("input");
438
10
            writer.String(batch_prompts[i].data(),
439
10
                          static_cast<rapidjson::SizeType>(batch_prompts[i].size()));
440
10
            writer.EndObject();
441
10
        }
442
10
        writer.EndArray();
443
444
10
        prompt = buffer.GetString();
445
10
        return Status::OK();
446
10
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
_ZNK5doris10AIFunctionINS_31FunctionAIFilterBatchTestHelperEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Line
Count
Source
428
2
                              std::string& prompt) const {
429
2
        rapidjson::StringBuffer buffer;
430
2
        rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
431
432
2
        writer.StartArray();
433
6
        for (size_t i = 0; i < batch_prompts.size(); ++i) {
434
4
            writer.StartObject();
435
4
            writer.Key("idx");
436
4
            writer.Uint64(i);
437
4
            writer.Key("input");
438
4
            writer.String(batch_prompts[i].data(),
439
4
                          static_cast<rapidjson::SizeType>(batch_prompts[i].size()));
440
4
            writer.EndObject();
441
4
        }
442
2
        writer.EndArray();
443
444
2
        prompt = buffer.GetString();
445
2
        return Status::OK();
446
2
    }
447
};
448
449
} // namespace doris