You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by tw...@apache.org on 2018/08/14 09:42:06 UTC
[flink] branch master updated (047a85b -> 2f16894)
This is an automated email from the ASF dual-hosted git repository.
twalthr pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git.
from 047a85b Fix Javadoc links in documentation
new ab1d1df [FLINK-9853] [table] Add HEX support for Table API & SQL
new 2f16894 [hotfix] [table] [docs] Improvements for the functions documentation
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
docs/dev/table/functions.md | 174 ++++++++++++++++++++-
docs/dev/table/sql.md | 119 +-------------
docs/dev/table/tableApi.md | 7 +-
.../flink/table/api/scala/expressionDsl.scala | 9 ++
.../flink/table/codegen/calls/BuiltInMethods.scala | 4 +
.../table/codegen/calls/FunctionGenerator.scala | 12 ++
.../flink/table/expressions/mathExpressions.scala | 18 +++
.../table/functions/sql/ScalarSqlFunctions.scala | 9 ++
.../table/runtime/functions/ScalarFunctions.scala | 16 +-
.../flink/table/validate/FunctionCatalog.scala | 2 +
.../table/expressions/ScalarFunctionsTest.scala | 93 +++++++++++
11 files changed, 338 insertions(+), 125 deletions(-)
[flink] 01/02: [FLINK-9853] [table] Add HEX support for Table API &
SQL
Posted by tw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
twalthr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
commit ab1d1dfb2ad872748833896d552e2d56a26a9a92
Author: xueyu <27...@qq.com>
AuthorDate: Sun Jul 15 20:01:15 2018 +0800
[FLINK-9853] [table] Add HEX support for Table API & SQL
This closes #6337.
---
docs/dev/table/functions.md | 39 +++++++++
.../flink/table/api/scala/expressionDsl.scala | 9 +++
.../flink/table/codegen/calls/BuiltInMethods.scala | 4 +
.../table/codegen/calls/FunctionGenerator.scala | 12 +++
.../flink/table/expressions/mathExpressions.scala | 18 +++++
.../table/functions/sql/ScalarSqlFunctions.scala | 9 +++
.../table/runtime/functions/ScalarFunctions.scala | 16 +++-
.../flink/table/validate/FunctionCatalog.scala | 2 +
.../table/expressions/ScalarFunctionsTest.scala | 93 ++++++++++++++++++++++
9 files changed, 199 insertions(+), 3 deletions(-)
diff --git a/docs/dev/table/functions.md b/docs/dev/table/functions.md
index 00a9605..f637b4d 100644
--- a/docs/dev/table/functions.md
+++ b/docs/dev/table/functions.md
@@ -1393,6 +1393,19 @@ BIN(integer)
<p>E.g. <code>BIN(4)</code> returns '100' and <code>BIN(12)</code> returns '1100'.</p>
</td>
</tr>
+
+ <tr>
+ <td>
+{% highlight text %}
+HEX(numeric)
+HEX(string)
+ {% endhighlight %}
+ </td>
+ <td>
+ <p>Returns a string representation of an integer <i>numeric</i> value or a <i>string</i> in hex format. Returns NULL if the argument is NULL.</p>
+ <p>E.g. a numeric 20 leads to "14", a numeric 100 leads to "64", a string "hello,world" leads to "68656C6C6F2C776F726C64".</p>
+ </td>
+ </tr>
</tbody>
</table>
</div>
@@ -1805,6 +1818,19 @@ INTEGER.bin()
<p>E.g., <code>4.bin()</code> returns "100" and <code>12.bin()</code> returns "1100".</p>
</td>
</tr>
+
+ <tr>
+ <td>
+ {% highlight java %}
+NUMERIC.hex()
+STRING.hex()
+{% endhighlight %}
+ </td>
+ <td>
+ <p>Returns a string representation of an integer <i>NUMERIC</i> value or a <i>STRING</i> in hex format. Returns NULL if the argument is NULL.</p>
+ <p>E.g. a numeric 20 leads to "14", a numeric 100 leads to "64", a string "hello,world" leads to "68656C6C6F2C776F726C64".</p>
+ </td>
+ </tr>
</tbody>
</table>
</div>
@@ -2217,6 +2243,19 @@ INTEGER.bin()
<p>E.g., <code>4.bin()</code> returns "100" and <code>12.bin()</code> returns "1100".</p>
</td>
</tr>
+
+ <tr>
+ <td>
+ {% highlight scala %}
+NUMERIC.hex()
+STRING.hex()
+{% endhighlight %}
+ </td>
+ <td>
+ <p>Returns a string representation of an integer <i>NUMERIC</i> value or a <i>STRING</i> in hex format. Returns NULL if the argument is NULL.</p>
+ <p>E.g. a numeric 20 leads to "14", a numeric 100 leads to "64", a string "hello,world" leads to "68656C6C6F2C776F726C64".</p>
+ </td>
+ </tr>
</tbody>
</table>
</div>
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/api/scala/expressionDsl.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/api/scala/expressionDsl.scala
index d1bb06c..66e7544 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/api/scala/expressionDsl.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/api/scala/expressionDsl.scala
@@ -406,6 +406,15 @@ trait ImplicitExpressionOperations {
*/
def bin() = Bin(expr)
+ /**
+ * Returns a string representation of an integer numeric value or a string in hex format. Returns
+ * null if numeric or string is null.
+ *
+ * E.g. a numeric 20 leads to "14", a numeric 100 leads to "64", and a string "hello,world" leads
+ * to "68656c6c6f2c776f726c64".
+ */
+ def hex() = Hex(expr)
+
// String operations
/**
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/BuiltInMethods.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/BuiltInMethods.scala
index f5ed9b3..942666a 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/BuiltInMethods.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/BuiltInMethods.scala
@@ -17,6 +17,7 @@
*/
package org.apache.flink.table.codegen.calls
+import java.lang.reflect.Method
import java.lang.{Long => JLong}
import java.math.{BigDecimal => JBigDecimal}
@@ -135,4 +136,7 @@ object BuiltInMethods {
val FROMBASE64 = Types.lookupMethod(classOf[ScalarFunctions], "fromBase64", classOf[String])
val TOBASE64 = Types.lookupMethod(classOf[ScalarFunctions], "toBase64", classOf[String])
+
+ val HEX_LONG: Method = Types.lookupMethod(classOf[ScalarFunctions], "hex", classOf[Long])
+ val HEX_STRING: Method = Types.lookupMethod(classOf[ScalarFunctions], "hex", classOf[String])
}
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
index 74b69d6..fd71126 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
@@ -455,6 +455,18 @@ object FunctionGenerator {
STRING_TYPE_INFO,
BuiltInMethods.BIN)
+ addSqlFunctionMethod(
+ ScalarSqlFunctions.HEX,
+ Seq(LONG_TYPE_INFO),
+ STRING_TYPE_INFO,
+ BuiltInMethods.HEX_LONG)
+
+ addSqlFunctionMethod(
+ ScalarSqlFunctions.HEX,
+ Seq(STRING_TYPE_INFO),
+ STRING_TYPE_INFO,
+ BuiltInMethods.HEX_STRING)
+
// ----------------------------------------------------------------------------------------------
// Temporal functions
// ----------------------------------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/mathExpressions.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/mathExpressions.scala
index cf3efa9..13e005e 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/mathExpressions.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/mathExpressions.scala
@@ -422,3 +422,21 @@ case class Bin(child: Expression) extends UnaryExpression {
relBuilder.call(ScalarSqlFunctions.BIN, child.toRexNode)
}
}
+
+case class Hex(child: Expression) extends UnaryExpression {
+ override private[flink] def resultType: TypeInformation[_] = BasicTypeInfo.STRING_TYPE_INFO
+
+ override private[flink] def validateInput(): ValidationResult = {
+ if (TypeCheckUtils.isIntegerFamily(child.resultType) ||
+ TypeCheckUtils.isString(child.resultType)) {
+ ValidationSuccess
+ } else {
+ ValidationFailure(s"hex() requires an integer or string input but was '${child.resultType}'.")
+ }
+ }
+ override def toString: String = s"hex($child)"
+
+ override private[flink] def toRexNode(implicit relBuilder: RelBuilder): RexNode = {
+ relBuilder.call(ScalarSqlFunctions.HEX, child.toRexNode)
+ }
+}
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/functions/sql/ScalarSqlFunctions.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/functions/sql/ScalarSqlFunctions.scala
index 21793e3..a0b6c9c 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/functions/sql/ScalarSqlFunctions.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/functions/sql/ScalarSqlFunctions.scala
@@ -42,6 +42,15 @@ object ScalarSqlFunctions {
OperandTypes.family(SqlTypeFamily.INTEGER),
SqlFunctionCategory.NUMERIC)
+ val HEX = new SqlFunction(
+ "HEX",
+ SqlKind.OTHER_FUNCTION,
+ ReturnTypes.cascade(ReturnTypes.explicit(SqlTypeName.VARCHAR), SqlTypeTransforms.TO_NULLABLE),
+ InferTypes.RETURN_TYPE,
+ OperandTypes.or(OperandTypes.family(SqlTypeFamily.INTEGER),
+ OperandTypes.family(SqlTypeFamily.STRING)),
+ SqlFunctionCategory.NUMERIC)
+
val CONCAT = new SqlFunction(
"CONCAT",
SqlKind.OTHER_FUNCTION,
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/runtime/functions/ScalarFunctions.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/runtime/functions/ScalarFunctions.scala
index 03ee62c..1881874 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/runtime/functions/ScalarFunctions.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/runtime/functions/ScalarFunctions.scala
@@ -17,11 +17,12 @@
*/
package org.apache.flink.table.runtime.functions
-import scala.annotation.varargs
+import java.lang.{StringBuilder, Long => JLong}
import java.math.{BigDecimal => JBigDecimal}
-import java.lang.StringBuilder
-import org.apache.commons.codec.binary.Base64
+import org.apache.commons.codec.binary.{Base64, Hex}
+
+import scala.annotation.varargs
/**
* Built-in scalar runtime functions.
@@ -212,4 +213,13 @@ object ScalarFunctions {
*/
def toBase64(base: String): String = Base64.encodeBase64String(base.getBytes())
+ /**
+ * Returns the hex string of a long argument.
+ */
+ def hex(x: Long): String = JLong.toHexString(x).toUpperCase()
+
+ /**
+ * Returns the hex string of a string argument.
+ */
+ def hex(x: String): String = Hex.encodeHexString(x.getBytes).toUpperCase()
}
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/validate/FunctionCatalog.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/validate/FunctionCatalog.scala
index bca156c..a446401 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/validate/FunctionCatalog.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/validate/FunctionCatalog.scala
@@ -239,6 +239,7 @@ object FunctionCatalog {
"rand" -> classOf[Rand],
"randInteger" -> classOf[RandInteger],
"bin" -> classOf[Bin],
+ "hex" -> classOf[Hex],
// temporal functions
"extract" -> classOf[Extract],
@@ -438,6 +439,7 @@ class BasicOperatorTable extends ReflectiveSqlOperatorTable {
ScalarSqlFunctions.CONCAT,
ScalarSqlFunctions.CONCAT_WS,
ScalarSqlFunctions.BIN,
+ ScalarSqlFunctions.HEX,
SqlStdOperatorTable.TIMESTAMP_ADD,
ScalarSqlFunctions.LOG,
ScalarSqlFunctions.LPAD,
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarFunctionsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarFunctionsTest.scala
index 6f9a9ae..8e85b34 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarFunctionsTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarFunctionsTest.scala
@@ -393,6 +393,99 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
}
@Test
+ def testHex(): Unit = {
+ testAllApis(
+ 100.hex(),
+ "100.hex()",
+ "HEX(100)",
+ "64")
+
+ testAllApis(
+ 'f2.hex(),
+ "f2.hex()",
+ "HEX(f2)",
+ "2A")
+
+ testAllApis(
+ Null(Types.BYTE).hex(),
+ "hex(Null(BYTE))",
+ "HEX(CAST(NULL AS TINYINT))",
+ "null")
+
+ testAllApis(
+ 'f3.hex(),
+ "f3.hex()",
+ "HEX(f3)",
+ "2B")
+
+ testAllApis(
+ 'f4.hex(),
+ "f4.hex()",
+ "HEX(f4)",
+ "2C")
+
+ testAllApis(
+ 'f7.hex(),
+ "f7.hex()",
+ "HEX(f7)",
+ "3")
+
+ testAllApis(
+ 12.hex(),
+ "12.hex()",
+ "HEX(12)",
+ "C")
+
+ testAllApis(
+ 10.hex(),
+ "10.hex()",
+ "HEX(10)",
+ "A")
+
+ testAllApis(
+ 0.hex(),
+ "0.hex()",
+ "HEX(0)",
+ "0")
+
+ testAllApis(
+ "ö".hex(),
+ "'ö'.hex()",
+ "HEX('ö')",
+ "C3B6")
+
+ testAllApis(
+ 'f32.hex(),
+ "f32.hex()",
+ "HEX(f32)",
+ "FFFFFFFFFFFFFFFF")
+
+ testAllApis(
+ 'f0.hex(),
+ "f0.hex()",
+ "HEX(f0)",
+ "546869732069732061207465737420537472696E672E")
+
+ testAllApis(
+ 'f8.hex(),
+ "f8.hex()",
+ "HEX(f8)",
+ "20546869732069732061207465737420537472696E672E20")
+
+ testAllApis(
+ 'f23.hex(),
+ "f23.hex()",
+ "HEX(f23)",
+ "25546869732069732061207465737420537472696E672E")
+
+ testAllApis(
+ 'f24.hex(),
+ "f24.hex()",
+ "HEX(f24)",
+ "2A5F546869732069732061207465737420537472696E672E")
+ }
+
+ @Test
def testBin(): Unit = {
testAllApis(
[flink] 02/02: [hotfix] [table] [docs] Improvements for the
functions documentation
Posted by tw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
twalthr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
commit 2f1689477a8b5de898e834deb5865ff68b3032a3
Author: Timo Walther <tw...@apache.org>
AuthorDate: Tue Aug 14 11:39:28 2018 +0200
[hotfix] [table] [docs] Improvements for the functions documentation
---
docs/dev/table/functions.md | 135 +++++++++++++++++++++++++++++++++++++++++---
docs/dev/table/sql.md | 119 ++------------------------------------
docs/dev/table/tableApi.md | 7 ++-
3 files changed, 139 insertions(+), 122 deletions(-)
diff --git a/docs/dev/table/functions.md b/docs/dev/table/functions.md
index f637b4d..cf42bfa 100644
--- a/docs/dev/table/functions.md
+++ b/docs/dev/table/functions.md
@@ -1,7 +1,7 @@
---
title: "Built-In Functions"
nav-parent_id: tableapi
-nav-pos: 45
+nav-pos: 31
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
@@ -30,7 +30,8 @@ If you think that the function is general enough, please <a href="https://issues
{:toc}
Scalar Functions
------------------------------
+----------------
+
The scalar functions take zero, one or more values as the input and return a single value as the result.
### Comparison Functions
@@ -3127,7 +3128,7 @@ DATE_FORMAT(timestamp, string)
{% endhighlight %}
</td>
<td>
- <p>Returns a string that formats <i>timestamp</i> with a specified format <i>string</i>. The format specification is given in the <a href="sql.html#date-format-specifier">Date Format Specifier table</a>.</p>
+ <p>Returns a string that formats <i>timestamp</i> with a specified format <i>string</i>. The format specification is given in the <a href="#date-format-specifiers">Date Format Specifier table</a>.</p>
</td>
</tr>
@@ -3383,7 +3384,7 @@ dateFormat(TIMESTAMP, STRING)
{% endhighlight %}
</td>
<td>
- <p>Returns a string that formats <i>TIMESTAMP</i> with a specified format <i>STRING</i>. The format specification is given in the <a href="sql.html#date-format-specifier">Date Format Specifier table</a>.</p>
+ <p>Returns a string that formats <i>TIMESTAMP</i> with a specified format <i>STRING</i>. The format specification is given in the <a href="#date-format-specifiers">Date Format Specifier table</a>.</p>
<p>E.g., <code>dateFormat(ts, '%Y, %d %M')</code> results in strings formatted as "2017, 05 May".</p>
</td>
</tr>
@@ -3628,7 +3629,7 @@ dateFormat(TIMESTAMP, STRING)
{% endhighlight %}
</td>
<td>
- <p>Returns a string that formats <i>TIMESTAMP</i> with a specified format <i>STRING</i>. The format specification is given in the <a href="sql.html#date-format-specifier">Date Format Specifier table</a>.</p>
+ <p>Returns a string that formats <i>TIMESTAMP</i> with a specified format <i>STRING</i>. The format specification is given in the <a href="#date-format-specifiers">Date Format Specifier table</a>.</p>
<p>E.g., <code>dateFormat('ts, "%Y, %d %M")</code> results in strings formatted as "2017, 05 May".</p>
</td>
</tr>
@@ -3811,7 +3812,7 @@ ANY.cast(TYPE)
{% endhighlight %}
</td>
<td>
- <p>Returns a new <i>ANY</i> being cast to type <i>TYPE</i>. See the supported types <a href="sql.html#data-types">here</a>.</p>
+ <p>Returns a new <i>ANY</i> being cast to type <i>TYPE</i>. See the supported types <a href="tableApi.html#data-types">here</a>.</p>
<p>E.g., <code>'42'.cast(INT)</code> returns 42.</p>
</td>
</tr>
@@ -3836,7 +3837,7 @@ ANY.cast(TYPE)
{% endhighlight %}
</td>
<td>
- <p>Returns a new <i>ANY</i> being cast to type <i>TYPE</i>. See the supported types <a href="sql.html#data-types">here</a>.</p>
+ <p>Returns a new <i>ANY</i> being cast to type <i>TYPE</i>. See the supported types <a href="tableApi.html#data-types">here</a>.</p>
<p>E.g., <code>"42".cast(Types.INT)</code> returns 42.</p>
</td>
</tr>
@@ -4759,7 +4760,8 @@ ANY.as(NAME1, NAME2, ...)
</div>
Aggregate Functions
------------------------------
+-------------------
+
The aggregate functions take an expression across all the rows as the input and return a single aggregated value as the result.
<div class="codetabs" markdown="1">
@@ -5168,3 +5170,120 @@ FIELD.collect
</div>
{% top %}
+
+Date Format Specifiers
+----------------------
+
+The following table lists specifiers for date format functions.
+
+<table class="table table-bordered">
+ <thead>
+ <tr>
+ <th class="text-left" style="width: 40%">Specifier</th>
+ <th class="text-center">Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td>{% highlight text %}%a{% endhighlight %}</td>
+ <td>Abbreviated weekday name (<code>Sun</code> .. <code>Sat</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%b{% endhighlight %}</td>
+ <td>Abbreviated month name (<code>Jan</code> .. <code>Dec</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%c{% endhighlight %}</td>
+ <td>Month, numeric (<code>1</code> .. <code>12</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%D{% endhighlight %}</td>
+ <td>Day of the month with English suffix (<code>0th</code>, <code>1st</code>, <code>2nd</code>, <code>3rd</code>, ...)</td>
+ </tr>
+ <tr><td>{% highlight text %}%d{% endhighlight %}</td>
+ <td>Day of the month, numeric (<code>01</code> .. <code>31</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%e{% endhighlight %}</td>
+ <td>Day of the month, numeric (<code>1</code> .. <code>31</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%f{% endhighlight %}</td>
+ <td>Fraction of second (6 digits for printing: <code>000000</code> .. <code>999000</code>; 1 - 9 digits for parsing: <code>0</code> .. <code>999999999</code>) (Timestamp is truncated to milliseconds.) </td>
+ </tr>
+ <tr><td>{% highlight text %}%H{% endhighlight %}</td>
+ <td>Hour (<code>00</code> .. <code>23</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%h{% endhighlight %}</td>
+ <td>Hour (<code>01</code> .. <code>12</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%I{% endhighlight %}</td>
+ <td>Hour (<code>01</code> .. <code>12</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%i{% endhighlight %}</td>
+ <td>Minutes, numeric (<code>00</code> .. <code>59</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%j{% endhighlight %}</td>
+ <td>Day of year (<code>001</code> .. <code>366</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%k{% endhighlight %}</td>
+ <td>Hour (<code>0</code> .. <code>23</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%l{% endhighlight %}</td>
+ <td>Hour (<code>1</code> .. <code>12</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%M{% endhighlight %}</td>
+ <td>Month name (<code>January</code> .. <code>December</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%m{% endhighlight %}</td>
+ <td>Month, numeric (<code>01</code> .. <code>12</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%p{% endhighlight %}</td>
+ <td><code>AM</code> or <code>PM</code></td>
+ </tr>
+ <tr><td>{% highlight text %}%r{% endhighlight %}</td>
+ <td>Time, 12-hour (<code>hh:mm:ss</code> followed by <code>AM</code> or <code>PM</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%S{% endhighlight %}</td>
+ <td>Seconds (<code>00</code> .. <code>59</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%s{% endhighlight %}</td>
+ <td>Seconds (<code>00</code> .. <code>59</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%T{% endhighlight %}</td>
+ <td>Time, 24-hour (<code>hh:mm:ss</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%U{% endhighlight %}</td>
+ <td>Week (<code>00</code> .. <code>53</code>), where Sunday is the first day of the week</td>
+ </tr>
+ <tr><td>{% highlight text %}%u{% endhighlight %}</td>
+ <td>Week (<code>00</code> .. <code>53</code>), where Monday is the first day of the week</td>
+ </tr>
+ <tr><td>{% highlight text %}%V{% endhighlight %}</td>
+ <td>Week (<code>01</code> .. <code>53</code>), where Sunday is the first day of the week; used with <code>%X</code></td>
+ </tr>
+ <tr><td>{% highlight text %}%v{% endhighlight %}</td>
+ <td>Week (<code>01</code> .. <code>53</code>), where Monday is the first day of the week; used with <code>%x</code></td>
+ </tr>
+ <tr><td>{% highlight text %}%W{% endhighlight %}</td>
+ <td>Weekday name (<code>Sunday</code> .. <code>Saturday</code>)</td>
+ </tr>
+ <tr><td>{% highlight text %}%w{% endhighlight %}</td>
+ <td>Day of the week (<code>0</code> .. <code>6</code>), where Sunday is the first day of the week</td>
+ </tr>
+ <tr><td>{% highlight text %}%X{% endhighlight %}</td>
+ <td>Year for the week where Sunday is the first day of the week, numeric, four digits; used with <code>%V</code></td>
+ </tr>
+ <tr><td>{% highlight text %}%x{% endhighlight %}</td>
+ <td>Year for the week, where Monday is the first day of the week, numeric, four digits; used with <code>%v</code></td>
+ </tr>
+ <tr><td>{% highlight text %}%Y{% endhighlight %}</td>
+ <td>Year, numeric, four digits</td>
+ </tr>
+ <tr><td>{% highlight text %}%y{% endhighlight %}</td>
+ <td>Year, numeric (two digits) </td>
+ </tr>
+ <tr><td>{% highlight text %}%%{% endhighlight %}</td>
+ <td>A literal <code>%</code> character</td>
+ </tr>
+ <tr><td>{% highlight text %}%x{% endhighlight %}</td>
+ <td><code>x</code>, for any <code>x</code> not listed above</td>
+ </tr>
+ </tbody>
+</table>
+
+{% top %}
diff --git a/docs/dev/table/sql.md b/docs/dev/table/sql.md
index 60f07ef..604e989 100644
--- a/docs/dev/table/sql.md
+++ b/docs/dev/table/sql.md
@@ -891,8 +891,13 @@ The SQL runtime is built on top of Flink's DataSet and DataStream APIs. Internal
| `Types.OBJECT_ARRAY` | `ARRAY` | e.g. `java.lang.Byte[]`|
| `Types.MAP` | `MAP` | `java.util.HashMap` |
| `Types.MULTISET` | `MULTISET` | e.g. `java.util.HashMap<String, Integer>` for a multiset of `String` |
+| `Types.ROW` | `ROW` | `org.apache.flink.types.Row` |
-Generic types and composite types (e.g., POJOs or Tuples) can be fields of a row as well. Generic types are treated as a black box and can be passed on or processed by [user-defined functions](udfs.html). Composite types can be accessed with [built-in functions](#built-in-functions) (see *Value access functions* section).
+Generic types and (nested) composite types (e.g., POJOs, tuples, rows, Scala case classes) can be fields of a row as well.
+
+Fields of composite types with arbitrary nesting can be accessed with [value access functions](functions.html#value-access-functions).
+
+Generic types are treated as a black box and can be passed on or processed by [user-defined functions](udfs.html).
{% top %}
@@ -907,117 +912,5 @@ A, ABS, ABSOLUTE, ACTION, ADA, ADD, ADMIN, AFTER, ALL, ALLOCATE, ALLOW, ALTER, A
{% endhighlight %}
-#### Date Format Specifier
-
-<table class="table table-bordered">
- <thead>
- <tr>
- <th class="text-left" style="width: 40%">Specifier</th>
- <th class="text-center">Description</th>
- </tr>
- </thead>
- <tbody>
- <tr><td>{% highlight text %}%a{% endhighlight %}</td>
- <td>Abbreviated weekday name (<code>Sun</code> .. <code>Sat</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%b{% endhighlight %}</td>
- <td>Abbreviated month name (<code>Jan</code> .. <code>Dec</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%c{% endhighlight %}</td>
- <td>Month, numeric (<code>1</code> .. <code>12</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%D{% endhighlight %}</td>
- <td>Day of the month with English suffix (<code>0th</code>, <code>1st</code>, <code>2nd</code>, <code>3rd</code>, ...)</td>
- </tr>
- <tr><td>{% highlight text %}%d{% endhighlight %}</td>
- <td>Day of the month, numeric (<code>01</code> .. <code>31</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%e{% endhighlight %}</td>
- <td>Day of the month, numeric (<code>1</code> .. <code>31</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%f{% endhighlight %}</td>
- <td>Fraction of second (6 digits for printing: <code>000000</code> .. <code>999000</code>; 1 - 9 digits for parsing: <code>0</code> .. <code>999999999</code>) (Timestamp is truncated to milliseconds.) </td>
- </tr>
- <tr><td>{% highlight text %}%H{% endhighlight %}</td>
- <td>Hour (<code>00</code> .. <code>23</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%h{% endhighlight %}</td>
- <td>Hour (<code>01</code> .. <code>12</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%I{% endhighlight %}</td>
- <td>Hour (<code>01</code> .. <code>12</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%i{% endhighlight %}</td>
- <td>Minutes, numeric (<code>00</code> .. <code>59</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%j{% endhighlight %}</td>
- <td>Day of year (<code>001</code> .. <code>366</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%k{% endhighlight %}</td>
- <td>Hour (<code>0</code> .. <code>23</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%l{% endhighlight %}</td>
- <td>Hour (<code>1</code> .. <code>12</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%M{% endhighlight %}</td>
- <td>Month name (<code>January</code> .. <code>December</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%m{% endhighlight %}</td>
- <td>Month, numeric (<code>01</code> .. <code>12</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%p{% endhighlight %}</td>
- <td><code>AM</code> or <code>PM</code></td>
- </tr>
- <tr><td>{% highlight text %}%r{% endhighlight %}</td>
- <td>Time, 12-hour (<code>hh:mm:ss</code> followed by <code>AM</code> or <code>PM</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%S{% endhighlight %}</td>
- <td>Seconds (<code>00</code> .. <code>59</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%s{% endhighlight %}</td>
- <td>Seconds (<code>00</code> .. <code>59</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%T{% endhighlight %}</td>
- <td>Time, 24-hour (<code>hh:mm:ss</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%U{% endhighlight %}</td>
- <td>Week (<code>00</code> .. <code>53</code>), where Sunday is the first day of the week</td>
- </tr>
- <tr><td>{% highlight text %}%u{% endhighlight %}</td>
- <td>Week (<code>00</code> .. <code>53</code>), where Monday is the first day of the week</td>
- </tr>
- <tr><td>{% highlight text %}%V{% endhighlight %}</td>
- <td>Week (<code>01</code> .. <code>53</code>), where Sunday is the first day of the week; used with <code>%X</code></td>
- </tr>
- <tr><td>{% highlight text %}%v{% endhighlight %}</td>
- <td>Week (<code>01</code> .. <code>53</code>), where Monday is the first day of the week; used with <code>%x</code></td>
- </tr>
- <tr><td>{% highlight text %}%W{% endhighlight %}</td>
- <td>Weekday name (<code>Sunday</code> .. <code>Saturday</code>)</td>
- </tr>
- <tr><td>{% highlight text %}%w{% endhighlight %}</td>
- <td>Day of the week (<code>0</code> .. <code>6</code>), where Sunday is the first day of the week</td>
- </tr>
- <tr><td>{% highlight text %}%X{% endhighlight %}</td>
- <td>Year for the week where Sunday is the first day of the week, numeric, four digits; used with <code>%V</code></td>
- </tr>
- <tr><td>{% highlight text %}%x{% endhighlight %}</td>
- <td>Year for the week, where Monday is the first day of the week, numeric, four digits; used with <code>%v</code></td>
- </tr>
- <tr><td>{% highlight text %}%Y{% endhighlight %}</td>
- <td>Year, numeric, four digits</td>
- </tr>
- <tr><td>{% highlight text %}%y{% endhighlight %}</td>
- <td>Year, numeric (two digits) </td>
- </tr>
- <tr><td>{% highlight text %}%%{% endhighlight %}</td>
- <td>A literal <code>%</code> character</td>
- </tr>
- <tr><td>{% highlight text %}%x{% endhighlight %}</td>
- <td><code>x</code>, for any <code>x</code> not listed above</td>
- </tr>
- </tbody>
-</table>
-
{% top %}
diff --git a/docs/dev/table/tableApi.md b/docs/dev/table/tableApi.md
index 08ea36d..f8bcd3d 100644
--- a/docs/dev/table/tableApi.md
+++ b/docs/dev/table/tableApi.md
@@ -1577,8 +1577,13 @@ The Table API is built on top of Flink's DataSet and DataStream APIs. Internally
| `Types.OBJECT_ARRAY` | `ARRAY` | e.g. `java.lang.Byte[]`|
| `Types.MAP` | `MAP` | `java.util.HashMap` |
| `Types.MULTISET` | `MULTISET` | e.g. `java.util.HashMap<String, Integer>` for a multiset of `String` |
+| `Types.ROW` | `ROW` | `org.apache.flink.types.Row` |
-Generic types and composite types (e.g., POJOs or Tuples) can be fields of a row as well. Generic types are treated as a black box and can be passed on or processed by [user-defined functions](udfs.html). Composite types can be accessed with [built-in functions](#built-in-functions) (see *Value access functions* section).
+Generic types and (nested) composite types (e.g., POJOs, tuples, rows, Scala case classes) can be fields of a row as well.
+
+Fields of composite types with arbitrary nesting can be accessed with [value access functions](functions.html#value-access-functions).
+
+Generic types are treated as a black box and can be passed on or processed by [user-defined functions](udfs.html).
{% top %}