blob: 8e77ae3809b6ffe83ea0f51330fff2f6842b35d4 [file] [log] [blame]
import{_ as l,r as t,o as i,c,a as r,d as s,e as n,b as a,w as d,f as e}from"./app-5cdcb249.js";const u={},k=e('<h1 id="多语言远程-udf-c-c-java" tabindex="-1"><a class="header-anchor" href="#多语言远程-udf-c-c-java" aria-hidden="true">#</a> 多语言远程 UDF(C / C++ / Java / ...)</h1><p>Remote UDF Service 支持通过 RPC 的方式访问用户提供的 UDF Service,以实现用户自定义函数的执行。<br> 相比于 Native 的 UDF 实现,Remote UDF Service 有如下优势:</p><ul><li>跨语言:可以用 Protobuf 支持的各类语言编写 UDF Service。</li><li>安全:UDF 执行失败或崩溃,仅会影响 UDF Service 自身,而不会导致 IoTDB 进程崩溃。</li><li>灵活:UDF Service 中可以调用任意其他服务或程序库类,以满足更多样的业务需求。</li></ul><h2 id="依赖" tabindex="-1"><a class="header-anchor" href="#依赖" aria-hidden="true">#</a> 依赖</h2><h3 id="protobuf-编译安装" tabindex="-1"><a class="header-anchor" href="#protobuf-编译安装" aria-hidden="true">#</a> protobuf 编译安装</h3>',5),h={href:"https://github.com/protocolbuffers/protobuf/releases",target:"_blank",rel:"noopener noreferrer"},m=s("li",null,"确认安装依赖库:automake,autoconf,libtool是否已经安装,未安装的需要安装",-1),b=s("li",null,"下载 protobuf 安装文件,解压",-1),v=s("li",null,"编译 (用于生成编译服务器下可执行程序):",-1),g=e(`<div class="language-bash line-numbers-mode" data-ext="sh"><pre class="language-bash"><code>./autogen.sh
./configure <span class="token parameter variable">--prefix</span><span class="token operator">=</span>/XX/bin/protobuflib/
<span class="token function">make</span>
<span class="token function">make</span> <span class="token function">install</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你使用的是 Java C++等,完成以上步骤就已经可以使用生成的protobuf可执行程序生产protobuf相关文件了。</p><h3 id="protobuf-c-编译安装-c-语言远程-udf-需此步骤" tabindex="-1"><a class="header-anchor" href="#protobuf-c-编译安装-c-语言远程-udf-需此步骤" aria-hidden="true">#</a> protobuf-c 编译安装(C 语言远程 UDF 需此步骤)</h3>`,3),f={href:"https://codechina.csdn.net/mirrors/protobuf-c/protobuf-c/-/releases/v1.4.0?spm=1033.2243.3001.5876",target:"_blank",rel:"noopener noreferrer"},x=s("li",null,"确认安装依赖库:protobuf, 设置之前protobuf编译出的依赖库资源的环境变量:",-1),F=e(`<div class="language-bash line-numbers-mode" data-ext="sh"><pre class="language-bash"><code><span class="token assign-left variable">PKG_CONFIG_PATH</span><span class="token operator">=</span>/XX/bin/protobuflib/
<span class="token builtin class-name">export</span> PKG_CONFIG_PATH
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><ul><li>下载protobuf-c,解压</li><li>编译 (用于生成编译服务器下可执行程序):</li></ul><div class="language-bash line-numbers-mode" data-ext="sh"><pre class="language-bash"><code>./autogen.sh
./configure <span class="token parameter variable">--prefix</span><span class="token operator">=</span>/XX/bin/protobufc/
<span class="token function">make</span>
<span class="token function">make</span> <span class="token function">install</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>protobufc下生成的文件,即为编译生成的依赖库、protobuf-c可执行程序,使用protobuf-c可执行程序可以根据proto文件生成.c和.h文件</p><h2 id="编写-udf-函数" tabindex="-1"><a class="header-anchor" href="#编写-udf-函数" aria-hidden="true">#</a> 编写 UDF 函数</h2><h3 id="拷贝-proto-文件" tabindex="-1"><a class="header-anchor" href="#拷贝-proto-文件" aria-hidden="true">#</a> 拷贝 proto 文件</h3><p>function_service.proto 和 types.proto 拷贝到 Rpc 服务中</p><ul><li>function_service.proto <ul><li>PFunctionCallRequest <ul><li>function_name:函数名称,对应创建函数时指定的symbol</li><li>args:方法传递的参数</li><li>context:查询上下文信息</li></ul></li><li>PFunctionCallResponse <ul><li>result:结果</li><li>status:状态,0代表正常</li></ul></li><li>PCheckFunctionRequest <ul><li>function:函数相关信息</li><li>match_type:匹配类型</li></ul></li><li>PCheckFunctionResponse <ul><li>status:状态,0代表正常</li></ul></li></ul></li></ul><h3 id="生成接口" tabindex="-1"><a class="header-anchor" href="#生成接口" aria-hidden="true">#</a> 生成接口</h3><p>通过 protoc 生成代码,具体参数通过 protoc -h 查看</p><h3 id="实现接口" tabindex="-1"><a class="header-anchor" href="#实现接口" aria-hidden="true">#</a> 实现接口</h3><p>共需要实现以下三个方法</p><ul><li>fnCall:用于编写计算逻辑</li><li>checkFn:用于创建 UDF 时校验,校验函数名/参数/返回值等是否合法</li><li>handShake:用于接口探活</li></ul><h2 id="创建-udf" tabindex="-1"><a class="header-anchor" href="#创建-udf" aria-hidden="true">#</a> 创建 UDF</h2><div class="language-sql line-numbers-mode" data-ext="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> <span class="token operator">&lt;</span>UDF<span class="token operator">-</span>NAME<span class="token operator">&gt;</span> <span class="token keyword">AS</span>
SYMBOL <span class="token operator">=</span> <span class="token operator">&lt;</span>SYMBOL<span class="token operator">&gt;</span><span class="token punctuation">,</span>
OBJECT_FILE <span class="token operator">=</span> <span class="token operator">&lt;</span>OBJECT_FILE<span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token keyword">LANGUAGE</span> PROTOBUF
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>说明:</p><ol><li><code>symbol</code>表示的是 rpc 调用传递的方法名,这个参数是必须设定的。</li><li><code>object_file</code>表示的 rpc 服务地址,目前支持单个地址和 brpc 兼容格式的集群地址。</li></ol><p>示例:</p><div class="language-sql line-numbers-mode" data-ext="sql"><pre class="language-sql"><code><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> rpc_udf1 <span class="token keyword">AS</span>
SYMBOL <span class="token operator">=</span> <span class="token string">&quot;fnCall&quot;</span><span class="token punctuation">,</span>
OBJECT_FILE <span class="token operator">=</span> <span class="token string">&quot;127.0.0.1:9090&quot;</span><span class="token punctuation">,</span>
<span class="token keyword">LANGUAGE</span> PROTOBUF<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="udf-卸载" tabindex="-1"><a class="header-anchor" href="#udf-卸载" aria-hidden="true">#</a> UDF 卸载</h2><p>卸载 UDF SQL 语法如下:</p><div class="language-sql line-numbers-mode" data-ext="sql"><pre class="language-sql"><code><span class="token keyword">DROP</span> <span class="token keyword">FUNCTION</span> <span class="token operator">&lt;</span>UDF<span class="token operator">-</span>NAME<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>例如:</p><div class="language-sql line-numbers-mode" data-ext="sql"><pre class="language-sql"><code><span class="token keyword">DROP</span> <span class="token keyword">FUNCTION</span> rpc_udf1
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h2 id="udf-查询" tabindex="-1"><a class="header-anchor" href="#udf-查询" aria-hidden="true">#</a> UDF 查询</h2><p>UDF 的使用方法与普通内建函数的类似。</p><h3 id="支持的基础-sql-语法" tabindex="-1"><a class="header-anchor" href="#支持的基础-sql-语法" aria-hidden="true">#</a> 支持的基础 SQL 语法</h3><ul><li><code>SLIMIT</code> / <code>SOFFSET</code></li><li><code>LIMIT</code> / <code>OFFSET</code></li><li>支持值过滤</li><li>支持时间过滤</li></ul><h3 id="带-查询" tabindex="-1"><a class="header-anchor" href="#带-查询" aria-hidden="true">#</a> * 查询</h3><p>假定现在有时间序列 <code>root.sg.d1.s1</code>和 <code>root.sg.d1.s2</code>。</p><ul><li><strong>执行<code>SELECT example(*) from root.sg.d1</code></strong></li></ul><p>那么结果集中将包括<code>example(root.sg.d1.s1)</code>和<code>example(root.sg.d1.s2)</code>的结果。</p><ul><li><strong>执行<code>SELECT example(s1, *) from root.sg.d1</code></strong></li></ul><p>那么结果集中将包括<code>example(root.sg.d1.s1, root.sg.d1.s1)</code>和<code>example(root.sg.d1.s1, root.sg.d1.s2)</code>的结果。</p><ul><li><strong>执行<code>SELECT example(*, *) from root.sg.d1</code></strong></li></ul><p>那么结果集中将包括<code>example(root.sg.d1.s1, root.sg.d1.s1)</code>,<code>example(root.sg.d1.s2, root.sg.d1.s1)</code>,<code>example(root.sg.d1.s1, root.sg.d1.s2)</code> 和 <code>example(root.sg.d1.s2, root.sg.d1.s2)</code>的结果。</p><h3 id="带自定义输入参数的查询" tabindex="-1"><a class="header-anchor" href="#带自定义输入参数的查询" aria-hidden="true">#</a> 带自定义输入参数的查询</h3><p>您可以在进行 UDF 查询的时候,向 UDF 传入任意数量的键值对参数。键值对中的键和值都需要被单引号或者双引号引起来。注意,键值对参数只能在所有时间序列后传入。下面是一组例子:</p><div class="language-sql line-numbers-mode" data-ext="sql"><pre class="language-sql"><code><span class="token keyword">SELECT</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> <span class="token string">&#39;key1&#39;</span><span class="token operator">=</span><span class="token string">&#39;value1&#39;</span><span class="token punctuation">,</span> <span class="token string">&#39;key2&#39;</span><span class="token operator">=</span><span class="token string">&#39;value2&#39;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> example<span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token string">&#39;key3&#39;</span><span class="token operator">=</span><span class="token string">&#39;value3&#39;</span><span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">,</span> <span class="token string">&#39;key1&#39;</span><span class="token operator">=</span><span class="token string">&#39;value1&#39;</span><span class="token punctuation">,</span> <span class="token string">&#39;key2&#39;</span><span class="token operator">=</span><span class="token string">&#39;value2&#39;</span><span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="与其他查询的嵌套查询" tabindex="-1"><a class="header-anchor" href="#与其他查询的嵌套查询" aria-hidden="true">#</a> 与其他查询的嵌套查询</h3><div class="language-sql line-numbers-mode" data-ext="sql"><pre class="language-sql"><code><span class="token keyword">SELECT</span> s1<span class="token punctuation">,</span> s2<span class="token punctuation">,</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> <span class="token operator">*</span><span class="token punctuation">,</span> example<span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1 <span class="token keyword">DISABLE</span> ALIGN<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> s1 <span class="token operator">*</span> example<span class="token punctuation">(</span><span class="token operator">*</span> <span class="token operator">/</span> s1 <span class="token operator">+</span> s2<span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
<span class="token keyword">SELECT</span> s1<span class="token punctuation">,</span> s2<span class="token punctuation">,</span> s1 <span class="token operator">+</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">)</span><span class="token punctuation">,</span> s1 <span class="token operator">-</span> example<span class="token punctuation">(</span>s1 <span class="token operator">+</span> example<span class="token punctuation">(</span>s1<span class="token punctuation">,</span> s2<span class="token punctuation">)</span> <span class="token operator">/</span> s2<span class="token punctuation">)</span> <span class="token keyword">FROM</span> root<span class="token punctuation">.</span>sg<span class="token punctuation">.</span>d1<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="查看所有注册的-udf" tabindex="-1"><a class="header-anchor" href="#查看所有注册的-udf" aria-hidden="true">#</a> 查看所有注册的 UDF</h2><div class="language-sql line-numbers-mode" data-ext="sql"><pre class="language-sql"><code><span class="token keyword">SHOW</span> FUNCTIONS
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h2 id="用户权限管理" tabindex="-1"><a class="header-anchor" href="#用户权限管理" aria-hidden="true">#</a> 用户权限管理</h2><p>用户在使用 UDF 时会涉及到 3 种权限:</p><ul><li><code>CREATE_FUNCTION</code>:具备该权限的用户才被允许执行 UDF 注册操作</li><li><code>DROP_FUNCTION</code>:具备该权限的用户才被允许执行 UDF 卸载操作</li><li><code>READ_TIMESERIES</code>:具备该权限的用户才被允许使用 UDF 进行查询</li></ul>`,46);function _(E,S){const o=t("ExternalLinkIcon"),p=t("RouterLink");return i(),c("div",null,[r(`
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
`),k,s("ul",null,[s("li",null,[n("下载地址 "),s("a",h,[n("https://github.com/protocolbuffers/protobuf/releases"),a(o)])]),m,b,v]),g,s("ul",null,[s("li",null,[n("下载地址: "),s("a",f,[n("https://codechina.csdn.net/mirrors/protobuf-c/protobuf-c/-/releases/v1.4.0?spm=1033.2243.3001.5876"),a(o)])]),x]),F,s("p",null,[n("更多用户权限相关的内容,请参考 "),a(p,{to:"/zh/UserGuide/V1.2.x/stage/Administration-Management/Administration.html"},{default:d(()=>[n("权限管理语句")]),_:1}),n("。")])])}const y=l(u,[["render",_],["__file","User-Defined-Function-C_timecho.html.vue"]]);export{y as default};