Coverage Report

Created: 2026-08-06 19:50

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/function.h"
46
#include "runtime/query_context.h"
47
#include "runtime/runtime_state.h"
48
#include "service/http/http_client.h"
49
#include "util/security.h"
50
#include "util/string_util.h"
51
#include "util/threadpool.h"
52
53
namespace doris {
54
55
// Base class for AI-based functions
56
template <typename Derived>
57
class AIFunction : public IFunction {
58
public:
59
16
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE8get_nameB5cxx11Ev
Line
Count
Source
59
6
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_17FunctionAIExtractEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_14FunctionAIMaskEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAITranslateEE8get_nameB5cxx11Ev
Line
Count
Source
59
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
60
61
    // If the user doesn't provide the first arg, `resource_name`
62
    // FE will add the `resource_name` to the arguments list using the Session Variable.
63
    // So the value here should be the maximum number that the function can accept.
64
12
    size_t get_number_of_arguments() const override {
65
12
        return assert_cast<const Derived&>(*this).number_of_arguments;
66
12
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE23get_number_of_argumentsEv
Line
Count
Source
64
4
    size_t get_number_of_arguments() const override {
65
4
        return assert_cast<const Derived&>(*this).number_of_arguments;
66
4
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE23get_number_of_argumentsEv
Line
Count
Source
64
1
    size_t get_number_of_arguments() const override {
65
1
        return assert_cast<const Derived&>(*this).number_of_arguments;
66
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE23get_number_of_argumentsEv
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE23get_number_of_argumentsEv
Line
Count
Source
64
2
    size_t get_number_of_arguments() const override {
65
2
        return assert_cast<const Derived&>(*this).number_of_arguments;
66
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE23get_number_of_argumentsEv
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE23get_number_of_argumentsEv
Line
Count
Source
64
4
    size_t get_number_of_arguments() const override {
65
4
        return assert_cast<const Derived&>(*this).number_of_arguments;
66
4
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE23get_number_of_argumentsEv
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE23get_number_of_argumentsEv
Line
Count
Source
64
1
    size_t get_number_of_arguments() const override {
65
1
        return assert_cast<const Derived&>(*this).number_of_arguments;
66
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE23get_number_of_argumentsEv
67
68
0
    bool is_blockable() const override { return true; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12is_blockableEv
69
70
24
    bool use_default_implementation_for_nulls() const final { return false; }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE36use_default_implementation_for_nullsEv
Line
Count
Source
70
8
    bool use_default_implementation_for_nulls() const final { return false; }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE36use_default_implementation_for_nullsEv
Line
Count
Source
70
2
    bool use_default_implementation_for_nulls() const final { return false; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE36use_default_implementation_for_nullsEv
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE36use_default_implementation_for_nullsEv
Line
Count
Source
70
4
    bool use_default_implementation_for_nulls() const final { return false; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE36use_default_implementation_for_nullsEv
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE36use_default_implementation_for_nullsEv
Line
Count
Source
70
8
    bool use_default_implementation_for_nulls() const final { return false; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE36use_default_implementation_for_nullsEv
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE36use_default_implementation_for_nullsEv
Line
Count
Source
70
2
    bool use_default_implementation_for_nulls() const final { return false; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE36use_default_implementation_for_nullsEv
71
72
23
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
23
        bool has_nullable_argument = std::ranges::any_of(
74
25
                arguments, [](const auto& argument) { return argument->is_nullable(); });
_ZZNK5doris10AIFunctionINS_13FunctionEmbedEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
74
8
                arguments, [](const auto& argument) { return argument->is_nullable(); });
_ZZNK5doris10AIFunctionINS_16FunctionAIFilterEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
74
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20get_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_
_ZZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
74
6
                arguments, [](const auto& argument) { return argument->is_nullable(); });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_17FunctionAIExtractEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
_ZZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
74
7
                arguments, [](const auto& argument) { return argument->is_nullable(); });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_14FunctionAIMaskEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
_ZZNK5doris10AIFunctionINS_20FunctionAISimilarityEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
Line
Count
Source
74
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAITranslateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EEENKUlRKT_E_clIS7_EEDaSE_
75
23
        DataTypePtr return_type =
76
23
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
23
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
23
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
5
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
5
        bool has_nullable_argument = std::ranges::any_of(
74
5
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
5
        DataTypePtr return_type =
76
5
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
5
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
5
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
2
        bool has_nullable_argument = std::ranges::any_of(
74
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
2
        DataTypePtr return_type =
76
2
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
2
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
2
    }
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
1
        bool has_nullable_argument = std::ranges::any_of(
74
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
1
        DataTypePtr return_type =
76
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
1
    }
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
1
        bool has_nullable_argument = std::ranges::any_of(
74
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
1
        DataTypePtr return_type =
76
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
1
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
1
        bool has_nullable_argument = std::ranges::any_of(
74
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
1
        DataTypePtr return_type =
76
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
1
    }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
3
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
3
        bool has_nullable_argument = std::ranges::any_of(
74
3
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
3
        DataTypePtr return_type =
76
3
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
3
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
3
    }
_ZNK5doris10AIFunctionINS_17FunctionAIExtractEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
1
        bool has_nullable_argument = std::ranges::any_of(
74
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
1
        DataTypePtr return_type =
76
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
1
    }
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
5
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
5
        bool has_nullable_argument = std::ranges::any_of(
74
5
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
5
        DataTypePtr return_type =
76
5
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
5
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
5
    }
_ZNK5doris10AIFunctionINS_14FunctionAIMaskEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
1
        bool has_nullable_argument = std::ranges::any_of(
74
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
1
        DataTypePtr return_type =
76
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
1
    }
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
2
        bool has_nullable_argument = std::ranges::any_of(
74
2
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
2
        DataTypePtr return_type =
76
2
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
2
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
2
    }
_ZNK5doris10AIFunctionINS_19FunctionAITranslateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
72
1
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const final {
73
1
        bool has_nullable_argument = std::ranges::any_of(
74
1
                arguments, [](const auto& argument) { return argument->is_nullable(); });
75
1
        DataTypePtr return_type =
76
1
                assert_cast<const Derived&>(*this).get_nested_return_type_impl(arguments);
77
1
        return has_nullable_argument ? make_nullable(return_type) : return_type;
78
1
    }
79
80
    using PreparedFunctionImpl::execute;
81
82
    virtual Status build_prompt(const Columns& prompt_columns, size_t row_num,
83
86
                                std::string& prompt) const {
84
86
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
85
86
        prompt = std::string(text_ref.data, text_ref.size);
86
87
86
        return Status::OK();
88
86
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
83
14
                                std::string& prompt) const {
84
14
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
85
14
        prompt = std::string(text_ref.data, text_ref.size);
86
87
14
        return Status::OK();
88
14
    }
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_16FunctionAIFilterEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
83
65
                                std::string& prompt) const {
84
65
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
85
65
        prompt = std::string(text_ref.data, text_ref.size);
86
87
65
        return Status::OK();
88
65
    }
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
83
1
                                std::string& prompt) const {
84
1
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
85
1
        prompt = std::string(text_ref.data, text_ref.size);
86
87
1
        return Status::OK();
88
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
83
5
                                std::string& prompt) const {
84
5
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
85
5
        prompt = std::string(text_ref.data, text_ref.size);
86
87
5
        return Status::OK();
88
5
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
83
1
                                std::string& prompt) const {
84
1
        StringRef text_ref = prompt_columns[0]->get_data_at(row_num);
85
1
        prompt = std::string(text_ref.data, text_ref.size);
86
87
1
        return Status::OK();
88
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12build_promptERKSt6vectorINS_3COWINS_7IColumnEE13immutable_ptrIS5_EESaIS8_EEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
89
90
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
91
91
                        uint32_t result, size_t input_rows_count) const override {
92
91
        if (block.get_by_position(arguments[0]).column->only_null()) {
93
1
            block.get_by_position(result).column =
94
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
95
1
                                                                            Field());
96
1
            return Status::OK();
97
1
        }
98
99
90
        TAIResource config;
100
90
        std::shared_ptr<AIAdapter> adapter;
101
90
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
102
90
            !status.ok()) {
103
0
            return status;
104
0
        }
105
106
90
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
107
90
                                                          input_rows_count, config, adapter);
108
90
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
91
14
                        uint32_t result, size_t input_rows_count) const override {
92
14
        if (block.get_by_position(arguments[0]).column->only_null()) {
93
0
            block.get_by_position(result).column =
94
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
95
0
                                                                            Field());
96
0
            return Status::OK();
97
0
        }
98
99
14
        TAIResource config;
100
14
        std::shared_ptr<AIAdapter> adapter;
101
14
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
102
14
            !status.ok()) {
103
0
            return status;
104
0
        }
105
106
14
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
107
14
                                                          input_rows_count, config, adapter);
108
14
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
91
47
                        uint32_t result, size_t input_rows_count) const override {
92
47
        if (block.get_by_position(arguments[0]).column->only_null()) {
93
0
            block.get_by_position(result).column =
94
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
95
0
                                                                            Field());
96
0
            return Status::OK();
97
0
        }
98
99
47
        TAIResource config;
100
47
        std::shared_ptr<AIAdapter> adapter;
101
47
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
102
47
            !status.ok()) {
103
0
            return status;
104
0
        }
105
106
47
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
107
47
                                                          input_rows_count, config, adapter);
108
47
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
91
2
                        uint32_t result, size_t input_rows_count) const override {
92
2
        if (block.get_by_position(arguments[0]).column->only_null()) {
93
0
            block.get_by_position(result).column =
94
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
95
0
                                                                            Field());
96
0
            return Status::OK();
97
0
        }
98
99
2
        TAIResource config;
100
2
        std::shared_ptr<AIAdapter> adapter;
101
2
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
102
2
            !status.ok()) {
103
0
            return status;
104
0
        }
105
106
2
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
107
2
                                                          input_rows_count, config, adapter);
108
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
91
2
                        uint32_t result, size_t input_rows_count) const override {
92
2
        if (block.get_by_position(arguments[0]).column->only_null()) {
93
0
            block.get_by_position(result).column =
94
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
95
0
                                                                            Field());
96
0
            return Status::OK();
97
0
        }
98
99
2
        TAIResource config;
100
2
        std::shared_ptr<AIAdapter> adapter;
101
2
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
102
2
            !status.ok()) {
103
0
            return status;
104
0
        }
105
106
2
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
107
2
                                                          input_rows_count, config, adapter);
108
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
91
4
                        uint32_t result, size_t input_rows_count) const override {
92
4
        if (block.get_by_position(arguments[0]).column->only_null()) {
93
1
            block.get_by_position(result).column =
94
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
95
1
                                                                            Field());
96
1
            return Status::OK();
97
1
        }
98
99
3
        TAIResource config;
100
3
        std::shared_ptr<AIAdapter> adapter;
101
3
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
102
3
            !status.ok()) {
103
0
            return status;
104
0
        }
105
106
3
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
107
3
                                                          input_rows_count, config, adapter);
108
3
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
91
22
                        uint32_t result, size_t input_rows_count) const override {
92
22
        if (block.get_by_position(arguments[0]).column->only_null()) {
93
0
            block.get_by_position(result).column =
94
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
95
0
                                                                            Field());
96
0
            return Status::OK();
97
0
        }
98
99
22
        TAIResource config;
100
22
        std::shared_ptr<AIAdapter> adapter;
101
22
        if (Status status = this->_init_from_resource(context, block, arguments, config, adapter);
102
22
            !status.ok()) {
103
0
            return status;
104
0
        }
105
106
22
        return assert_cast<const Derived&>(*this).execute(context, block, arguments, result,
107
22
                                                          input_rows_count, config, adapter);
108
22
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
109
110
protected:
111
    // Reads the shared AI context window size from query options. String AI batch functions and
112
    // ai_agg both use the same byte-based session variable so batching behavior stays consistent.
113
80
    static int64_t get_ai_context_window_size(FunctionContext* context) {
114
80
        DORIS_CHECK(context != nullptr);
115
80
        QueryContext* query_ctx = context->state()->get_query_ctx();
116
80
        DORIS_CHECK(query_ctx != nullptr);
117
118
80
        return query_ctx->query_options().ai_context_window_size;
119
80
    }
_ZN5doris10AIFunctionINS_13FunctionEmbedEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
113
5
    static int64_t get_ai_context_window_size(FunctionContext* context) {
114
5
        DORIS_CHECK(context != nullptr);
115
5
        QueryContext* query_ctx = context->state()->get_query_ctx();
116
5
        DORIS_CHECK(query_ctx != nullptr);
117
118
5
        return query_ctx->query_options().ai_context_window_size;
119
5
    }
_ZN5doris10AIFunctionINS_16FunctionAIFilterEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
113
47
    static int64_t get_ai_context_window_size(FunctionContext* context) {
114
47
        DORIS_CHECK(context != nullptr);
115
47
        QueryContext* query_ctx = context->state()->get_query_ctx();
116
47
        DORIS_CHECK(query_ctx != nullptr);
117
118
47
        return query_ctx->query_options().ai_context_window_size;
119
47
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_20FunctionAIFixGrammarEE26get_ai_context_window_sizeEPNS_15FunctionContextE
_ZN5doris10AIFunctionINS_19FunctionAISentimentEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
113
2
    static int64_t get_ai_context_window_size(FunctionContext* context) {
114
2
        DORIS_CHECK(context != nullptr);
115
2
        QueryContext* query_ctx = context->state()->get_query_ctx();
116
2
        DORIS_CHECK(query_ctx != nullptr);
117
118
2
        return query_ctx->query_options().ai_context_window_size;
119
2
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAISummarizeEE26get_ai_context_window_sizeEPNS_15FunctionContextE
_ZN5doris10AIFunctionINS_18FunctionAIClassifyEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
113
2
    static int64_t get_ai_context_window_size(FunctionContext* context) {
114
2
        DORIS_CHECK(context != nullptr);
115
2
        QueryContext* query_ctx = context->state()->get_query_ctx();
116
2
        DORIS_CHECK(query_ctx != nullptr);
117
118
2
        return query_ctx->query_options().ai_context_window_size;
119
2
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_17FunctionAIExtractEE26get_ai_context_window_sizeEPNS_15FunctionContextE
_ZN5doris10AIFunctionINS_18FunctionAIGenerateEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
113
2
    static int64_t get_ai_context_window_size(FunctionContext* context) {
114
2
        DORIS_CHECK(context != nullptr);
115
2
        QueryContext* query_ctx = context->state()->get_query_ctx();
116
2
        DORIS_CHECK(query_ctx != nullptr);
117
118
2
        return query_ctx->query_options().ai_context_window_size;
119
2
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_14FunctionAIMaskEE26get_ai_context_window_sizeEPNS_15FunctionContextE
_ZN5doris10AIFunctionINS_20FunctionAISimilarityEE26get_ai_context_window_sizeEPNS_15FunctionContextE
Line
Count
Source
113
22
    static int64_t get_ai_context_window_size(FunctionContext* context) {
114
22
        DORIS_CHECK(context != nullptr);
115
22
        QueryContext* query_ctx = context->state()->get_query_ctx();
116
22
        DORIS_CHECK(query_ctx != nullptr);
117
118
22
        return query_ctx->query_options().ai_context_window_size;
119
22
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAITranslateEE26get_ai_context_window_sizeEPNS_15FunctionContextE
120
121
6
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20create_result_columnEv
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE20create_result_columnEv
Line
Count
Source
121
2
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20create_result_columnEv
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20create_result_columnEv
Line
Count
Source
121
2
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE20create_result_columnEv
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20create_result_columnEv
Line
Count
Source
121
2
    MutableColumnPtr create_result_column() const { return ColumnString::create(); }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE20create_result_columnEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE20create_result_columnEv
122
123
    // Provider-reusable hook for AI functions(string) -> string.
124
    Status append_batch_results(const std::vector<std::string>& batch_results,
125
6
                                IColumn& col_result) const {
126
6
        auto& string_col = assert_cast<ColumnString&>(col_result);
127
11
        for (const auto& batch_result : batch_results) {
128
11
            string_col.insert_data(batch_result.data(), batch_result.size());
129
11
        }
130
6
        return Status::OK();
131
6
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Line
Count
Source
125
2
                                IColumn& col_result) const {
126
2
        auto& string_col = assert_cast<ColumnString&>(col_result);
127
4
        for (const auto& batch_result : batch_results) {
128
4
            string_col.insert_data(batch_result.data(), batch_result.size());
129
4
        }
130
2
        return Status::OK();
131
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Line
Count
Source
125
2
                                IColumn& col_result) const {
126
2
        auto& string_col = assert_cast<ColumnString&>(col_result);
127
2
        for (const auto& batch_result : batch_results) {
128
2
            string_col.insert_data(batch_result.data(), batch_result.size());
129
2
        }
130
2
        return Status::OK();
131
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Line
Count
Source
125
2
                                IColumn& col_result) const {
126
2
        auto& string_col = assert_cast<ColumnString&>(col_result);
127
5
        for (const auto& batch_result : batch_results) {
128
5
            string_col.insert_data(batch_result.data(), batch_result.size());
129
5
        }
130
2
        return Status::OK();
131
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE20append_batch_resultsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERNS_7IColumnE
132
133
97
    static void normalize_endpoint(TAIResource& config) {
134
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
135
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
136
        //    for other AI scalar functions.
137
        // 2. `:embedContent` -> `:batchEmbedContents`
138
97
        if (iequal(config.provider_type, "GEMINI")) {
139
4
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
140
1
                static constexpr std::string_view legacy_suffix = ":embedContent";
141
1
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
142
1
                                        legacy_suffix.size(), ":batchEmbedContents");
143
1
                return;
144
1
            }
145
146
3
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
147
1
                return;
148
1
            }
149
150
2
            std::string model_name = config.model_name;
151
2
            if (!model_name.starts_with("models/")) {
152
2
                model_name = "models/" + model_name;
153
2
            }
154
155
2
            config.endpoint += "/";
156
2
            config.endpoint += model_name;
157
2
            config.endpoint +=
158
2
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
159
2
            return;
160
3
        }
161
162
        // The endpoint `v1/completions` does not support `system_prompt`.
163
        // To ensure a clear structure and stable AI results.
164
        // Convert from `v1/completions` to `v1/chat/completions`
165
93
        if (config.endpoint.ends_with("v1/completions")) {
166
1
            static constexpr std::string_view legacy_suffix = "v1/completions";
167
1
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
168
1
                                    legacy_suffix.size(), "v1/chat/completions");
169
1
        }
170
93
    }
_ZN5doris10AIFunctionINS_13FunctionEmbedEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
133
16
    static void normalize_endpoint(TAIResource& config) {
134
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
135
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
136
        //    for other AI scalar functions.
137
        // 2. `:embedContent` -> `:batchEmbedContents`
138
16
        if (iequal(config.provider_type, "GEMINI")) {
139
2
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
140
1
                static constexpr std::string_view legacy_suffix = ":embedContent";
141
1
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
142
1
                                        legacy_suffix.size(), ":batchEmbedContents");
143
1
                return;
144
1
            }
145
146
1
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
147
0
                return;
148
0
            }
149
150
1
            std::string model_name = config.model_name;
151
1
            if (!model_name.starts_with("models/")) {
152
1
                model_name = "models/" + model_name;
153
1
            }
154
155
1
            config.endpoint += "/";
156
1
            config.endpoint += model_name;
157
1
            config.endpoint +=
158
1
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
159
1
            return;
160
1
        }
161
162
        // The endpoint `v1/completions` does not support `system_prompt`.
163
        // To ensure a clear structure and stable AI results.
164
        // Convert from `v1/completions` to `v1/chat/completions`
165
14
        if (config.endpoint.ends_with("v1/completions")) {
166
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
167
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
168
0
                                    legacy_suffix.size(), "v1/chat/completions");
169
0
        }
170
14
    }
_ZN5doris10AIFunctionINS_16FunctionAIFilterEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
133
47
    static void normalize_endpoint(TAIResource& config) {
134
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
135
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
136
        //    for other AI scalar functions.
137
        // 2. `:embedContent` -> `:batchEmbedContents`
138
47
        if (iequal(config.provider_type, "GEMINI")) {
139
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
140
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
141
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
142
0
                                        legacy_suffix.size(), ":batchEmbedContents");
143
0
                return;
144
0
            }
145
146
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
147
0
                return;
148
0
            }
149
150
0
            std::string model_name = config.model_name;
151
0
            if (!model_name.starts_with("models/")) {
152
0
                model_name = "models/" + model_name;
153
0
            }
154
155
0
            config.endpoint += "/";
156
0
            config.endpoint += model_name;
157
0
            config.endpoint +=
158
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
159
0
            return;
160
0
        }
161
162
        // The endpoint `v1/completions` does not support `system_prompt`.
163
        // To ensure a clear structure and stable AI results.
164
        // Convert from `v1/completions` to `v1/chat/completions`
165
47
        if (config.endpoint.ends_with("v1/completions")) {
166
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
167
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
168
0
                                    legacy_suffix.size(), "v1/chat/completions");
169
0
        }
170
47
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_20FunctionAIFixGrammarEE18normalize_endpointERNS_11TAIResourceE
_ZN5doris10AIFunctionINS_19FunctionAISentimentEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
133
7
    static void normalize_endpoint(TAIResource& config) {
134
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
135
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
136
        //    for other AI scalar functions.
137
        // 2. `:embedContent` -> `:batchEmbedContents`
138
7
        if (iequal(config.provider_type, "GEMINI")) {
139
2
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
140
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
141
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
142
0
                                        legacy_suffix.size(), ":batchEmbedContents");
143
0
                return;
144
0
            }
145
146
2
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
147
1
                return;
148
1
            }
149
150
1
            std::string model_name = config.model_name;
151
1
            if (!model_name.starts_with("models/")) {
152
1
                model_name = "models/" + model_name;
153
1
            }
154
155
1
            config.endpoint += "/";
156
1
            config.endpoint += model_name;
157
1
            config.endpoint +=
158
1
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
159
1
            return;
160
2
        }
161
162
        // The endpoint `v1/completions` does not support `system_prompt`.
163
        // To ensure a clear structure and stable AI results.
164
        // Convert from `v1/completions` to `v1/chat/completions`
165
5
        if (config.endpoint.ends_with("v1/completions")) {
166
1
            static constexpr std::string_view legacy_suffix = "v1/completions";
167
1
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
168
1
                                    legacy_suffix.size(), "v1/chat/completions");
169
1
        }
170
5
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAISummarizeEE18normalize_endpointERNS_11TAIResourceE
_ZN5doris10AIFunctionINS_18FunctionAIClassifyEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
133
2
    static void normalize_endpoint(TAIResource& config) {
134
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
135
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
136
        //    for other AI scalar functions.
137
        // 2. `:embedContent` -> `:batchEmbedContents`
138
2
        if (iequal(config.provider_type, "GEMINI")) {
139
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
140
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
141
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
142
0
                                        legacy_suffix.size(), ":batchEmbedContents");
143
0
                return;
144
0
            }
145
146
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
147
0
                return;
148
0
            }
149
150
0
            std::string model_name = config.model_name;
151
0
            if (!model_name.starts_with("models/")) {
152
0
                model_name = "models/" + model_name;
153
0
            }
154
155
0
            config.endpoint += "/";
156
0
            config.endpoint += model_name;
157
0
            config.endpoint +=
158
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
159
0
            return;
160
0
        }
161
162
        // The endpoint `v1/completions` does not support `system_prompt`.
163
        // To ensure a clear structure and stable AI results.
164
        // Convert from `v1/completions` to `v1/chat/completions`
165
2
        if (config.endpoint.ends_with("v1/completions")) {
166
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
167
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
168
0
                                    legacy_suffix.size(), "v1/chat/completions");
169
0
        }
170
2
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_17FunctionAIExtractEE18normalize_endpointERNS_11TAIResourceE
_ZN5doris10AIFunctionINS_18FunctionAIGenerateEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
133
3
    static void normalize_endpoint(TAIResource& config) {
134
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
135
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
136
        //    for other AI scalar functions.
137
        // 2. `:embedContent` -> `:batchEmbedContents`
138
3
        if (iequal(config.provider_type, "GEMINI")) {
139
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
140
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
141
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
142
0
                                        legacy_suffix.size(), ":batchEmbedContents");
143
0
                return;
144
0
            }
145
146
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
147
0
                return;
148
0
            }
149
150
0
            std::string model_name = config.model_name;
151
0
            if (!model_name.starts_with("models/")) {
152
0
                model_name = "models/" + model_name;
153
0
            }
154
155
0
            config.endpoint += "/";
156
0
            config.endpoint += model_name;
157
0
            config.endpoint +=
158
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
159
0
            return;
160
0
        }
161
162
        // The endpoint `v1/completions` does not support `system_prompt`.
163
        // To ensure a clear structure and stable AI results.
164
        // Convert from `v1/completions` to `v1/chat/completions`
165
3
        if (config.endpoint.ends_with("v1/completions")) {
166
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
167
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
168
0
                                    legacy_suffix.size(), "v1/chat/completions");
169
0
        }
170
3
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_14FunctionAIMaskEE18normalize_endpointERNS_11TAIResourceE
_ZN5doris10AIFunctionINS_20FunctionAISimilarityEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
133
22
    static void normalize_endpoint(TAIResource& config) {
134
        // 1. If users configure only the version root like `.../v1` or `.../v1beta`, append
135
        //    `models/<model>:batchEmbedContents` for `embed`, and `models/<model>:generateContent`
136
        //    for other AI scalar functions.
137
        // 2. `:embedContent` -> `:batchEmbedContents`
138
22
        if (iequal(config.provider_type, "GEMINI")) {
139
0
            if (iequal(Derived::name, "embed") && config.endpoint.ends_with(":embedContent")) {
140
0
                static constexpr std::string_view legacy_suffix = ":embedContent";
141
0
                config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
142
0
                                        legacy_suffix.size(), ":batchEmbedContents");
143
0
                return;
144
0
            }
145
146
0
            if (!config.endpoint.ends_with("v1") && !config.endpoint.ends_with("v1beta")) {
147
0
                return;
148
0
            }
149
150
0
            std::string model_name = config.model_name;
151
0
            if (!model_name.starts_with("models/")) {
152
0
                model_name = "models/" + model_name;
153
0
            }
154
155
0
            config.endpoint += "/";
156
0
            config.endpoint += model_name;
157
0
            config.endpoint +=
158
0
                    iequal(Derived::name, "embed") ? ":batchEmbedContents" : ":generateContent";
159
0
            return;
160
0
        }
161
162
        // The endpoint `v1/completions` does not support `system_prompt`.
163
        // To ensure a clear structure and stable AI results.
164
        // Convert from `v1/completions` to `v1/chat/completions`
165
22
        if (config.endpoint.ends_with("v1/completions")) {
166
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
167
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
168
0
                                    legacy_suffix.size(), "v1/chat/completions");
169
0
        }
170
22
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAITranslateEE18normalize_endpointERNS_11TAIResourceE
171
172
    // Executes one HTTP POST request and validates transport-level success.
173
    Status do_send_request(HttpClient* client, const std::string& request_body,
174
                           std::string& response, const TAIResource& config,
175
3
                           std::shared_ptr<AIAdapter>& adapter, FunctionContext* context) const {
176
3
        RETURN_IF_ERROR(client->init(config.endpoint, false));
177
178
3
        QueryContext* query_ctx = context->state()->get_query_ctx();
179
3
        int64_t remaining_query_time = query_ctx->get_remaining_query_time_seconds();
180
3
        if (remaining_query_time <= 0) {
181
0
            return Status::TimedOut("Query timeout exceeded before AI request");
182
0
        }
183
184
3
        client->set_timeout_ms(remaining_query_time * 1000);
185
186
3
        if (!config.api_key.empty()) {
187
3
            RETURN_IF_ERROR(adapter->set_authentication(client));
188
3
        }
189
190
3
        Status st = client->execute_post_request(request_body, &response);
191
3
        long http_status = client->get_http_status();
192
193
3
        if (!st.ok()) {
194
1
            LOG(INFO) << "AI HTTP request failed before status validation, provider="
195
1
                      << config.provider_type << ", model=" << config.model_name
196
1
                      << ", endpoint=" << mask_token(config.endpoint)
197
1
                      << ", exec_status=" << st.to_string() << ", response_body=" << response;
198
1
            return st;
199
1
        }
200
2
        if (http_status != 200) {
201
1
            return Status::HttpError(
202
1
                    "http status code is not 200, code={}, url={}, response_body={}", http_status,
203
1
                    mask_token(config.endpoint), response);
204
1
        }
205
1
        return Status::OK();
206
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
175
3
                           std::shared_ptr<AIAdapter>& adapter, FunctionContext* context) const {
176
3
        RETURN_IF_ERROR(client->init(config.endpoint, false));
177
178
3
        QueryContext* query_ctx = context->state()->get_query_ctx();
179
3
        int64_t remaining_query_time = query_ctx->get_remaining_query_time_seconds();
180
3
        if (remaining_query_time <= 0) {
181
0
            return Status::TimedOut("Query timeout exceeded before AI request");
182
0
        }
183
184
3
        client->set_timeout_ms(remaining_query_time * 1000);
185
186
3
        if (!config.api_key.empty()) {
187
3
            RETURN_IF_ERROR(adapter->set_authentication(client));
188
3
        }
189
190
3
        Status st = client->execute_post_request(request_body, &response);
191
3
        long http_status = client->get_http_status();
192
193
3
        if (!st.ok()) {
194
1
            LOG(INFO) << "AI HTTP request failed before status validation, provider="
195
1
                      << config.provider_type << ", model=" << config.model_name
196
1
                      << ", endpoint=" << mask_token(config.endpoint)
197
1
                      << ", exec_status=" << st.to_string() << ", response_body=" << response;
198
1
            return st;
199
1
        }
200
2
        if (http_status != 200) {
201
1
            return Status::HttpError(
202
1
                    "http status code is not 200, code={}, url={}, response_body={}", http_status,
203
1
                    mask_token(config.endpoint), response);
204
1
        }
205
1
        return Status::OK();
206
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
207
208
    // Sends the request with retry mechanism for handling transient failures
209
    Status send_request_to_llm(const std::string& request_body, std::string& response,
210
                               const TAIResource& config, std::shared_ptr<AIAdapter>& adapter,
211
0
                               FunctionContext* context) const {
212
0
        return HttpClient::execute_with_retry(config.max_retries, config.retry_delay_second,
213
0
                                              [this, &request_body, &response, &config, &adapter,
214
0
                                               context](HttpClient* client) -> Status {
215
0
                                                  return this->do_send_request(client, request_body,
216
0
                                                                               response, config,
217
0
                                                                               adapter, context);
218
0
                                              });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_13FunctionEmbedEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_16FunctionAIFilterEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAISentimentEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_17FunctionAIExtractEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_14FunctionAIMaskEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAITranslateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
219
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
220
221
    // Provider-reusable helper for string-returning functions.
222
    // Estimates one batch entry size using the raw prompt length plus the fixed JSON wrapper cost.
223
100
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
224
100
        static constexpr size_t json_wrapper_size = 20;
225
100
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
226
100
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
223
64
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
224
64
        static constexpr size_t json_wrapper_size = 20;
225
64
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
226
64
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
223
4
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
224
4
        static constexpr size_t json_wrapper_size = 20;
225
4
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
226
4
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
223
2
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
224
2
        static constexpr size_t json_wrapper_size = 20;
225
2
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
226
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
223
5
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
224
5
        static constexpr size_t json_wrapper_size = 20;
225
5
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
226
5
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
223
25
    size_t estimate_batch_entry_size(size_t idx, const std::string& prompt) const {
224
25
        static constexpr size_t json_wrapper_size = 20;
225
25
        return prompt.size() + std::to_string(idx).size() + json_wrapper_size;
226
25
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE25estimate_batch_entry_sizeEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
227
228
    // Provider-reusable helper for string-returning functions.
229
    // Executes one batch request and parses the provider result into one string per input row.
230
    Status execute_batch_request(const std::vector<std::string>& batch_prompts,
231
                                 std::vector<std::string>& results, const TAIResource& config,
232
                                 std::shared_ptr<AIAdapter>& adapter,
233
0
                                 FunctionContext* context) const {
234
#ifdef BE_TEST
235
        const char* test_result = std::getenv("AI_TEST_RESULT");
236
        if (test_result != nullptr) {
237
            std::vector<std::string> parsed_test_response;
238
            RETURN_IF_ERROR(
239
                    adapter->parse_response(std::string(test_result), parsed_test_response));
240
            if (parsed_test_response.empty()) {
241
                return Status::InternalError("AI returned empty result");
242
            }
243
            if (parsed_test_response.size() != batch_prompts.size()) {
244
                return Status::RuntimeError(
245
                        "Failed to parse {} batch result, expected {} items but got {}", get_name(),
246
                        batch_prompts.size(), parsed_test_response.size());
247
            }
248
            results = std::move(parsed_test_response);
249
            return Status::OK();
250
        }
251
        if (config.provider_type == "MOCK") {
252
            results.clear();
253
            results.reserve(batch_prompts.size());
254
            for (const auto& prompt : batch_prompts) {
255
                results.emplace_back("this is a mock response. " + prompt);
256
            }
257
            return Status::OK();
258
        }
259
#endif
260
261
0
        std::string batch_prompt;
262
0
        RETURN_IF_ERROR(build_batch_prompt(batch_prompts, batch_prompt));
263
264
0
        std::vector<std::string> inputs = {batch_prompt};
265
0
        std::vector<std::string> parsed_response;
266
267
0
        std::string request_body;
268
0
        RETURN_IF_ERROR(adapter->build_request_payload(
269
0
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
270
271
0
        std::string response;
272
0
        RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
273
0
        RETURN_IF_ERROR(adapter->parse_response(response, parsed_response));
274
0
        if (parsed_response.empty()) {
275
0
            return Status::InternalError("AI returned empty result");
276
0
        }
277
0
        if (parsed_response.size() != batch_prompts.size()) {
278
0
            LOG(WARNING) << "AI batch result size mismatch, function=" << get_name()
279
0
                         << ", provider=" << config.provider_type << ", model=" << config.model_name
280
0
                         << ", expected_rows=" << batch_prompts.size()
281
0
                         << ", actual_rows=" << parsed_response.size()
282
0
                         << ", response_body=" << response;
283
0
            return Status::RuntimeError(
284
0
                    "Failed to parse {} batch result, expected {} items but got {}", get_name(),
285
0
                    batch_prompts.size(), parsed_response.size());
286
0
        }
287
0
        results = std::move(parsed_response);
288
0
        return Status::OK();
289
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE21execute_batch_requestERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERSB_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
290
291
    // Provider-reusable helper for string-returning functions.
292
    // Runs the common batch execution flow; derived classes only need to define how one batch of
293
    // string results is inserted into the final output column.
294
    Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
295
                   uint32_t result, size_t input_rows_count, const TAIResource& config,
296
76
                   std::shared_ptr<AIAdapter>& adapter) const {
297
76
        Columns prompt_columns;
298
76
        prompt_columns.reserve(arguments.size() - 1);
299
76
        ColumnUInt8::MutablePtr result_null_map;
300
176
        for (size_t i = 1; i < arguments.size(); ++i) {
301
100
            const auto& argument = block.get_by_position(arguments[i]);
302
100
            if (argument.type->is_nullable()) {
303
7
                const auto& [column, is_const] = unpack_if_const(argument.column);
304
7
                const auto& nullable =
305
7
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
306
7
                if (!result_null_map) {
307
6
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
308
6
                }
309
7
                VectorizedUtils::update_null_map(result_null_map->get_data(),
310
7
                                                 nullable.get_null_map_data(), is_const);
311
7
            }
312
100
            prompt_columns.emplace_back(
313
100
                    argument.unnest_nullable(argument.type->is_nullable()
314
100
                                                     ? argument.get_nullable_column_info()
315
100
                                                     : NullableColumnInfo {},
316
100
                                             false)
317
100
                            .column);
318
100
        }
319
320
76
        if (result_null_map &&
321
76
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
322
1
            block.get_by_position(result).column =
323
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
324
1
                                                                            Field());
325
1
            return Status::OK();
326
1
        }
327
328
75
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
329
75
        std::vector<std::string> batch_prompts;
330
75
        size_t current_batch_size = 2; // []
331
75
        const size_t max_batch_prompt_size =
332
75
                static_cast<size_t>(get_ai_context_window_size(context));
333
75
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
334
335
184
        for (size_t i = 0; i < input_rows_count; ++i) {
336
109
            if (null_map && (*null_map)[i]) {
337
9
                continue;
338
9
            }
339
340
100
            std::string prompt;
341
100
            RETURN_IF_ERROR(
342
100
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
343
344
100
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
345
100
            if (entry_size > max_batch_prompt_size) {
346
4
                if (!batch_prompts.empty()) {
347
1
                    std::vector<std::string> batch_results;
348
1
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
349
1
                                                                config, adapter, context));
350
1
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
351
1
                            batch_results, *col_result));
352
1
                    batch_prompts.clear();
353
1
                    current_batch_size = 2;
354
1
                }
355
356
4
                std::vector<std::string> single_prompts;
357
4
                single_prompts.emplace_back(std::move(prompt));
358
4
                std::vector<std::string> single_results;
359
4
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
360
4
                                                            adapter, context));
361
4
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
362
4
                        single_results, *col_result));
363
4
                continue;
364
4
            }
365
366
96
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
367
96
            if (!batch_prompts.empty() &&
368
96
                current_batch_size + additional_size > max_batch_prompt_size) {
369
2
                std::vector<std::string> batch_results;
370
2
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
371
2
                                                            adapter, context));
372
2
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
373
2
                        batch_results, *col_result));
374
2
                batch_prompts.clear();
375
2
                current_batch_size = 2;
376
2
                additional_size = entry_size;
377
2
            }
378
379
96
            batch_prompts.emplace_back(std::move(prompt));
380
96
            current_batch_size += additional_size;
381
96
        }
382
383
75
        if (!batch_prompts.empty()) {
384
72
            std::vector<std::string> batch_results;
385
72
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
386
72
                                                        adapter, context));
387
66
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
388
66
                                                                                    *col_result));
389
66
        }
390
391
42
        if (!result_null_map) {
392
37
            block.replace_by_position(result, std::move(col_result));
393
37
            return Status::OK();
394
37
        }
395
396
5
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
397
1
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
398
1
                                                                     std::move(result_null_map)));
399
1
            return Status::OK();
400
1
        }
401
402
4
        auto nested_result = col_result->clone_empty();
403
4
        size_t result_row = 0;
404
16
        for (UInt8 is_null : result_null_map->get_data()) {
405
16
            if (is_null) {
406
9
                nested_result->insert_default();
407
9
            } else {
408
7
                nested_result->insert_from(*col_result, result_row++);
409
7
            }
410
16
        }
411
412
4
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
413
4
                                                                 std::move(result_null_map)));
414
4
        return Status::OK();
415
5
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
296
47
                   std::shared_ptr<AIAdapter>& adapter) const {
297
47
        Columns prompt_columns;
298
47
        prompt_columns.reserve(arguments.size() - 1);
299
47
        ColumnUInt8::MutablePtr result_null_map;
300
94
        for (size_t i = 1; i < arguments.size(); ++i) {
301
47
            const auto& argument = block.get_by_position(arguments[i]);
302
47
            if (argument.type->is_nullable()) {
303
1
                const auto& [column, is_const] = unpack_if_const(argument.column);
304
1
                const auto& nullable =
305
1
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
306
1
                if (!result_null_map) {
307
1
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
308
1
                }
309
1
                VectorizedUtils::update_null_map(result_null_map->get_data(),
310
1
                                                 nullable.get_null_map_data(), is_const);
311
1
            }
312
47
            prompt_columns.emplace_back(
313
47
                    argument.unnest_nullable(argument.type->is_nullable()
314
47
                                                     ? argument.get_nullable_column_info()
315
47
                                                     : NullableColumnInfo {},
316
47
                                             false)
317
47
                            .column);
318
47
        }
319
320
47
        if (result_null_map &&
321
47
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
322
0
            block.get_by_position(result).column =
323
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
324
0
                                                                            Field());
325
0
            return Status::OK();
326
0
        }
327
328
47
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
329
47
        std::vector<std::string> batch_prompts;
330
47
        size_t current_batch_size = 2; // []
331
47
        const size_t max_batch_prompt_size =
332
47
                static_cast<size_t>(get_ai_context_window_size(context));
333
47
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
334
335
113
        for (size_t i = 0; i < input_rows_count; ++i) {
336
66
            if (null_map && (*null_map)[i]) {
337
2
                continue;
338
2
            }
339
340
64
            std::string prompt;
341
64
            RETURN_IF_ERROR(
342
64
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
343
344
64
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
345
64
            if (entry_size > max_batch_prompt_size) {
346
4
                if (!batch_prompts.empty()) {
347
1
                    std::vector<std::string> batch_results;
348
1
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
349
1
                                                                config, adapter, context));
350
1
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
351
1
                            batch_results, *col_result));
352
1
                    batch_prompts.clear();
353
1
                    current_batch_size = 2;
354
1
                }
355
356
4
                std::vector<std::string> single_prompts;
357
4
                single_prompts.emplace_back(std::move(prompt));
358
4
                std::vector<std::string> single_results;
359
4
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
360
4
                                                            adapter, context));
361
4
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
362
4
                        single_results, *col_result));
363
4
                continue;
364
4
            }
365
366
60
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
367
60
            if (!batch_prompts.empty() &&
368
60
                current_batch_size + additional_size > max_batch_prompt_size) {
369
2
                std::vector<std::string> batch_results;
370
2
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
371
2
                                                            adapter, context));
372
2
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
373
2
                        batch_results, *col_result));
374
2
                batch_prompts.clear();
375
2
                current_batch_size = 2;
376
2
                additional_size = entry_size;
377
2
            }
378
379
60
            batch_prompts.emplace_back(std::move(prompt));
380
60
            current_batch_size += additional_size;
381
60
        }
382
383
47
        if (!batch_prompts.empty()) {
384
44
            std::vector<std::string> batch_results;
385
44
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
386
44
                                                        adapter, context));
387
38
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
388
38
                                                                                    *col_result));
389
38
        }
390
391
20
        if (!result_null_map) {
392
19
            block.replace_by_position(result, std::move(col_result));
393
19
            return Status::OK();
394
19
        }
395
396
1
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
397
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
398
0
                                                                     std::move(result_null_map)));
399
0
            return Status::OK();
400
0
        }
401
402
1
        auto nested_result = col_result->clone_empty();
403
1
        size_t result_row = 0;
404
4
        for (UInt8 is_null : result_null_map->get_data()) {
405
4
            if (is_null) {
406
2
                nested_result->insert_default();
407
2
            } else {
408
2
                nested_result->insert_from(*col_result, result_row++);
409
2
            }
410
4
        }
411
412
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
413
1
                                                                 std::move(result_null_map)));
414
1
        return Status::OK();
415
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
296
2
                   std::shared_ptr<AIAdapter>& adapter) const {
297
2
        Columns prompt_columns;
298
2
        prompt_columns.reserve(arguments.size() - 1);
299
2
        ColumnUInt8::MutablePtr result_null_map;
300
4
        for (size_t i = 1; i < arguments.size(); ++i) {
301
2
            const auto& argument = block.get_by_position(arguments[i]);
302
2
            if (argument.type->is_nullable()) {
303
0
                const auto& [column, is_const] = unpack_if_const(argument.column);
304
0
                const auto& nullable =
305
0
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
306
0
                if (!result_null_map) {
307
0
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
308
0
                }
309
0
                VectorizedUtils::update_null_map(result_null_map->get_data(),
310
0
                                                 nullable.get_null_map_data(), is_const);
311
0
            }
312
2
            prompt_columns.emplace_back(
313
2
                    argument.unnest_nullable(argument.type->is_nullable()
314
2
                                                     ? argument.get_nullable_column_info()
315
2
                                                     : NullableColumnInfo {},
316
2
                                             false)
317
2
                            .column);
318
2
        }
319
320
2
        if (result_null_map &&
321
2
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
322
0
            block.get_by_position(result).column =
323
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
324
0
                                                                            Field());
325
0
            return Status::OK();
326
0
        }
327
328
2
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
329
2
        std::vector<std::string> batch_prompts;
330
2
        size_t current_batch_size = 2; // []
331
2
        const size_t max_batch_prompt_size =
332
2
                static_cast<size_t>(get_ai_context_window_size(context));
333
2
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
334
335
6
        for (size_t i = 0; i < input_rows_count; ++i) {
336
4
            if (null_map && (*null_map)[i]) {
337
0
                continue;
338
0
            }
339
340
4
            std::string prompt;
341
4
            RETURN_IF_ERROR(
342
4
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
343
344
4
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
345
4
            if (entry_size > max_batch_prompt_size) {
346
0
                if (!batch_prompts.empty()) {
347
0
                    std::vector<std::string> batch_results;
348
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
349
0
                                                                config, adapter, context));
350
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
351
0
                            batch_results, *col_result));
352
0
                    batch_prompts.clear();
353
0
                    current_batch_size = 2;
354
0
                }
355
356
0
                std::vector<std::string> single_prompts;
357
0
                single_prompts.emplace_back(std::move(prompt));
358
0
                std::vector<std::string> single_results;
359
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
360
0
                                                            adapter, context));
361
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
362
0
                        single_results, *col_result));
363
0
                continue;
364
0
            }
365
366
4
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
367
4
            if (!batch_prompts.empty() &&
368
4
                current_batch_size + additional_size > max_batch_prompt_size) {
369
0
                std::vector<std::string> batch_results;
370
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
371
0
                                                            adapter, context));
372
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
373
0
                        batch_results, *col_result));
374
0
                batch_prompts.clear();
375
0
                current_batch_size = 2;
376
0
                additional_size = entry_size;
377
0
            }
378
379
4
            batch_prompts.emplace_back(std::move(prompt));
380
4
            current_batch_size += additional_size;
381
4
        }
382
383
2
        if (!batch_prompts.empty()) {
384
2
            std::vector<std::string> batch_results;
385
2
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
386
2
                                                        adapter, context));
387
2
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
388
2
                                                                                    *col_result));
389
2
        }
390
391
2
        if (!result_null_map) {
392
2
            block.replace_by_position(result, std::move(col_result));
393
2
            return Status::OK();
394
2
        }
395
396
0
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
397
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
398
0
                                                                     std::move(result_null_map)));
399
0
            return Status::OK();
400
0
        }
401
402
0
        auto nested_result = col_result->clone_empty();
403
0
        size_t result_row = 0;
404
0
        for (UInt8 is_null : result_null_map->get_data()) {
405
0
            if (is_null) {
406
0
                nested_result->insert_default();
407
0
            } else {
408
0
                nested_result->insert_from(*col_result, result_row++);
409
0
            }
410
0
        }
411
412
0
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
413
0
                                                                 std::move(result_null_map)));
414
0
        return Status::OK();
415
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
296
2
                   std::shared_ptr<AIAdapter>& adapter) const {
297
2
        Columns prompt_columns;
298
2
        prompt_columns.reserve(arguments.size() - 1);
299
2
        ColumnUInt8::MutablePtr result_null_map;
300
6
        for (size_t i = 1; i < arguments.size(); ++i) {
301
4
            const auto& argument = block.get_by_position(arguments[i]);
302
4
            if (argument.type->is_nullable()) {
303
1
                const auto& [column, is_const] = unpack_if_const(argument.column);
304
1
                const auto& nullable =
305
1
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
306
1
                if (!result_null_map) {
307
1
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
308
1
                }
309
1
                VectorizedUtils::update_null_map(result_null_map->get_data(),
310
1
                                                 nullable.get_null_map_data(), is_const);
311
1
            }
312
4
            prompt_columns.emplace_back(
313
4
                    argument.unnest_nullable(argument.type->is_nullable()
314
4
                                                     ? argument.get_nullable_column_info()
315
4
                                                     : NullableColumnInfo {},
316
4
                                             false)
317
4
                            .column);
318
4
        }
319
320
2
        if (result_null_map &&
321
2
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
322
0
            block.get_by_position(result).column =
323
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
324
0
                                                                            Field());
325
0
            return Status::OK();
326
0
        }
327
328
2
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
329
2
        std::vector<std::string> batch_prompts;
330
2
        size_t current_batch_size = 2; // []
331
2
        const size_t max_batch_prompt_size =
332
2
                static_cast<size_t>(get_ai_context_window_size(context));
333
2
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
334
335
6
        for (size_t i = 0; i < input_rows_count; ++i) {
336
4
            if (null_map && (*null_map)[i]) {
337
2
                continue;
338
2
            }
339
340
2
            std::string prompt;
341
2
            RETURN_IF_ERROR(
342
2
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
343
344
2
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
345
2
            if (entry_size > max_batch_prompt_size) {
346
0
                if (!batch_prompts.empty()) {
347
0
                    std::vector<std::string> batch_results;
348
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
349
0
                                                                config, adapter, context));
350
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
351
0
                            batch_results, *col_result));
352
0
                    batch_prompts.clear();
353
0
                    current_batch_size = 2;
354
0
                }
355
356
0
                std::vector<std::string> single_prompts;
357
0
                single_prompts.emplace_back(std::move(prompt));
358
0
                std::vector<std::string> single_results;
359
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
360
0
                                                            adapter, context));
361
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
362
0
                        single_results, *col_result));
363
0
                continue;
364
0
            }
365
366
2
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
367
2
            if (!batch_prompts.empty() &&
368
2
                current_batch_size + additional_size > max_batch_prompt_size) {
369
0
                std::vector<std::string> batch_results;
370
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
371
0
                                                            adapter, context));
372
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
373
0
                        batch_results, *col_result));
374
0
                batch_prompts.clear();
375
0
                current_batch_size = 2;
376
0
                additional_size = entry_size;
377
0
            }
378
379
2
            batch_prompts.emplace_back(std::move(prompt));
380
2
            current_batch_size += additional_size;
381
2
        }
382
383
2
        if (!batch_prompts.empty()) {
384
2
            std::vector<std::string> batch_results;
385
2
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
386
2
                                                        adapter, context));
387
2
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
388
2
                                                                                    *col_result));
389
2
        }
390
391
2
        if (!result_null_map) {
392
1
            block.replace_by_position(result, std::move(col_result));
393
1
            return Status::OK();
394
1
        }
395
396
1
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
397
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
398
0
                                                                     std::move(result_null_map)));
399
0
            return Status::OK();
400
0
        }
401
402
1
        auto nested_result = col_result->clone_empty();
403
1
        size_t result_row = 0;
404
3
        for (UInt8 is_null : result_null_map->get_data()) {
405
3
            if (is_null) {
406
2
                nested_result->insert_default();
407
2
            } else {
408
1
                nested_result->insert_from(*col_result, result_row++);
409
1
            }
410
3
        }
411
412
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
413
1
                                                                 std::move(result_null_map)));
414
1
        return Status::OK();
415
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
296
3
                   std::shared_ptr<AIAdapter>& adapter) const {
297
3
        Columns prompt_columns;
298
3
        prompt_columns.reserve(arguments.size() - 1);
299
3
        ColumnUInt8::MutablePtr result_null_map;
300
6
        for (size_t i = 1; i < arguments.size(); ++i) {
301
3
            const auto& argument = block.get_by_position(arguments[i]);
302
3
            if (argument.type->is_nullable()) {
303
3
                const auto& [column, is_const] = unpack_if_const(argument.column);
304
3
                const auto& nullable =
305
3
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
306
3
                if (!result_null_map) {
307
3
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
308
3
                }
309
3
                VectorizedUtils::update_null_map(result_null_map->get_data(),
310
3
                                                 nullable.get_null_map_data(), is_const);
311
3
            }
312
3
            prompt_columns.emplace_back(
313
3
                    argument.unnest_nullable(argument.type->is_nullable()
314
3
                                                     ? argument.get_nullable_column_info()
315
3
                                                     : NullableColumnInfo {},
316
3
                                             false)
317
3
                            .column);
318
3
        }
319
320
3
        if (result_null_map &&
321
3
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
322
1
            block.get_by_position(result).column =
323
1
                    block.get_by_position(result).type->create_column_const(input_rows_count,
324
1
                                                                            Field());
325
1
            return Status::OK();
326
1
        }
327
328
2
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
329
2
        std::vector<std::string> batch_prompts;
330
2
        size_t current_batch_size = 2; // []
331
2
        const size_t max_batch_prompt_size =
332
2
                static_cast<size_t>(get_ai_context_window_size(context));
333
2
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
334
335
10
        for (size_t i = 0; i < input_rows_count; ++i) {
336
8
            if (null_map && (*null_map)[i]) {
337
3
                continue;
338
3
            }
339
340
5
            std::string prompt;
341
5
            RETURN_IF_ERROR(
342
5
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
343
344
5
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
345
5
            if (entry_size > max_batch_prompt_size) {
346
0
                if (!batch_prompts.empty()) {
347
0
                    std::vector<std::string> batch_results;
348
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
349
0
                                                                config, adapter, context));
350
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
351
0
                            batch_results, *col_result));
352
0
                    batch_prompts.clear();
353
0
                    current_batch_size = 2;
354
0
                }
355
356
0
                std::vector<std::string> single_prompts;
357
0
                single_prompts.emplace_back(std::move(prompt));
358
0
                std::vector<std::string> single_results;
359
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
360
0
                                                            adapter, context));
361
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
362
0
                        single_results, *col_result));
363
0
                continue;
364
0
            }
365
366
5
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
367
5
            if (!batch_prompts.empty() &&
368
5
                current_batch_size + additional_size > max_batch_prompt_size) {
369
0
                std::vector<std::string> batch_results;
370
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
371
0
                                                            adapter, context));
372
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
373
0
                        batch_results, *col_result));
374
0
                batch_prompts.clear();
375
0
                current_batch_size = 2;
376
0
                additional_size = entry_size;
377
0
            }
378
379
5
            batch_prompts.emplace_back(std::move(prompt));
380
5
            current_batch_size += additional_size;
381
5
        }
382
383
2
        if (!batch_prompts.empty()) {
384
2
            std::vector<std::string> batch_results;
385
2
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
386
2
                                                        adapter, context));
387
2
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
388
2
                                                                                    *col_result));
389
2
        }
390
391
2
        if (!result_null_map) {
392
0
            block.replace_by_position(result, std::move(col_result));
393
0
            return Status::OK();
394
0
        }
395
396
2
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
397
1
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
398
1
                                                                     std::move(result_null_map)));
399
1
            return Status::OK();
400
1
        }
401
402
1
        auto nested_result = col_result->clone_empty();
403
1
        size_t result_row = 0;
404
5
        for (UInt8 is_null : result_null_map->get_data()) {
405
5
            if (is_null) {
406
3
                nested_result->insert_default();
407
3
            } else {
408
2
                nested_result->insert_from(*col_result, result_row++);
409
2
            }
410
5
        }
411
412
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
413
1
                                                                 std::move(result_null_map)));
414
1
        return Status::OK();
415
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
296
22
                   std::shared_ptr<AIAdapter>& adapter) const {
297
22
        Columns prompt_columns;
298
22
        prompt_columns.reserve(arguments.size() - 1);
299
22
        ColumnUInt8::MutablePtr result_null_map;
300
66
        for (size_t i = 1; i < arguments.size(); ++i) {
301
44
            const auto& argument = block.get_by_position(arguments[i]);
302
44
            if (argument.type->is_nullable()) {
303
2
                const auto& [column, is_const] = unpack_if_const(argument.column);
304
2
                const auto& nullable =
305
2
                        assert_cast<const ColumnNullable&, TypeCheckOnRelease::DISABLE>(*column);
306
2
                if (!result_null_map) {
307
1
                    result_null_map = ColumnUInt8::create(input_rows_count, 0);
308
1
                }
309
2
                VectorizedUtils::update_null_map(result_null_map->get_data(),
310
2
                                                 nullable.get_null_map_data(), is_const);
311
2
            }
312
44
            prompt_columns.emplace_back(
313
44
                    argument.unnest_nullable(argument.type->is_nullable()
314
44
                                                     ? argument.get_nullable_column_info()
315
44
                                                     : NullableColumnInfo {},
316
44
                                             false)
317
44
                            .column);
318
44
        }
319
320
22
        if (result_null_map &&
321
22
            !simd::contain_zero(result_null_map->get_data().data(), input_rows_count)) {
322
0
            block.get_by_position(result).column =
323
0
                    block.get_by_position(result).type->create_column_const(input_rows_count,
324
0
                                                                            Field());
325
0
            return Status::OK();
326
0
        }
327
328
22
        auto col_result = assert_cast<const Derived&>(*this).create_result_column();
329
22
        std::vector<std::string> batch_prompts;
330
22
        size_t current_batch_size = 2; // []
331
22
        const size_t max_batch_prompt_size =
332
22
                static_cast<size_t>(get_ai_context_window_size(context));
333
22
        const NullMap* null_map = result_null_map ? &result_null_map->get_data() : nullptr;
334
335
49
        for (size_t i = 0; i < input_rows_count; ++i) {
336
27
            if (null_map && (*null_map)[i]) {
337
2
                continue;
338
2
            }
339
340
25
            std::string prompt;
341
25
            RETURN_IF_ERROR(
342
25
                    assert_cast<const Derived&>(*this).build_prompt(prompt_columns, i, prompt));
343
344
25
            size_t entry_size = estimate_batch_entry_size(batch_prompts.size(), prompt);
345
25
            if (entry_size > max_batch_prompt_size) {
346
0
                if (!batch_prompts.empty()) {
347
0
                    std::vector<std::string> batch_results;
348
0
                    RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results,
349
0
                                                                config, adapter, context));
350
0
                    RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
351
0
                            batch_results, *col_result));
352
0
                    batch_prompts.clear();
353
0
                    current_batch_size = 2;
354
0
                }
355
356
0
                std::vector<std::string> single_prompts;
357
0
                single_prompts.emplace_back(std::move(prompt));
358
0
                std::vector<std::string> single_results;
359
0
                RETURN_IF_ERROR(this->execute_batch_request(single_prompts, single_results, config,
360
0
                                                            adapter, context));
361
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
362
0
                        single_results, *col_result));
363
0
                continue;
364
0
            }
365
366
25
            size_t additional_size = entry_size + (batch_prompts.empty() ? 0 : 1);
367
25
            if (!batch_prompts.empty() &&
368
25
                current_batch_size + additional_size > max_batch_prompt_size) {
369
0
                std::vector<std::string> batch_results;
370
0
                RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
371
0
                                                            adapter, context));
372
0
                RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(
373
0
                        batch_results, *col_result));
374
0
                batch_prompts.clear();
375
0
                current_batch_size = 2;
376
0
                additional_size = entry_size;
377
0
            }
378
379
25
            batch_prompts.emplace_back(std::move(prompt));
380
25
            current_batch_size += additional_size;
381
25
        }
382
383
22
        if (!batch_prompts.empty()) {
384
22
            std::vector<std::string> batch_results;
385
22
            RETURN_IF_ERROR(this->execute_batch_request(batch_prompts, batch_results, config,
386
22
                                                        adapter, context));
387
22
            RETURN_IF_ERROR(assert_cast<const Derived&>(*this).append_batch_results(batch_results,
388
22
                                                                                    *col_result));
389
22
        }
390
391
16
        if (!result_null_map) {
392
15
            block.replace_by_position(result, std::move(col_result));
393
15
            return Status::OK();
394
15
        }
395
396
1
        if (!simd::contain_one(result_null_map->get_data().data(), input_rows_count)) {
397
0
            block.replace_by_position(result, ColumnNullable::create(std::move(col_result),
398
0
                                                                     std::move(result_null_map)));
399
0
            return Status::OK();
400
0
        }
401
402
1
        auto nested_result = col_result->clone_empty();
403
1
        size_t result_row = 0;
404
4
        for (UInt8 is_null : result_null_map->get_data()) {
405
4
            if (is_null) {
406
2
                nested_result->insert_default();
407
2
            } else {
408
2
                nested_result->insert_from(*col_result, result_row++);
409
2
            }
410
4
        }
411
412
1
        block.replace_by_position(result, ColumnNullable::create(std::move(nested_result),
413
1
                                                                 std::move(result_null_map)));
414
1
        return Status::OK();
415
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE7executeEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
416
417
private:
418
    // The ai resource must be literal
419
    Status _init_from_resource(FunctionContext* context, const Block& block,
420
                               const ColumnNumbers& arguments, TAIResource& config,
421
90
                               std::shared_ptr<AIAdapter>& adapter) const {
422
90
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
423
90
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
424
90
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
425
426
90
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
427
90
                context->state()->get_query_ctx()->get_ai_resources();
428
90
        DORIS_CHECK(ai_resources);
429
90
        auto it = ai_resources->find(resource_name);
430
90
        DORIS_CHECK(it != ai_resources->end());
431
90
        config = it->second;
432
433
90
        normalize_endpoint(config);
434
435
90
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
436
90
        DORIS_CHECK(adapter);
437
438
90
        adapter->init(config);
439
90
        return Status::OK();
440
90
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
421
14
                               std::shared_ptr<AIAdapter>& adapter) const {
422
14
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
423
14
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
424
14
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
425
426
14
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
427
14
                context->state()->get_query_ctx()->get_ai_resources();
428
14
        DORIS_CHECK(ai_resources);
429
14
        auto it = ai_resources->find(resource_name);
430
14
        DORIS_CHECK(it != ai_resources->end());
431
14
        config = it->second;
432
433
14
        normalize_endpoint(config);
434
435
14
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
436
14
        DORIS_CHECK(adapter);
437
438
14
        adapter->init(config);
439
14
        return Status::OK();
440
14
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
421
47
                               std::shared_ptr<AIAdapter>& adapter) const {
422
47
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
423
47
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
424
47
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
425
426
47
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
427
47
                context->state()->get_query_ctx()->get_ai_resources();
428
47
        DORIS_CHECK(ai_resources);
429
47
        auto it = ai_resources->find(resource_name);
430
47
        DORIS_CHECK(it != ai_resources->end());
431
47
        config = it->second;
432
433
47
        normalize_endpoint(config);
434
435
47
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
436
47
        DORIS_CHECK(adapter);
437
438
47
        adapter->init(config);
439
47
        return Status::OK();
440
47
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
421
2
                               std::shared_ptr<AIAdapter>& adapter) const {
422
2
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
423
2
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
424
2
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
425
426
2
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
427
2
                context->state()->get_query_ctx()->get_ai_resources();
428
2
        DORIS_CHECK(ai_resources);
429
2
        auto it = ai_resources->find(resource_name);
430
2
        DORIS_CHECK(it != ai_resources->end());
431
2
        config = it->second;
432
433
2
        normalize_endpoint(config);
434
435
2
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
436
2
        DORIS_CHECK(adapter);
437
438
2
        adapter->init(config);
439
2
        return Status::OK();
440
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
421
2
                               std::shared_ptr<AIAdapter>& adapter) const {
422
2
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
423
2
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
424
2
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
425
426
2
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
427
2
                context->state()->get_query_ctx()->get_ai_resources();
428
2
        DORIS_CHECK(ai_resources);
429
2
        auto it = ai_resources->find(resource_name);
430
2
        DORIS_CHECK(it != ai_resources->end());
431
2
        config = it->second;
432
433
2
        normalize_endpoint(config);
434
435
2
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
436
2
        DORIS_CHECK(adapter);
437
438
2
        adapter->init(config);
439
2
        return Status::OK();
440
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
421
3
                               std::shared_ptr<AIAdapter>& adapter) const {
422
3
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
423
3
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
424
3
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
425
426
3
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
427
3
                context->state()->get_query_ctx()->get_ai_resources();
428
3
        DORIS_CHECK(ai_resources);
429
3
        auto it = ai_resources->find(resource_name);
430
3
        DORIS_CHECK(it != ai_resources->end());
431
3
        config = it->second;
432
433
3
        normalize_endpoint(config);
434
435
3
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
436
3
        DORIS_CHECK(adapter);
437
438
3
        adapter->init(config);
439
3
        return Status::OK();
440
3
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
421
22
                               std::shared_ptr<AIAdapter>& adapter) const {
422
22
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
423
22
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
424
22
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
425
426
22
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
427
22
                context->state()->get_query_ctx()->get_ai_resources();
428
22
        DORIS_CHECK(ai_resources);
429
22
        auto it = ai_resources->find(resource_name);
430
22
        DORIS_CHECK(it != ai_resources->end());
431
22
        config = it->second;
432
433
22
        normalize_endpoint(config);
434
435
22
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
436
22
        DORIS_CHECK(adapter);
437
438
22
        adapter->init(config);
439
22
        return Status::OK();
440
22
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
441
442
    // Serializes one text batch into the shared JSON-array prompt format consumed by LLM
443
    // providers for batch string functions.
444
    Status build_batch_prompt(const std::vector<std::string>& batch_prompts,
445
0
                              std::string& prompt) const {
446
0
        rapidjson::StringBuffer buffer;
447
0
        rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
448
449
0
        writer.StartArray();
450
0
        for (size_t i = 0; i < batch_prompts.size(); ++i) {
451
0
            writer.StartObject();
452
0
            writer.Key("idx");
453
0
            writer.Uint64(i);
454
0
            writer.Key("input");
455
0
            writer.String(batch_prompts[i].data(),
456
0
                          static_cast<rapidjson::SizeType>(batch_prompts[i].size()));
457
0
            writer.EndObject();
458
0
        }
459
0
        writer.EndArray();
460
461
0
        prompt = buffer.GetString();
462
0
        return Status::OK();
463
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE18build_batch_promptERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EERS9_
464
};
465
466
} // namespace doris