Apache Doris 原生C++ UDF之Coding(2)

简介: Apache Doris 原生C++ UDF之Coding(2)

一、环境信息

1.1 硬件信息

  1. CPU :4C
  2. CPU型号:x64(AVX2)
  3. 内存 :10GB
  4. 硬盘 :66GB SSD

1.2 软件信息

  1. Linux版本 :CentOS-7
  2. Apahce Doris版本 :0.15-release
  3. CodeBlocks版本:20.03mingw

二、自定义TIME_TO_SEC函数

实现传入一个时间参数,将其时间部分转换成秒的UDF。

2.1 源码开发 & 实现一

2.1.1 测试主函数

//time_to_sec 的语法格式
//  TIME_TO_SEC(time)
//语法格式说明
//time:传入时间,如果传入了日期部分,也不会管,只将时间部分转换成秒
//重点:是指将传入的时间转换成距离当天00:00:00的秒数,00:00:00为基数,等于 0 秒
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int time_to_sec(string text)
{
    // clear other str
    regex r("^((?![0-9]{2}:[0-9]{2}:[0-9]{2}).)*");
    string time = regex_replace(text, r, "");
    cout << time << endl;
    // handle abnormal
    if(time.length() != 8)
        return NULL;
    // get hh mm ss
    int HH = atoi(time.substr(0,2).c_str());
    int MM = atoi(time.substr(3,2).c_str());
    int SS = atoi(time.substr(6,2).c_str());
    // return sum sec
    return HH*3600 + MM*60 + SS;
}
int main()
{
    cout<<time_to_sec("1987-01-01 00:39:38")<<endl;
    return 0;
}

2.1.2 UDF头文件

C++
#pragma once
#include "udf.h"
#include <bits/stdc++.h>
namespace doris_udf {
IntVal TIME_TO_SEC(FunctionContext* context, const StringVal& time);
/// --- Prepare / Close Functions ---
/// ---------------------------------
/// The UDF can optionally include a prepare function. The prepare function is called
/// before any calls to the UDF to evaluate values.
void AddUdfPrepare(FunctionContext* context, FunctionContext::FunctionStateScope scope);
/// The UDF can also optionally include a close function. The close function is called
/// after all calls to the UDF have completed.
void AddUdfClose(FunctionContext* context, FunctionContext::FunctionStateScope scope);
}

2.1.3 UDF源文件

C++
#include "time_to_sec.h"
namespace doris_udf {
IntVal TIME_TO_SEC(FunctionContext* context, const StringVal& time) {
    // handle null
    if (time.is_null) {
        return IntVal::null();
    }
    // clear other str
    using namespace std;
    const string timestr((char *)time.ptr);
    const regex r("^((?![0-9]{2}:[0-9]{2}:[0-9]{2}).)*");
    const string replace_str = "";
    string hms_time = regex_replace(timestr, r, replace_str);
    // handle str abnormal
    if(hms_time.length() != 8) {
        return IntVal::null();
    }
    // get hh mm ss
    int HH = atoi(hms_time.substr(0,2).c_str());
    int MM = atoi(hms_time.substr(3,2).c_str());
    int SS = atoi(hms_time.substr(6,2).c_str());
    // return sum sec
    return HH*3600 + MM*60 + SS;
}
/// --- Prepare / Close Functions ---
/// ---------------------------------
void AddUdfPrepare(FunctionContext* context, FunctionContext::FunctionStateScope scope) {}
void AddUdfClose(FunctionContext* context, FunctionContext::FunctionStateScope scope) {}
}

2.1.4 实现方式一小结

不建议使用,doris对其中的regex相关函数并不友好,会直接导致be所有节点crash。

2.2 源码开发 & 实现二

2.2.1 测试主函数

C++
//time_to_sec 的语法格式
//  TIME_TO_SEC(time)
//语法格式说明
//time:传入时间,如果传入了日期部分,也不会管,只将时间部分转换成秒
//重点:是指将传入的时间转换成距离当天00:00:00的秒数,00:00:00为基数,等于 0 秒
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int time_to_sec(string text)
{
   // clear other str
   string segSign = ":";
   string::size_type pos1 = text.find(segSign);
   if(pos1 == string::npos)
      cout << "没找到!" << endl;
   else
      cout << "找到了!下标:" << pos1<<endl;
    string time = text.substr(pos1-2,8);
    cout << time << endl;
    // handle abnormal
    if(time.length() != 8)
       return NULL;
    // get hh mm ss
    int HH = atoi(time.substr(0,2).c_str());
    int MM = atoi(time.substr(3,2).c_str());
    int SS = atoi(time.substr(6,2).c_str());
    // return sum sec
    return HH*3600 + MM*60 + SS;
}
int main()
{
    cout<<time_to_sec("1987-01-01 00:39:38")<<endl;
    return 0;
}

2.2.2 UDF头文件

C++
#pragma once
#include "udf.h"
#include <bits/stdc++.h>
namespace doris_udf {
IntVal TIME_TO_SEC(FunctionContext* context, const StringVal& time);
/// --- Prepare / Close Functions ---
/// ---------------------------------
/// The UDF can optionally include a prepare function. The prepare function is called
/// before any calls to the UDF to evaluate values.
void AddUdfPrepare(FunctionContext* context, FunctionContext::FunctionStateScope scope);
/// The UDF can also optionally include a close function. The close function is called
/// after all calls to the UDF have completed.
void AddUdfClose(FunctionContext* context, FunctionContext::FunctionStateScope scope);
}

2.2.3 UDF源文件

C++
#include "time_to_sec.h"
namespace doris_udf {
IntVal TIME_TO_SEC(FunctionContext* context, const StringVal& time) {
    // handle null
    if (time.is_null) {
        return IntVal::null();
    }
    // clear other str
    using namespace std;
    string timestr((char *)time.ptr);
    string segSign = ":";
    string::size_type pos = timestr.find(segSign);
    string hms_time;
    if(pos == string::npos)
        return IntVal::null();
     else
        hms_time = timestr.substr(pos-2,8);
    // handle str abnormal
    if(hms_time.length() != 8) {
        return IntVal::null();
    }
    // get hh mm ss
    int HH = atoi(hms_time.substr(0,2).c_str());
    int MM = atoi(hms_time.substr(3,2).c_str());
    int SS = atoi(hms_time.substr(6,2).c_str());
    // return sum sec
    IntVal result;
    result.val = HH*3600 + MM*60 + SS;
    return {result.val};
}
/// --- Prepare / Close Functions ---
/// ---------------------------------
void AddUdfPrepare(FunctionContext* context, FunctionContext::FunctionStateScope scope) {}
void AddUdfClose(FunctionContext* context, FunctionContext::FunctionStateScope scope) {}
}

2.2.4 实现方式二小结

基本完全使用字符串的API实现,简单高效并且兼容性较好,最终选定实现二。

三、编译结果

四、函数使用

4.1 创建 UDF 函数

CREATE FUNCTION 
TIME_TO_SEC(String) 
RETURNS INT PROPERTIES ( 
"symbol" = "_ZN9doris_udf11TIME_TO_SECEPNS_15FunctionContextERKNS_9StringValE",
"object_file" = "http://10.192.119.68:8088/udf/udf_samples/build/src/udf_samples/libtime_to_sec.so" );

4.2 使用UDF 函数

原先不兼容TIME_TO_SEC的Tableau固化SQL,现在可以正常运行。

五、总结

  • 自定义C++ UDF 的使用与普通的函数方式一致,唯一的区别在于,内置函数的作用域是全局的,而 UDF 的作用域是 DB 内部
  • 1.2后的新版本不建议使用原生C++ UDF,因为兼容性较差、GLIBC一升级就没法用了;建议使用JAVA UDF

Apache Doris 自定义C++ UDF的Coding至此结束,查阅过程中若遇到问题欢迎留言交流

相关文章
|
11月前
|
消息中间件 OLAP Kafka
Apache Doris 实时更新技术揭秘:为何在 OLAP 领域表现卓越?
Apache Doris 为何在 OLAP 领域表现卓越?凭借其主键模型、数据延迟、查询性能、并发处理、易用性等多方面特性的表现,在分析领域展现了独特的实时更新能力。
858 9
|
12月前
|
JSON 关系型数据库 Apache
十亿 JSON 秒级响应:Apache Doris vs ClickHouse,Elasticsearch,PostgreSQL
JSONBench 是一个为 JSON 数据而生的数据分析 Benchmark,在默认设置下,Doris 的性能表现是 Elasticsearch 的 2 倍,是 PostgreSQL 的 80 倍。调优后,Doris 查询整体耗时降低了 74%,对比原榜单第一的 ClickHouse 产品实现了 39% 的领先优势。本文详细描述了调优思路与 Doris 调优前后的性能表现,欢迎阅读了解~
1287 0
十亿 JSON 秒级响应:Apache Doris vs ClickHouse,Elasticsearch,PostgreSQL
|
10月前
|
存储 自然语言处理 分布式计算
Apache Doris 3.1 正式发布:半结构化分析全面升级,湖仓一体能力再跃新高
Apache Doris 3.1 正式发布!全面升级半结构化分析,支持 VARIANT 稀疏列与模板化 Schema,提升湖仓一体能力,增强 Iceberg/Paimon 集成,优化存储引擎与查询性能,助力高效数据分析。
1137 4
Apache Doris 3.1 正式发布:半结构化分析全面升级,湖仓一体能力再跃新高
|
11月前
|
存储 分布式计算 Apache
湖仓一体:小米集团基于 Apache Doris + Apache Paimon 实现 6 倍性能飞跃
小米通过将 Apache Doris(数据库)与 Apache Paimon(数据湖)深度融合,不仅解决了数据湖分析的性能瓶颈,更实现了 “1+1>2” 的协同效应。在这些实践下,小米在湖仓数据分析场景下获得了可观的业务收益。
1600 9
湖仓一体:小米集团基于 Apache Doris + Apache Paimon 实现 6 倍性能飞跃
|
11月前
|
人工智能 运维 监控
智能运维与数据治理:基于 Apache Doris 的 Data Agent 解决方案
本文基于 Apache Doris 数据运维治理 Agent 展开讨论,如何让 AI 成为 Doris 数据运维工程师和数据治理专家的智能助手,并在某些场景下实现对人工操作的全面替代。这种变革不仅仅是技术层面的进步,更是数据运维治理思维方式的根本性转变:从“被动响应”到“主动预防”,从“人工判断”到“智能决策”,从“孤立处理”到“协同治理”。
1651 11
智能运维与数据治理:基于 Apache Doris 的 Data Agent 解决方案
|
人工智能 监控 数据挖掘
6/14 上海,Apache Doris x 阿里云 SelectDB AI 主题线下 Meetup 正式开启报名!
6 月 14 日,由 Apache Doris 社区、飞轮科技、阿里云联合发起的湖仓数智融合、AI 洞见未来:Apache Doris x 阿里云 SelectDB 联合 Meetup 将在上海·汇付天下总部大楼正式开启,邀您一同探索 AI 与数据分析的融合实践!
592 76
|
10月前
|
SQL 人工智能 数据挖掘
Apache Doris 4.0 AI 能力揭秘(二):为企业级应用而生的 AI 函数设计与实践
Apache Doris 4.0 原生集成 LLM 函数,将大语言模型能力深度融入 SQL 引擎,实现文本处理智能化与数据分析一体化。通过十大函数,支持智能客服、内容分析、金融风控等场景,提升实时决策效率。采用资源池化管理,保障数据一致性,降低传输开销,毫秒级完成 AI 分析。结合缓存复用、并行执行与权限控制,兼顾性能、成本与安全,推动数据库向 AI 原生演进。
997 0
Apache Doris 4.0 AI 能力揭秘(二):为企业级应用而生的 AI 函数设计与实践
|
11月前
|
SQL 存储 运维
Apache Doris 在菜鸟的大规模湖仓业务场景落地实践
本文介绍了 Apache Doris 在菜鸟的大规模落地的实践经验,菜鸟为什么选择 Doris,以及 Doris 如何在菜鸟从 0 开始,一步步的验证、落地,到如今上万核的规模,服务于各个业务线,Doris 已然成为菜鸟 OLAP 数据分析的最优选型。
627 2
Apache Doris 在菜鸟的大规模湖仓业务场景落地实践
|
11月前
|
SQL 存储 JSON
Apache Doris 2.1.10 版本正式发布
亲爱的社区小伙伴们,Apache Doris 2.1.10 版本已正式发布。2.1.10 版本对湖仓一体、半结构化数据类型、查询优化器、执行引擎、存储管理进行了若干改进优化。欢迎大家下载使用。
472 5
|
11月前
|
人工智能 自然语言处理 数据挖掘
Apache Doris 4.0 AI 能力揭秘(一):AI 函数之 LLM 函数介绍
在即将发布的 Apache Doris 4.0 版本中,我们正式引入了一系列 LLM 函数,将前沿的 AI 能力与日常的数据分析相结合,无论是精准提取文本信息,还是对评论进行情感分类,亦或生成精炼的文本摘要,皆可在数据库内部无缝完成。
691 0
Apache Doris 4.0 AI 能力揭秘(一):AI 函数之 LLM 函数介绍

推荐镜像

更多