-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathfunctions.html
334 lines (312 loc) · 30.3 KB
/
functions.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>10.5. Functions — Presto 0.189 Documentation</title>
<link rel="stylesheet" href="../_static/presto.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.189',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="top" title="Presto 0.189 Documentation" href="../index.html" />
<link rel="up" title="10. Developer Guide" href="../develop.html" />
<link rel="next" title="10.6. System Access Control" href="system-access-control.html" />
<link rel="prev" title="10.4. Types" href="types.html" />
</head>
<body role="document">
<div class="header">
<h1 class="heading"><a href="../index.html">
<span>Presto 0.189 Documentation</span></a></h1>
<h2 class="heading"><span>10.5. Functions</span></h2>
</div>
<div class="topnav">
<p class="nav">
<span class="left">
« <a href="types.html">10.4. Types</a>
</span>
<span class="right">
<a href="system-access-control.html">10.6. System Access Control</a> »
</span>
</p>
</div>
<div class="content">
<div class="section" id="functions">
<h1>10.5. Functions</h1>
<div class="section" id="plugin-implementation">
<h2>Plugin Implementation</h2>
<p>The function framework is used to implement SQL functions. Presto includes a
number of built-in functions. In order to implement new functions, you can
write a plugin that returns one more more functions from <code class="docutils literal"><span class="pre">getFunctions()</span></code>:</p>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExampleFunctionsPlugin</span>
<span class="kd">implements</span> <span class="n">Plugin</span>
<span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Set</span><span class="o"><</span><span class="n">Class</span><span class="o"><?>></span> <span class="n">getFunctions</span><span class="o">()</span>
<span class="o">{</span>
<span class="k">return</span> <span class="n">ImmutableSet</span><span class="o">.<</span><span class="n">Class</span><span class="o"><?>></span><span class="n">builder</span><span class="o">()</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">ExampleNullFunction</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">IsNullFunction</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">IsEqualOrNullFunction</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">ExampleStringFunction</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">ExampleAverageFunction</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
</div>
<p>Note that the <code class="docutils literal"><span class="pre">ImmutableSet</span></code> class is a utility class from Guava.
The <code class="docutils literal"><span class="pre">getFunctions()</span></code> method contains all of the classes for the functions
that we will implement below in this tutorial.</p>
<p>For a full example in the codebase, see either the <code class="docutils literal"><span class="pre">presto-ml</span></code> module for machine
learning functions or the <code class="docutils literal"><span class="pre">presto-teradata-functions</span></code> module for Teradata-compatible
functions, both in the root of the Presto source.</p>
</div>
<div class="section" id="scalar-function-implementation">
<h2>Scalar Function Implementation</h2>
<p>The function framework uses annotations to indicate relevant information
about functions, including name, description, return type and parameter
types. Below is a sample function which implements <code class="docutils literal"><span class="pre">is_null</span></code>:</p>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExampleNullFunction</span>
<span class="o">{</span>
<span class="nd">@ScalarFunction</span><span class="o">(</span><span class="s">"is_null"</span><span class="o">)</span>
<span class="nd">@Description</span><span class="o">(</span><span class="s">"Returns TRUE if the argument is NULL"</span><span class="o">)</span>
<span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">BOOLEAN</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isNull</span><span class="o">(</span><span class="nd">@SqlNullable</span> <span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">VARCHAR</span><span class="o">)</span> <span class="n">Slice</span> <span class="n">string</span><span class="o">)</span>
<span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="n">string</span> <span class="o">==</span> <span class="kc">null</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
</div>
<p>The function <code class="docutils literal"><span class="pre">is_null</span></code> takes a single <code class="docutils literal"><span class="pre">VARCHAR</span></code> argument and returns a
<code class="docutils literal"><span class="pre">BOOLEAN</span></code> indicating if the argument was <code class="docutils literal"><span class="pre">NULL</span></code>. Note that the argument to
the function is of type <code class="docutils literal"><span class="pre">Slice</span></code>. <code class="docutils literal"><span class="pre">VARCHAR</span></code> uses <code class="docutils literal"><span class="pre">Slice</span></code>, which is essentially
a wrapper around <code class="docutils literal"><span class="pre">byte[]</span></code>, rather than <code class="docutils literal"><span class="pre">String</span></code> for its native container type.</p>
<ul>
<li><p class="first"><code class="docutils literal"><span class="pre">@SqlType</span></code>:</p>
<p>The <code class="docutils literal"><span class="pre">@SqlType</span></code> annotation is used to declare the return type and the argument
types. Note that the return type and arguments of the Java code must match
the native container types of the corresponding annotations.</p>
</li>
<li><p class="first"><code class="docutils literal"><span class="pre">@SqlNullable</span></code>:</p>
<p>The <code class="docutils literal"><span class="pre">@SqlNullable</span></code> annotation indicates that the argument may be <code class="docutils literal"><span class="pre">NULL</span></code>. Without
this annotation the framework assumes that all functions return <code class="docutils literal"><span class="pre">NULL</span></code> if
any of their arguments are <code class="docutils literal"><span class="pre">NULL</span></code>. When working with a <code class="docutils literal"><span class="pre">Type</span></code> that has a
primitive native container type, such as <code class="docutils literal"><span class="pre">BigintType</span></code>, use the object wrapper for the
native container type when using <code class="docutils literal"><span class="pre">@SqlNullable</span></code>. The method must be annotated with
<code class="docutils literal"><span class="pre">@SqlNullable</span></code> if it can return <code class="docutils literal"><span class="pre">NULL</span></code> when the arguments are non-null.</p>
</li>
</ul>
</div>
<div class="section" id="parametric-scalar-functions">
<h2>Parametric Scalar Functions</h2>
<p>Scalar functions that have type parameters have some additional complexity.
To make our previous example work with any type we need the following:</p>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="nd">@ScalarFunction</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"is_null"</span><span class="o">)</span>
<span class="nd">@Description</span><span class="o">(</span><span class="s">"Returns TRUE if the argument is NULL"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">IsNullFunction</span>
<span class="o">{</span>
<span class="nd">@TypeParameter</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span>
<span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">BOOLEAN</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isNullSlice</span><span class="o">(</span><span class="nd">@SqlNullable</span> <span class="nd">@SqlType</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span> <span class="n">Slice</span> <span class="n">value</span><span class="o">)</span>
<span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="n">value</span> <span class="o">==</span> <span class="kc">null</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@TypeParameter</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span>
<span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">BOOLEAN</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isNullLong</span><span class="o">(</span><span class="nd">@SqlNullable</span> <span class="nd">@SqlType</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span> <span class="n">Long</span> <span class="n">value</span><span class="o">)</span>
<span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="n">value</span> <span class="o">==</span> <span class="kc">null</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@TypeParameter</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span>
<span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">BOOLEAN</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isNullDouble</span><span class="o">(</span><span class="nd">@SqlNullable</span> <span class="nd">@SqlType</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span> <span class="n">Double</span> <span class="n">value</span><span class="o">)</span>
<span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="n">value</span> <span class="o">==</span> <span class="kc">null</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// ...and so on for each native container type</span>
<span class="o">}</span>
</pre></div>
</div>
<ul>
<li><p class="first"><code class="docutils literal"><span class="pre">@TypeParameter</span></code>:</p>
<p>The <code class="docutils literal"><span class="pre">@TypeParameter</span></code> annotation is used to declare a type parameter which can
be used in the argument types <code class="docutils literal"><span class="pre">@SqlType</span></code> annotation, or return type of the function.
It can also be used to annotate a parameter of type <code class="docutils literal"><span class="pre">Type</span></code>. At runtime, the engine
will bind the concrete type to this parameter. <code class="docutils literal"><span class="pre">@OperatorDependency</span></code> may be used
to declare that an additional function for operating on the given type parameter is needed.
For example, the following function will only bind to types which have an equals function
defined:</p>
</li>
</ul>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="nd">@ScalarFunction</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"is_equal_or_null"</span><span class="o">)</span>
<span class="nd">@Description</span><span class="o">(</span><span class="s">"Returns TRUE if arguments are equal or both NULL"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">IsEqualOrNullFunction</span>
<span class="o">{</span>
<span class="nd">@TypeParameter</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span>
<span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">BOOLEAN</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isEqualOrNullSlice</span><span class="o">(</span>
<span class="nd">@OperatorDependency</span><span class="o">(</span><span class="n">operator</span> <span class="o">=</span> <span class="n">OperatorType</span><span class="o">.</span><span class="na">EQUAL</span><span class="o">,</span> <span class="n">returnType</span> <span class="o">=</span> <span class="n">StandardTypes</span><span class="o">.</span><span class="na">BOOLEAN</span><span class="o">,</span> <span class="n">argumentTypes</span> <span class="o">=</span> <span class="o">{</span><span class="s">"T"</span><span class="o">,</span> <span class="s">"T"</span><span class="o">})</span> <span class="n">MethodHandle</span> <span class="n">equals</span><span class="o">,</span>
<span class="nd">@SqlNullable</span> <span class="nd">@SqlType</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span> <span class="n">Slice</span> <span class="n">value1</span><span class="o">,</span>
<span class="nd">@SqlNullable</span> <span class="nd">@SqlType</span><span class="o">(</span><span class="s">"T"</span><span class="o">)</span> <span class="n">Slice</span> <span class="n">value2</span><span class="o">)</span>
<span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">value1</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">&&</span> <span class="n">value2</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(</span><span class="n">value1</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="n">value2</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">return</span> <span class="o">(</span><span class="kt">boolean</span><span class="o">)</span> <span class="n">equals</span><span class="o">.</span><span class="na">invokeExact</span><span class="o">(</span><span class="n">value1</span><span class="o">,</span> <span class="n">value2</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// ...and so on for each native container type</span>
<span class="o">}</span>
</pre></div>
</div>
</div>
<div class="section" id="another-scalar-function-example">
<h2>Another Scalar Function Example</h2>
<p>The <code class="docutils literal"><span class="pre">lowercaser</span></code> function takes a single <code class="docutils literal"><span class="pre">VARCHAR</span></code> argument and returns a
<code class="docutils literal"><span class="pre">VARCHAR</span></code>, which is the argument converted to lower case:</p>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExampleStringFunction</span>
<span class="o">{</span>
<span class="nd">@ScalarFunction</span><span class="o">(</span><span class="s">"lowercaser"</span><span class="o">)</span>
<span class="nd">@Description</span><span class="o">(</span><span class="s">"converts the string to alternating case"</span><span class="o">)</span>
<span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">VARCHAR</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">Slice</span> <span class="nf">lowercaser</span><span class="o">(</span><span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">VARCHAR</span><span class="o">)</span> <span class="n">Slice</span> <span class="n">slice</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">String</span> <span class="n">argument</span> <span class="o">=</span> <span class="n">slice</span><span class="o">.</span><span class="na">toStringUtf8</span><span class="o">();</span>
<span class="k">return</span> <span class="n">Slices</span><span class="o">.</span><span class="na">utf8Slice</span><span class="o">(</span><span class="n">argument</span><span class="o">.</span><span class="na">toLowerCase</span><span class="o">());</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
</div>
<p>Note that for most common string functions, including converting a string to
lower case, the Slice library also provides implementations that work directly
on the underlying <code class="docutils literal"><span class="pre">byte[]</span></code>, which have much better performance. This function
has no <code class="docutils literal"><span class="pre">@SqlNullable</span></code> annotations, meaning that if the argument is <code class="docutils literal"><span class="pre">NULL</span></code>,
the result will automatically be <code class="docutils literal"><span class="pre">NULL</span></code> (the function will not be called).</p>
</div>
<div class="section" id="aggregation-function-implementation">
<h2>Aggregation Function Implementation</h2>
<p>Aggregation functions use a similar framework to scalar functions, but are
a bit more complex.</p>
<ul>
<li><p class="first"><code class="docutils literal"><span class="pre">AccumulatorState</span></code>:</p>
<p>All aggregation functions accumulate input rows into a state object; this
object must implement <code class="docutils literal"><span class="pre">AccumulatorState</span></code>. For simple aggregations, just
extend <code class="docutils literal"><span class="pre">AccumulatorState</span></code> into a new interface with the getters and setters
you want, and the framework will generate all the implementations and
serializers for you. If you need a more complex state object, you will need
to implement <code class="docutils literal"><span class="pre">AccumulatorStateFactory</span></code> and <code class="docutils literal"><span class="pre">AccumulatorStateSerializer</span></code>
and provide these via the <code class="docutils literal"><span class="pre">AccumulatorStateMetadata</span></code> annotation.</p>
</li>
</ul>
<p>The following code implements the aggregation function <code class="docutils literal"><span class="pre">avg_double</span></code> which computes the
average of a <code class="docutils literal"><span class="pre">DOUBLE</span></code> column:</p>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="nd">@AggregationFunction</span><span class="o">(</span><span class="s">"avg_double"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">AverageAggregation</span>
<span class="o">{</span>
<span class="nd">@InputFunction</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">input</span><span class="o">(</span><span class="n">LongAndDoubleState</span> <span class="n">state</span><span class="o">,</span> <span class="nd">@SqlType</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">DOUBLE</span><span class="o">)</span> <span class="kt">double</span> <span class="n">value</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">state</span><span class="o">.</span><span class="na">setLong</span><span class="o">(</span><span class="n">state</span><span class="o">.</span><span class="na">getLong</span><span class="o">()</span> <span class="o">+</span> <span class="mi">1</span><span class="o">);</span>
<span class="n">state</span><span class="o">.</span><span class="na">setDouble</span><span class="o">(</span><span class="n">state</span><span class="o">.</span><span class="na">getDouble</span><span class="o">()</span> <span class="o">+</span> <span class="n">value</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@CombineFunction</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">combine</span><span class="o">(</span><span class="n">LongAndDoubleState</span> <span class="n">state</span><span class="o">,</span> <span class="n">LongAndDoubleState</span> <span class="n">otherState</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">state</span><span class="o">.</span><span class="na">setLong</span><span class="o">(</span><span class="n">state</span><span class="o">.</span><span class="na">getLong</span><span class="o">()</span> <span class="o">+</span> <span class="n">otherState</span><span class="o">.</span><span class="na">getLong</span><span class="o">());</span>
<span class="n">state</span><span class="o">.</span><span class="na">setDouble</span><span class="o">(</span><span class="n">state</span><span class="o">.</span><span class="na">getDouble</span><span class="o">()</span> <span class="o">+</span> <span class="n">otherState</span><span class="o">.</span><span class="na">getDouble</span><span class="o">());</span>
<span class="o">}</span>
<span class="nd">@OutputFunction</span><span class="o">(</span><span class="n">StandardTypes</span><span class="o">.</span><span class="na">DOUBLE</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">output</span><span class="o">(</span><span class="n">LongAndDoubleState</span> <span class="n">state</span><span class="o">,</span> <span class="n">BlockBuilder</span> <span class="n">out</span><span class="o">)</span>
<span class="o">{</span>
<span class="kt">long</span> <span class="n">count</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="na">getLong</span><span class="o">();</span>
<span class="k">if</span> <span class="o">(</span><span class="n">count</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="n">out</span><span class="o">.</span><span class="na">appendNull</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">else</span> <span class="o">{</span>
<span class="kt">double</span> <span class="n">value</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="na">getDouble</span><span class="o">();</span>
<span class="n">DOUBLE</span><span class="o">.</span><span class="na">writeDouble</span><span class="o">(</span><span class="n">out</span><span class="o">,</span> <span class="n">value</span> <span class="o">/</span> <span class="n">count</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
</div>
<p>The average has two parts: the sum of the <code class="docutils literal"><span class="pre">DOUBLE</span></code> in each row of the column
and the <code class="docutils literal"><span class="pre">LONG</span></code> count of the number of rows seen. <code class="docutils literal"><span class="pre">LongAndDoubleState</span></code> is an interface
which extends <code class="docutils literal"><span class="pre">AccumulatorState</span></code>:</p>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">LongAndDoubleState</span>
<span class="kd">extends</span> <span class="n">AccumulatorState</span>
<span class="o">{</span>
<span class="kt">long</span> <span class="nf">getLong</span><span class="o">();</span>
<span class="kt">void</span> <span class="nf">setLong</span><span class="o">(</span><span class="kt">long</span> <span class="n">value</span><span class="o">);</span>
<span class="kt">double</span> <span class="nf">getDouble</span><span class="o">();</span>
<span class="kt">void</span> <span class="nf">setDouble</span><span class="o">(</span><span class="kt">double</span> <span class="n">value</span><span class="o">);</span>
<span class="o">}</span>
</pre></div>
</div>
<p>As stated above, for simple <code class="docutils literal"><span class="pre">AccumulatorState</span></code> objects, it is sufficient to
just to define the interface with the getters and setters, and the framework
will generate the implementation for you.</p>
<p>An in-depth look at the various annotations relevant to writing an aggregation
function follows:</p>
<ul>
<li><p class="first"><code class="docutils literal"><span class="pre">@InputFunction</span></code>:</p>
<p>The <code class="docutils literal"><span class="pre">@InputFunction</span></code> annotation declares the function which accepts input
rows and stores them in the <code class="docutils literal"><span class="pre">AccumulatorState</span></code>. Similar to scalar functions
you must annotate the arguments with <code class="docutils literal"><span class="pre">@SqlType</span></code>. Note that, unlike in the above
scalar example where <code class="docutils literal"><span class="pre">Slice</span></code> is used to hold <code class="docutils literal"><span class="pre">VARCHAR</span></code>, the primitive
<code class="docutils literal"><span class="pre">double</span></code> type is used for the argument to input. In this example, the input
function simply keeps track of the running count of rows (via <code class="docutils literal"><span class="pre">setLong()</span></code>)
and the running sum (via <code class="docutils literal"><span class="pre">setDouble()</span></code>).</p>
</li>
<li><p class="first"><code class="docutils literal"><span class="pre">@CombineFunction</span></code>:</p>
<p>The <code class="docutils literal"><span class="pre">@CombineFunction</span></code> annotation declares the function used to combine two
state objects. This function is used to merge all the partial aggregation states.
It takes two state objects, and merges the results into the first one (in the
above example, just by adding them together).</p>
</li>
<li><p class="first"><code class="docutils literal"><span class="pre">@OutputFunction</span></code>:</p>
<p>The <code class="docutils literal"><span class="pre">@OutputFunction</span></code> is the last function called when computing an
aggregation. It takes the final state object (the result of merging all
partial states) and writes the result to a <code class="docutils literal"><span class="pre">BlockBuilder</span></code>.</p>
</li>
<li><p class="first">Where does serialization happen, and what is <code class="docutils literal"><span class="pre">GroupedAccumulatorState</span></code>?</p>
<p>The <code class="docutils literal"><span class="pre">@InputFunction</span></code> is usually run on a different worker from the
<code class="docutils literal"><span class="pre">@CombineFunction</span></code>, so the state objects are serialized and transported
between these workers by the aggregation framework. <code class="docutils literal"><span class="pre">GroupedAccumulatorState</span></code>
is used when performing a <code class="docutils literal"><span class="pre">GROUP</span> <span class="pre">BY</span></code> aggregation, and an implementation
will be automatically generated for you, if you don’t specify a
<code class="docutils literal"><span class="pre">AccumulatorStateFactory</span></code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="bottomnav">
<p class="nav">
<span class="left">
« <a href="types.html">10.4. Types</a>
</span>
<span class="right">
<a href="system-access-control.html">10.6. System Access Control</a> »
</span>
</p>
</div>
<div class="footer" role="contentinfo">
</div>
</body>
</html>