<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight text %}
RAND(seed integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive) with a initial seed. Two RAND functions will return identical sequences of numbers if they have same initial seed.</p>
</td>
</tr>
<tr>
<td>
{% highlight text %}
RAND_INTEGER(bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom integer value between 0.0 (inclusive) and the specified value (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight text %}
RAND_INTEGER(seed integer, bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom integer value between 0.0 (inclusive) and the specified value (exclusive) with a initial seed. Two RAND_INTEGER functions will return identical sequences of numbers if they have same initial seed and same bound.</p>
>>>>>>> support RAND and RAND_INTEGER on TableAPI, update the documentation:docs/dev/table_api.md
// Bounded Event-time Row-count over window (assuming an event-time attribute "rowtime")
.window(Over partitionBy 'a orderBy 'rowtime preceding 10.rows as 'w)
...
...
@@ -2071,6 +2067,50 @@ pi()
<p>Returns a value that is closer than any other value to pi.</p>
</td>
</tr>
<tr>
<td>
{% highlight java %}
rand()
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight java %}
rand(seed integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive) with a initial seed. Two rand functions will return identical sequences of numbers if they have same initial seed.</p>
</td>
</tr>
<tr>
<td>
{% highlight java %}
randInteger(bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom integer value between 0.0 (inclusive) and the specified value (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight java %}
randInteger(seed integer, bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom integer value between 0.0 (inclusive) and the specified value (exclusive) with a initial seed. Two randInteger functions will return identical sequences of numbers if they have same initial seed and same bound.</p>
</td>
</tr>
</tbody>
</table>
...
...
@@ -3280,6 +3320,50 @@ pi()
</td>
</tr>
<tr>
<td>
{% highlight scala %}
rand()
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight scala %}
rand(seed integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive) with a initial seed. Two rand functions will return identical sequences of numbers if they have same initial seed.</p>
</td>
</tr>
<tr>
<td>
{% highlight scala %}
randInteger(bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom integer value between 0.0 (inclusive) and the specified value (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight scala %}
randInteger(seed integer, bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom integer value between 0.0 (inclusive) and the specified value (exclusive) with a initial seed. Two randInteger functions will return identical sequences of numbers if they have same initial seed and same bound.</p>
<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight text %}
RAND(seed integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom double value between 0.0 (inclusive) and 1.0 (exclusive) with a initial seed. Two RAND functions will get identical sequences of numbers if they have same initial seed.</p>
</td>
</tr>
<tr>
<td>
{% highlight text %}
RAND_INTEGER(bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom int value between 0.0 (inclusive) and the specified value (exclusive).</p>
</td>
</tr>
<tr>
<td>
{% highlight text %}
RAND_INTEGER(seed integer, bound integer)
{% endhighlight %}
</td>
<td>
<p>Returns a pseudorandom int value between 0.0 (inclusive) and the specified value (exclusive) with a initial seed. Two RAND_INTEGER functions will get identical sequences of numbers if they have same initial seed and same bound.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% top %}
User-defined Functions
----------------
### User-defined Scalar Functions
If a required scalar function is not contained in the built-in functions, it is possible to define custom, user-defined scalar functions for both the Table API and SQL. A user-defined scalar functions maps zero, one, or multiple scalar values to a new scalar value.
In order to define a scalar function one has to extend the base class `ScalarFunction` in `org.apache.flink.table.functions` and implement (one or more) evaluation methods. The behavior of a scalar function is determined by the evaluation method. An evaluation method must be declared publicly and named `eval`. The parameter types and return type of the evaluation method also determine the parameter and return types of the scalar function. Evaluation methods can also be overloaded by implementing multiple methods named `eval`.
The following example shows how to define your own hash code function, register it in the TableEnvironment, and call it in a query. Note that you can configure your scalar function via a constructor before it is registered:
tableEnv.sql("SELECT string, HASHCODE(string) FROM MyTable");
{% endhighlight %}
</div>
<divdata-lang="scala"markdown="1">
{% highlight scala %}
// must be defined in static/object context
class HashCode(factor: Int) extends ScalarFunction {
def eval(s: String): Int = {
s.hashCode() * factor
}
}
val tableEnv = TableEnvironment.getTableEnvironment(env)
// use the function in Scala Table API
val hashCode = new HashCode(10)
myTable.select('string, hashCode('string))
// register and use the function in SQL
tableEnv.registerFunction("hashCode", new HashCode(10))
tableEnv.sql("SELECT string, HASHCODE(string) FROM MyTable");
{% endhighlight %}
</div>
</div>
By default the result type of an evaluation method is determined by Flink's type extraction facilities. This is sufficient for basic types or simple POJOs but might be wrong for more complex, custom, or composite types. In these cases `TypeInformation` of the result type can be manually defined by overriding `ScalarFunction#getResultType()`.
Internally, the Table API and SQL code generation works with primitive values as much as possible. If a user-defined scalar function should not introduce much overhead through object creation/casting during runtime, it is recommended to declare parameters and result types as primitive types instead of their boxed classes. `Types.DATE` and `Types.TIME` can also be represented as `int`. `Types.TIMESTAMP` can be represented as `long`.
The following example shows an advanced example which takes the internal timestamp representation and also returns the internal timestamp representation as a long value. By overriding `ScalarFunction#getResultType()` we define that the returned long value should be interpreted as a `Types.TIMESTAMP` by the code generation.
<divclass="codetabs"markdown="1">
<divdata-lang="java"markdown="1">
{% highlight java %}
public static class TimestampModifier extends ScalarFunction {
public long eval(long t) {
return t % 1000;
}
public TypeInformation<?> getResultType(signature: Class<?>[]) {
Similar to a user-defined scalar function, a user-defined table function takes zero, one, or multiple scalar values as input parameters. However in contrast to a scalar function, it can return an arbitrary number of rows as output instead of a single value. The returned rows may consist of one or more columns.
In order to define a table function one has to extend the base class `TableFunction` in `org.apache.flink.table.functions` and implement (one or more) evaluation methods. The behavior of a table function is determined by its evaluation methods. An evaluation method must be declared `public` and named `eval`. The `TableFunction` can be overloaded by implementing multiple methods named `eval`. The parameter types of the evaluation methods determine all valid parameters of the table function. The type of the returned table is determined by the generic type of `TableFunction`. Evaluation methods emit output rows using the protected `collect(T)` method.
In the Table API, a table function is used with `.join(Expression)` or `.leftOuterJoin(Expression)` for Scala users and `.join(String)` or `.leftOuterJoin(String)` for Java users. The `join` operator (cross) joins each row from the outer table (table on the left of the operator) with all rows produced by the table-valued function (which is on the right side of the operator). The `leftOuterJoin` operator joins each row from the outer table (table on the left of the operator) with all rows produced by the table-valued function (which is on the right side of the operator) and preserves outer rows for which the table function returns an empty table. In SQL use `LATERAL TABLE(<TableFunction>)` with CROSS JOIN and LEFT JOIN with an ON TRUE join condition (see examples below).
The following example shows how to define table-valued function, register it in the TableEnvironment, and call it in a query. Note that you can configure your table function via a constructor before it is registered:
<divclass="codetabs"markdown="1">
<divdata-lang="java"markdown="1">
{% highlight java %}
// The generic type "Tuple2<String,Integer>" determines the schema of the returned table as (String, Integer).
public class Split extends TableFunction<Tuple2<String,Integer>> {
val tableEnv = TableEnvironment.getTableEnvironment(env)
val myTable = ... // table schema: [a: String]
// Use the table function in the Scala Table API (Note: No registration required in Scala Table API).
val split = new Split("#")
// "as" specifies the field names of the generated table.
myTable.join(split('a) as ('word, 'length)).select('a, 'word, 'length);
myTable.leftOuterJoin(split('a) as ('word, 'length)).select('a, 'word, 'length);
// Register the table function to use it in SQL queries.
tableEnv.registerFunction("split", new Split("#"))
// Use the table function in SQL with LATERAL and TABLE keywords.
// CROSS JOIN a table function (equivalent to "join" in Table API)
tableEnv.sql("SELECT a, word, length FROM MyTable, LATERAL TABLE(split(a)) as T(word, length)");
// LEFT JOIN a table function (equivalent to "leftOuterJoin" in Table API)
tableEnv.sql("SELECT a, word, length FROM MyTable LEFT JOIN TABLE(split(a)) as T(word, length) ON TRUE");
{% endhighlight %}
**IMPORTANT:** Do not implement TableFunction as a Scala object. Scala object is a singleton and will cause concurrency issues.
</div>
</div>
Please note that POJO types do not have a deterministic field order. Therefore, you cannot rename the fields of POJO returned by a table function using `AS`.
>>>>>>> support RAND and RAND_INTEGER on TableAPI, update the documentation:docs/dev/table_api.md