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/05/15 11:34:28 UTC

[1/2] flink git commit: [FLINK-6926] [table] Add support for SHA-224, SHA-384, SHA-512

Repository: flink
Updated Branches:
  refs/heads/master 33d3b767e -> d5de2bcf1


[FLINK-6926] [table] Add support for SHA-224, SHA-384, SHA-512


Project: http://git-wip-us.apache.org/repos/asf/flink/repo
Commit: http://git-wip-us.apache.org/repos/asf/flink/commit/5544ab5d
Tree: http://git-wip-us.apache.org/repos/asf/flink/tree/5544ab5d
Diff: http://git-wip-us.apache.org/repos/asf/flink/diff/5544ab5d

Branch: refs/heads/master
Commit: 5544ab5df5d805511a40f2e4007b3afee06d15af
Parents: 33d3b76
Author: Michael Gendelman <ge...@gmail.com>
Authored: Sat Jan 13 23:24:08 2018 +0200
Committer: Timo Walther <tw...@apache.org>
Committed: Tue May 15 11:34:33 2018 +0200

----------------------------------------------------------------------
 docs/dev/table/sql.md                           | 33 ++++++++++
 docs/dev/table/tableApi.md                      | 69 +++++++++++++++++++-
 .../flink/table/api/scala/expressionDsl.scala   | 21 ++++++
 .../table/codegen/calls/FunctionGenerator.scala | 18 +++++
 .../table/expressions/hashExpressions.scala     | 39 +++++++++++
 .../functions/sql/ScalarSqlFunctions.scala      | 27 ++++++++
 .../flink/table/validate/FunctionCatalog.scala  |  9 ++-
 .../table/expressions/ScalarFunctionsTest.scala | 49 ++++++++++++--
 .../table/expressions/SqlExpressionTest.scala   | 13 ++++
 9 files changed, 269 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/docs/dev/table/sql.md
----------------------------------------------------------------------
diff --git a/docs/dev/table/sql.md b/docs/dev/table/sql.md
index ce0e1d6..7f4a386 100644
--- a/docs/dev/table/sql.md
+++ b/docs/dev/table/sql.md
@@ -2437,6 +2437,17 @@ SHA1(string)
     <tr>
       <td>
         {% highlight text %}
+SHA224(string)
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-224 hash of the string argument as a string of 56 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>    
+    
+    <tr>
+      <td>
+        {% highlight text %}
 SHA256(string)
 {% endhighlight %}
       </td>
@@ -2444,6 +2455,28 @@ SHA256(string)
         <p>Returns the SHA-256 hash of the string argument as a string of 64 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
     </tr>
+    
+    <tr>
+      <td>
+        {% highlight text %}
+SHA384(string)
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-384 hash of the string argument as a string of 96 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>  
+
+    <tr>
+      <td>
+        {% highlight text %}
+SHA512(string)
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-512 hash of the string argument as a string of 128 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>          
   </tbody>
 </table>
 

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/docs/dev/table/tableApi.md
----------------------------------------------------------------------
diff --git a/docs/dev/table/tableApi.md b/docs/dev/table/tableApi.md
index 69aaeea..05ce604 100644
--- a/docs/dev/table/tableApi.md
+++ b/docs/dev/table/tableApi.md
@@ -3083,7 +3083,18 @@ STRING.sha1()
       </td>
     </tr>
 
-        <tr>
+    <tr>
+      <td>
+        {% highlight java %}
+STRING.sha224()
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-224 hash of the string argument as a string of 56 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>
+
+    <tr>
       <td>
         {% highlight java %}
 STRING.sha256()
@@ -3094,6 +3105,28 @@ STRING.sha256()
       </td>
     </tr>
 
+    <tr>
+      <td>
+        {% highlight java %}
+STRING.sha384()
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-384 hash of the string argument as a string of 96 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td>
+        {% highlight java %}
+STRING.sha512()
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-512 hash of the string argument as a string of 128 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>
+
     </tbody>
 </table>
 
@@ -4529,7 +4562,18 @@ STRING.sha1()
       </td>
     </tr>
 
-        <tr>
+    <tr>
+      <td>
+        {% highlight scala %}
+STRING.sha224()
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-224 hash of the string argument as a string of 56 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>
+
+    <tr>
       <td>
         {% highlight scala %}
 STRING.sha256()
@@ -4539,7 +4583,28 @@ STRING.sha256()
         <p>Returns the SHA-256 hash of the string argument as a string of 64 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
     </tr>
+    
+    <tr>
+      <td>
+        {% highlight scala %}
+STRING.sha384()
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-384 hash of the string argument as a string of 96 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>    
 
+    <tr>
+      <td>
+        {% highlight scala %}
+STRING.sha512()
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the SHA-512 hash of the string argument as a string of 128 hexadecimal digits; null if <i>string</i> is null.</p>
+      </td>
+    </tr>  
     </tbody>
 </table>
 

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/api/scala/expressionDsl.scala
----------------------------------------------------------------------
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 09e7ef9..1494de6 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
@@ -773,11 +773,32 @@ trait ImplicitExpressionOperations {
   def sha1() = Sha1(expr)
 
   /**
+    * Returns the SHA-224 hash of the string argument; null if string is null.
+    *
+    * @return string of 64 hexadecimal digits or null
+    */
+  def sha224() = Sha224(expr)
+
+  /**
     * Returns the SHA-256 hash of the string argument; null if string is null.
     *
     * @return string of 64 hexadecimal digits or null
     */
   def sha256() = Sha256(expr)
+
+  /**
+    * Returns the SHA-384 hash of the string argument; null if string is null.
+    *
+    * @return string of 64 hexadecimal digits or null
+    */
+  def sha384() = Sha384(expr)
+
+  /**
+    * Returns the SHA-512 hash of the string argument; null if string is null.
+    *
+    * @return string of 64 hexadecimal digits or null
+    */
+  def sha512() = Sha512(expr)
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
----------------------------------------------------------------------
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 2cd7388..0f2e986 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
@@ -560,11 +560,29 @@ object FunctionGenerator {
   )
 
   addSqlFunction(
+    ScalarSqlFunctions.SHA224,
+    Seq(STRING_TYPE_INFO),
+    new HashCalcCallGen("SHA-224")
+  )
+
+  addSqlFunction(
     ScalarSqlFunctions.SHA256,
     Seq(STRING_TYPE_INFO),
     new HashCalcCallGen("SHA-256")
   )
 
+  addSqlFunction(
+    ScalarSqlFunctions.SHA384,
+    Seq(STRING_TYPE_INFO),
+    new HashCalcCallGen("SHA-384")
+  )
+
+  addSqlFunction(
+    ScalarSqlFunctions.SHA512,
+    Seq(STRING_TYPE_INFO),
+    new HashCalcCallGen("SHA-512")
+  )
+
   // ----------------------------------------------------------------------------------------------
 
   /**

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
index 2880ad4..59a3635 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
@@ -50,6 +50,19 @@ case class Sha1(child: Expression) extends UnaryExpression with InputTypeSpec {
   }
 }
 
+case class Sha224(child: Expression) extends UnaryExpression with InputTypeSpec {
+
+  override private[flink] def resultType: TypeInformation[_] = STRING_TYPE_INFO
+
+  override private[flink] def expectedTypes: Seq[TypeInformation[_]] = STRING_TYPE_INFO :: Nil
+
+  override def toString: String = s"($child).sha224()"
+
+  override private[flink] def toRexNode(implicit relBuilder: RelBuilder): RexNode = {
+    relBuilder.call(ScalarSqlFunctions.SHA224, child.toRexNode)
+  }
+}
+
 case class Sha256(child: Expression) extends UnaryExpression with InputTypeSpec {
 
   override private[flink] def resultType: TypeInformation[_] = STRING_TYPE_INFO
@@ -62,3 +75,29 @@ case class Sha256(child: Expression) extends UnaryExpression with InputTypeSpec
     relBuilder.call(ScalarSqlFunctions.SHA256, child.toRexNode)
   }
 }
+
+case class Sha384(child: Expression) extends UnaryExpression with InputTypeSpec {
+
+  override private[flink] def resultType: TypeInformation[_] = STRING_TYPE_INFO
+
+  override private[flink] def expectedTypes: Seq[TypeInformation[_]] = STRING_TYPE_INFO :: Nil
+
+  override def toString: String = s"($child).sha384()"
+
+  override private[flink] def toRexNode(implicit relBuilder: RelBuilder): RexNode = {
+    relBuilder.call(ScalarSqlFunctions.SHA384, child.toRexNode)
+  }
+}
+
+case class Sha512(child: Expression) extends UnaryExpression with InputTypeSpec {
+
+  override private[flink] def resultType: TypeInformation[_] = STRING_TYPE_INFO
+
+  override private[flink] def expectedTypes: Seq[TypeInformation[_]] = STRING_TYPE_INFO :: Nil
+
+  override def toString: String = s"($child).sha512()"
+
+  override private[flink] def toRexNode(implicit relBuilder: RelBuilder): RexNode = {
+    relBuilder.call(ScalarSqlFunctions.SHA512, child.toRexNode)
+  }
+}

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/functions/sql/ScalarSqlFunctions.scala
----------------------------------------------------------------------
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 891aba9..b0c6d44 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
@@ -103,6 +103,15 @@ object ScalarSqlFunctions {
     SqlFunctionCategory.STRING
   )
 
+  val SHA224 = new SqlFunction(
+    "SHA224",
+    SqlKind.OTHER_FUNCTION,
+    ReturnTypes.ARG0_NULLABLE,
+    InferTypes.RETURN_TYPE,
+    OperandTypes.STRING,
+    SqlFunctionCategory.STRING
+  )
+
   val SHA256 = new SqlFunction(
     "SHA256",
     SqlKind.OTHER_FUNCTION,
@@ -112,6 +121,24 @@ object ScalarSqlFunctions {
     SqlFunctionCategory.STRING
   )
 
+  val SHA384 = new SqlFunction(
+    "SHA384",
+    SqlKind.OTHER_FUNCTION,
+    ReturnTypes.ARG0_NULLABLE,
+    InferTypes.RETURN_TYPE,
+    OperandTypes.STRING,
+    SqlFunctionCategory.STRING
+  )
+
+  val SHA512 = new SqlFunction(
+    "SHA512",
+    SqlKind.OTHER_FUNCTION,
+    ReturnTypes.ARG0_NULLABLE,
+    InferTypes.RETURN_TYPE,
+    OperandTypes.STRING,
+    SqlFunctionCategory.STRING
+  )
+
   val DATE_FORMAT = new SqlFunction(
     "DATE_FORMAT",
     SqlKind.OTHER_FUNCTION,

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/validate/FunctionCatalog.scala
----------------------------------------------------------------------
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 51aac27..56e6cd6 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
@@ -273,7 +273,10 @@ object FunctionCatalog {
     // crypto hash
     "md5" -> classOf[Md5],
     "sha1" -> classOf[Sha1],
-    "sha256" -> classOf[Sha256]
+    "sha224" -> classOf[Sha224],
+    "sha256" -> classOf[Sha256],
+    "sha384" -> classOf[Sha384],
+    "sha512" -> classOf[Sha512]
   )
 
   /**
@@ -432,8 +435,10 @@ class BasicOperatorTable extends ReflectiveSqlOperatorTable {
     ScalarSqlFunctions.RPAD,
     ScalarSqlFunctions.MD5,
     ScalarSqlFunctions.SHA1,
+    ScalarSqlFunctions.SHA224,
     ScalarSqlFunctions.SHA256,
-
+    ScalarSqlFunctions.SHA384,
+    ScalarSqlFunctions.SHA512,
     // EXTENSIONS
     BasicOperatorTable.TUMBLE,
     BasicOperatorTable.HOP,

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarFunctionsTest.scala
----------------------------------------------------------------------
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 a9d2733..8a2bc33 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
@@ -1843,7 +1843,10 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
   def testHashFunctions(): Unit = {
     val expectedMd5 = "098f6bcd4621d373cade4e832627b4f6"
     val expectedSha1 = "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
+    val expectedSha224 = "90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809"
     val expectedSha256 = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
+    val expectedSha384 = "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9" // scalastyle:ignore
+    val expectedSha512 = "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff" // scalastyle:ignore
 
     testAllApis(
       "test".md5(),
@@ -1858,21 +1861,45 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
       expectedSha1)
 
     testAllApis(
+      "test".sha224(),
+      "sha224('test')",
+      "SHA224('test')",
+      expectedSha224)
+
+    testAllApis(
       "test".sha256(),
       "sha256('test')",
       "SHA256('test')",
       expectedSha256)
 
     testAllApis(
+      "test".sha384(),
+      "sha384('test')",
+      "SHA384('test')",
+      expectedSha384)
+
+    testAllApis(
+      "test".sha512(),
+      "sha512('test')",
+      "SHA512('test')",
+      expectedSha512)
+
+    testAllApis(
       'f33.md5(),
-      "sha256(f33)",
-      "SHA256(f33)",
+      "md5(f33)",
+      "MD5(f33)",
       "null")
 
     testAllApis(
-      'f33.sha256(),
-      "sha256(f33)",
-      "SHA256(f33)",
+      'f33.sha1(),
+      "sha1(f33)",
+      "SHA1(f33)",
+      "null")
+
+    testAllApis(
+      'f33.sha224(),
+      "sha224(f33)",
+      "SHA224(f33)",
       "null")
 
     testAllApis(
@@ -1880,6 +1907,18 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
       "sha256(f33)",
       "SHA256(f33)",
       "null")
+
+    testAllApis(
+      'f33.sha384(),
+      "sha384(f33)",
+      "SHA384(f33)",
+      "null")
+
+    testAllApis(
+      'f33.sha512(),
+      "sha512(f33)",
+      "SHA512(f33)",
+      "null")
   }
 
   // ----------------------------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/flink/blob/5544ab5d/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
index cf4b583..81ac02e 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
@@ -145,12 +145,25 @@ class SqlExpressionTest extends ExpressionTestBase {
     testSqlApi("SHA1('')", "da39a3ee5e6b4b0d3255bfef95601890afd80709")
     testSqlApi("SHA1('test')", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3")
 
+    testSqlApi("SHA224('')", "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
+    testSqlApi("SHA224('test')", "90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809")
+
     testSqlApi("SHA256('')", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
     testSqlApi("SHA256('test')", "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")
 
+    testSqlApi("SHA384('')", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b") // scalastyle:ignore
+    testSqlApi("SHA384('test')", "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9") // scalastyle:ignore
+
+    testSqlApi("SHA512('')", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e") // scalastyle:ignore
+    testSqlApi("SHA512('test')", "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff") // scalastyle:ignore
+
+
     testSqlApi("MD5(CAST(NULL AS VARCHAR))", "null")
     testSqlApi("SHA1(CAST(NULL AS VARCHAR))", "null")
+    testSqlApi("SHA224(CAST(NULL AS VARCHAR))", "null")
     testSqlApi("SHA256(CAST(NULL AS VARCHAR))", "null")
+    testSqlApi("SHA384(CAST(NULL AS VARCHAR))", "null")
+    testSqlApi("SHA512(CAST(NULL AS VARCHAR))", "null")
   }
 
   @Test


[2/2] flink git commit: [FLINK-6926] [table] Add support for SHA2 (Compatible with SQL vendors like MySQL)

Posted by tw...@apache.org.
[FLINK-6926] [table] Add support for SHA2 (Compatible with SQL vendors like MySQL)

This closes #5324.


Project: http://git-wip-us.apache.org/repos/asf/flink/repo
Commit: http://git-wip-us.apache.org/repos/asf/flink/commit/d5de2bcf
Tree: http://git-wip-us.apache.org/repos/asf/flink/tree/d5de2bcf
Diff: http://git-wip-us.apache.org/repos/asf/flink/diff/d5de2bcf

Branch: refs/heads/master
Commit: d5de2bcf122fd931080ac7a9edc704c93dbe15ee
Parents: 5544ab5
Author: Michael Gendelman <ge...@gmail.com>
Authored: Sun Jan 28 23:26:51 2018 +0200
Committer: Timo Walther <tw...@apache.org>
Committed: Tue May 15 13:18:30 2018 +0200

----------------------------------------------------------------------
 docs/dev/table/sql.md                           | 26 ++++++--
 docs/dev/table/tableApi.md                      | 26 +++++++-
 .../flink/table/api/scala/expressionDsl.scala   | 16 ++++-
 .../flink/table/codegen/CodeGenerator.scala     | 69 +++++++++++++++++---
 .../table/codegen/calls/FunctionGenerator.scala |  6 ++
 .../table/codegen/calls/HashCalcCallGen.scala   | 37 ++++++++++-
 .../table/expressions/hashExpressions.scala     | 21 ++++++
 .../functions/sql/ScalarSqlFunctions.scala      | 10 +++
 .../flink/table/plan/ProjectionTranslator.scala |  7 +-
 .../flink/table/plan/logical/LogicalNode.scala  |  9 ++-
 .../flink/table/validate/FunctionCatalog.scala  |  4 +-
 .../table/expressions/ScalarFunctionsTest.scala | 66 +++++++++++++++++--
 .../table/expressions/SqlExpressionTest.scala   | 40 ++++++++++--
 .../expressions/utils/ScalarTypesTestBase.scala |  6 +-
 14 files changed, 305 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/docs/dev/table/sql.md
----------------------------------------------------------------------
diff --git a/docs/dev/table/sql.md b/docs/dev/table/sql.md
index 7f4a386..8aa1bd7 100644
--- a/docs/dev/table/sql.md
+++ b/docs/dev/table/sql.md
@@ -2419,7 +2419,7 @@ MD5(string)
 {% endhighlight %}
       </td>
       <td>
-        <p>Returns the MD5 hash of the string argument as a string of 32 hexadecimal digits; null if <i>string</i> is null.</p>
+        <p>Returns the MD5 hash of the <i>string</i> argument as a string of 32 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
     </tr>
 
@@ -2430,7 +2430,7 @@ SHA1(string)
 {% endhighlight %}
       </td>
       <td>
-        <p>Returns the SHA-1 hash of the string argument as a string of 40 hexadecimal digits; null if <i>string</i> is null.</p>
+        <p>Returns the SHA-1 hash of the <i>string</i> argument as a string of 40 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
     </tr>
     
@@ -2441,7 +2441,7 @@ SHA224(string)
 {% endhighlight %}
       </td>
       <td>
-        <p>Returns the SHA-224 hash of the string argument as a string of 56 hexadecimal digits; null if <i>string</i> is null.</p>
+        <p>Returns the SHA-224 hash of the <i>string</i> argument as a string of 56 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
     </tr>    
     
@@ -2452,7 +2452,7 @@ SHA256(string)
 {% endhighlight %}
       </td>
       <td>
-        <p>Returns the SHA-256 hash of the string argument as a string of 64 hexadecimal digits; null if <i>string</i> is null.</p>
+        <p>Returns the SHA-256 hash of the <i>string</i> argument as a string of 64 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
     </tr>
     
@@ -2463,7 +2463,7 @@ SHA384(string)
 {% endhighlight %}
       </td>
       <td>
-        <p>Returns the SHA-384 hash of the string argument as a string of 96 hexadecimal digits; null if <i>string</i> is null.</p>
+        <p>Returns the SHA-384 hash of the <i>string</i> argument as a string of 96 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
     </tr>  
 
@@ -2474,9 +2474,21 @@ SHA512(string)
 {% endhighlight %}
       </td>
       <td>
-        <p>Returns the SHA-512 hash of the string argument as a string of 128 hexadecimal digits; null if <i>string</i> is null.</p>
+        <p>Returns the SHA-512 hash of the <i>string</i> argument as a string of 128 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
-    </tr>          
+    </tr>
+
+    <tr>
+      <td>
+        {% highlight text %}
+SHA2(string, hashLength)
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the hash using the SHA-2 family of hash functions (SHA-224, SHA-256, SHA-384, or SHA-512). The first argument <i>string</i> is the string to be hashed. <i>hashLength</i> is the bit length of the result (either 224, 256, 384, or 512). Returns <i>null</i> if <i>string</i> or <i>hashLength</i> is <i>null</i>.
+        </p>
+      </td>
+    </tr>
   </tbody>
 </table>
 

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/docs/dev/table/tableApi.md
----------------------------------------------------------------------
diff --git a/docs/dev/table/tableApi.md b/docs/dev/table/tableApi.md
index 05ce604..8c75078 100644
--- a/docs/dev/table/tableApi.md
+++ b/docs/dev/table/tableApi.md
@@ -3127,6 +3127,18 @@ STRING.sha512()
       </td>
     </tr>
 
+    <tr>
+      <td>
+        {% highlight java %}
+STRING.sha2(INT)
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the hash using the SHA-2 family of hash functions (SHA-224, SHA-256, SHA-384, or SHA-512). The first argument <i>string</i> is the string to be hashed. <i>hashLength</i> is the bit length of the result (either 224, 256, 384, or 512). Returns <i>null</i> if <i>string</i> or <i>hashLength</i> is <i>null</i>.
+        </p>
+      </td>
+    </tr>
+
     </tbody>
 </table>
 
@@ -4604,7 +4616,19 @@ STRING.sha512()
       <td>
         <p>Returns the SHA-512 hash of the string argument as a string of 128 hexadecimal digits; null if <i>string</i> is null.</p>
       </td>
-    </tr>  
+    </tr>
+
+    <tr>
+      <td>
+        {% highlight scala %}
+STRING.sha2(INT)
+{% endhighlight %}
+      </td>
+      <td>
+        <p>Returns the hash using the SHA-2 family of hash functions (SHA-224, SHA-256, SHA-384, or SHA-512). The first argument <i>string</i> is the string to be hashed. <i>hashLength</i> is the bit length of the result (either 224, 256, 384, or 512). Returns <i>null</i> if <i>string</i> or <i>hashLength</i> is <i>null</i>.
+        </p>
+      </td>
+    </tr>
     </tbody>
 </table>
 

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/api/scala/expressionDsl.scala
----------------------------------------------------------------------
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 1494de6..3d00c52 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
@@ -775,7 +775,7 @@ trait ImplicitExpressionOperations {
   /**
     * Returns the SHA-224 hash of the string argument; null if string is null.
     *
-    * @return string of 64 hexadecimal digits or null
+    * @return string of 56 hexadecimal digits or null
     */
   def sha224() = Sha224(expr)
 
@@ -789,16 +789,26 @@ trait ImplicitExpressionOperations {
   /**
     * Returns the SHA-384 hash of the string argument; null if string is null.
     *
-    * @return string of 64 hexadecimal digits or null
+    * @return string of 96 hexadecimal digits or null
     */
   def sha384() = Sha384(expr)
 
   /**
     * Returns the SHA-512 hash of the string argument; null if string is null.
     *
-    * @return string of 64 hexadecimal digits or null
+    * @return string of 128 hexadecimal digits or null
     */
   def sha512() = Sha512(expr)
+
+  /**
+    * Returns the hash for the given string expression using the SHA-2 family of hash
+    * functions (SHA-224, SHA-256, SHA-384, or SHA-512).
+    *
+    * @param hashLength bit length of the result (either 224, 256, 384, or 512)
+    * @return string or null if one of the arguments is null.
+    */
+  def sha2(hashLength: Expression) = Sha2(expr, hashLength)
+
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/CodeGenerator.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/CodeGenerator.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/CodeGenerator.scala
index f0b6793..6cabe21 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/CodeGenerator.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/CodeGenerator.scala
@@ -1895,7 +1895,7 @@ abstract class CodeGenerator(
   }
 
   /**
-    * Adds a reusable MessageDigest to the member area of the generated [[Function]].
+    * Adds a known reusable MessageDigest to the member area of the generated [[Function]].
     *
     * @return member variable term
     */
@@ -1904,20 +1904,69 @@ abstract class CodeGenerator(
 
     val field =
       s"""
-         |final java.security.MessageDigest $fieldTerm;
-         |""".stripMargin
+        |final java.security.MessageDigest $fieldTerm;
+        |""".stripMargin
     reusableMemberStatements.add(field)
 
-    val fieldInit =
+    val init =
       s"""
-         |try {
-         |  $fieldTerm = java.security.MessageDigest.getInstance("$algorithm");
-         |} catch (java.security.NoSuchAlgorithmException e) {
-         |  throw new RuntimeException("Algorithm for '$algorithm' is not available.", e);
-         |}
+        |try {
+        |  $fieldTerm = java.security.MessageDigest.getInstance("$algorithm");
+        |} catch (java.security.NoSuchAlgorithmException e) {
+        |  throw new RuntimeException("Algorithm for '$algorithm' is not available.", e);
+        |}
+        |""".stripMargin
+
+    reusableInitStatements.add(init)
+    fieldTerm
+  }
+
+  /**
+    * Adds a constant SHA2 reusable MessageDigest to the member area of the generated [[Function]].
+    *
+    * @return member variable term
+    */
+  def addReusableSha2MessageDigest(constant: GeneratedExpression): String = {
+    require(constant.literal, "Literal expected")
+    val fieldTerm = newName("messageDigest")
+
+    val field =
+        s"""
+           |final java.security.MessageDigest $fieldTerm;
+           |""".stripMargin
+      reusableMemberStatements.add(field)
+
+    val bitLen = constant.resultTerm
+    val init = s"""
+      |if ($bitLen == 224 || $bitLen == 256 || $bitLen == 384 || $bitLen == 512) {
+      |  try {
+      |    $fieldTerm = java.security.MessageDigest.getInstance("SHA-" + $bitLen);
+      |  } catch (java.security.NoSuchAlgorithmException e) {
+      |    throw new RuntimeException(
+      |      "Algorithm for 'SHA-" + $bitLen + "' is not available.", e);
+      |  }
+      |} else {
+      |  throw new RuntimeException("Unsupported algorithm.");
+      |}
+      |""".stripMargin
+
+    val nullableInit = if (nullCheck) {
+      s"""
+        |${constant.code}
+        |if (${constant.nullTerm}) {
+        |  $fieldTerm = null;
+        |} else {
+        |  $init
+        |}
+        |""".stripMargin
+    } else {
+      s"""
+         |${constant.code}
+         |$init
          |""".stripMargin
+    }
+    reusableInitStatements.add(nullableInit)
 
-    reusableInitStatements.add(fieldInit)
     fieldTerm
   }
 }

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
----------------------------------------------------------------------
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 0f2e986..bd75617 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
@@ -583,6 +583,12 @@ object FunctionGenerator {
     new HashCalcCallGen("SHA-512")
   )
 
+  addSqlFunction(
+    ScalarSqlFunctions.SHA2,
+    Seq(STRING_TYPE_INFO, INT_TYPE_INFO),
+    new HashCalcCallGen("SHA-2")
+  )
+
   // ----------------------------------------------------------------------------------------------
 
   /**

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/HashCalcCallGen.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/HashCalcCallGen.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/HashCalcCallGen.scala
index 3b46f47..d3be6e1 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/HashCalcCallGen.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/codegen/calls/HashCalcCallGen.scala
@@ -21,6 +21,7 @@ package org.apache.flink.table.codegen.calls
 import org.apache.commons.codec.Charsets
 import org.apache.commons.codec.binary.Hex
 import org.apache.flink.api.common.typeinfo.BasicTypeInfo._
+import org.apache.flink.table.codegen.CodeGenUtils.newName
 import org.apache.flink.table.codegen.calls.CallGenerator.generateCallWithStmtIfArgsNotNull
 import org.apache.flink.table.codegen.{CodeGenerator, GeneratedExpression}
 
@@ -31,12 +32,44 @@ class HashCalcCallGen(algName: String) extends CallGenerator {
       operands: Seq[GeneratedExpression])
     : GeneratedExpression = {
 
-    val md = codeGenerator.addReusableMessageDigest(algName)
+    val (initStmt, md) = operands.size match {
+
+      // for function calls of MD5, SHA1, SHA224, SHA256, SHA384, SHA512
+      case 1 =>
+        (None, codeGenerator.addReusableMessageDigest(algName))
+
+      // for function calls of SHA2 with constant bit length
+      case 2 if operands(1).literal =>
+        (None, codeGenerator.addReusableSha2MessageDigest(operands(1)))
+
+      // for function calls of SHA2 with variable bit length
+      case 2 =>
+        val messageDigest = newName("messageDigest")
+        val bitLen = operands(1).resultTerm
+        val init =
+          s"""
+            |final java.security.MessageDigest $messageDigest;
+            |if ($bitLen == 224 || $bitLen == 256 || $bitLen == 384 || $bitLen == 512) {
+            |  try {
+            |    $messageDigest = java.security.MessageDigest.getInstance("SHA-" + $bitLen);
+            |  } catch (java.security.NoSuchAlgorithmException e) {
+            |    throw new RuntimeException(
+            |      "Algorithm for 'SHA-" + $bitLen + "' is not available.", e);
+            |  }
+            |} else {
+            |  throw new RuntimeException("Unsupported algorithm.");
+            |}
+            |""".stripMargin
+        (Some(init), messageDigest)
+    }
 
     generateCallWithStmtIfArgsNotNull(codeGenerator.nullCheck, STRING_TYPE_INFO, operands) {
       (terms) =>
         val auxiliaryStmt =
-          s"$md.update(${terms.head}.getBytes(${classOf[Charsets].getCanonicalName}.UTF_8));"
+          s"""
+            |${initStmt.getOrElse("")}
+            |$md.update(${terms.head}.getBytes(${classOf[Charsets].getCanonicalName}.UTF_8));
+            |""".stripMargin
         val result = s"${classOf[Hex].getCanonicalName}.encodeHexString($md.digest())"
         (Some(auxiliaryStmt), result)
     }

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
index 59a3635..611c64d 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/expressions/hashExpressions.scala
@@ -101,3 +101,24 @@ case class Sha512(child: Expression) extends UnaryExpression with InputTypeSpec
     relBuilder.call(ScalarSqlFunctions.SHA512, child.toRexNode)
   }
 }
+
+case class Sha2(child: Expression, hashLength: Expression)
+    extends BinaryExpression with InputTypeSpec {
+
+  override private[flink] def left = child
+  override private[flink] def right = hashLength
+
+  override private[flink] def resultType: TypeInformation[_] = STRING_TYPE_INFO
+
+  override private[flink] def expectedTypes: Seq[TypeInformation[_]] =
+    STRING_TYPE_INFO :: INT_TYPE_INFO :: Nil
+
+  override def toString: String = s"($child).sha2($hashLength)"
+
+  override private[flink] def toRexNode(implicit relBuilder: RelBuilder): RexNode = {
+    relBuilder.call(ScalarSqlFunctions.SHA2, left.toRexNode, right.toRexNode)
+  }
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/functions/sql/ScalarSqlFunctions.scala
----------------------------------------------------------------------
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 b0c6d44..69f430b 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
@@ -139,6 +139,16 @@ object ScalarSqlFunctions {
     SqlFunctionCategory.STRING
   )
 
+  val SHA2 = new SqlFunction(
+    "SHA2",
+    SqlKind.OTHER_FUNCTION,
+    ReturnTypes.ARG0_NULLABLE,
+    InferTypes.RETURN_TYPE,
+    OperandTypes.sequence("'(DATA, HASH_LENGTH)'",
+      OperandTypes.STRING,  OperandTypes.NUMERIC_INTEGER),
+    SqlFunctionCategory.STRING
+  )
+
   val DATE_FORMAT = new SqlFunction(
     "DATE_FORMAT",
     SqlKind.OTHER_FUNCTION,

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/ProjectionTranslator.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/ProjectionTranslator.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/ProjectionTranslator.scala
index 97cd9cc..82b066c 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/ProjectionTranslator.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/ProjectionTranslator.scala
@@ -19,7 +19,7 @@
 package org.apache.flink.table.plan
 
 import org.apache.flink.api.common.typeutils.CompositeType
-import org.apache.flink.table.api.{OverWindow, TableEnvironment}
+import org.apache.flink.table.api.{OverWindow, TableEnvironment, ValidationException}
 import org.apache.flink.table.expressions._
 import org.apache.flink.table.plan.logical.{LogicalNode, Project}
 
@@ -92,6 +92,11 @@ object ProjectionTranslator {
             case _ => (x._1, x._2)
           }
         }
+
+      // Expression is null
+      case null =>
+        throw new ValidationException("Scala 'null' is not a valid expression. " +
+          "Use 'Null(TYPE)' to specify typed null expressions. For example: Null(Types.INT)")
     }
   }
 

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/logical/LogicalNode.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/logical/LogicalNode.scala b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/logical/LogicalNode.scala
index 6fe888a..b17d5a3 100644
--- a/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/logical/LogicalNode.scala
+++ b/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/plan/logical/LogicalNode.scala
@@ -84,7 +84,14 @@ abstract class LogicalNode extends TreeNode[LogicalNode] {
     resolvedNode.expressionPostOrderTransform {
       case a: Attribute if !a.valid =>
         val from = children.flatMap(_.output).map(_.name).mkString(", ")
-        failValidation(s"Cannot resolve [${a.name}] given input [$from].")
+        // give helpful error message for null literals
+        if (a.name == "null") {
+          failValidation(s"Cannot resolve field [${a.name}] given input [$from]. If you want to " +
+            s"express a null literal, use 'Null(TYPE)' for typed null expressions. " +
+            s"For example: Null(INT)")
+        } else {
+          failValidation(s"Cannot resolve field [${a.name}] given input [$from].")
+        }
 
       case e: Expression if e.validateInput().isFailure =>
         failValidation(s"Expression $e failed on input check: " +

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/main/scala/org/apache/flink/table/validate/FunctionCatalog.scala
----------------------------------------------------------------------
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 56e6cd6..8418cf2 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
@@ -276,7 +276,8 @@ object FunctionCatalog {
     "sha224" -> classOf[Sha224],
     "sha256" -> classOf[Sha256],
     "sha384" -> classOf[Sha384],
-    "sha512" -> classOf[Sha512]
+    "sha512" -> classOf[Sha512],
+    "sha2" -> classOf[Sha2]
   )
 
   /**
@@ -439,6 +440,7 @@ class BasicOperatorTable extends ReflectiveSqlOperatorTable {
     ScalarSqlFunctions.SHA256,
     ScalarSqlFunctions.SHA384,
     ScalarSqlFunctions.SHA512,
+    ScalarSqlFunctions.SHA2,
     // EXTENSIONS
     BasicOperatorTable.TUMBLE,
     BasicOperatorTable.HOP,

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarFunctionsTest.scala
----------------------------------------------------------------------
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 8a2bc33..a08f419 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
@@ -1845,8 +1845,10 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
     val expectedSha1 = "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
     val expectedSha224 = "90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809"
     val expectedSha256 = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
-    val expectedSha384 = "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9" // scalastyle:ignore
-    val expectedSha512 = "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff" // scalastyle:ignore
+    val expectedSha384 = "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a7" +
+      "82249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9"
+    val expectedSha512 = "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a" +
+      "5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"
 
     testAllApis(
       "test".md5(),
@@ -1860,30 +1862,63 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
       "SHA1('test')",
       expectedSha1)
 
+    // sha224
     testAllApis(
       "test".sha224(),
       "sha224('test')",
       "SHA224('test')",
       expectedSha224)
 
+    // sha-2 224
+    testAllApis(
+      "test".sha2(224),
+      "sha2('test', 224)",
+      "SHA2('test', 224)",
+      expectedSha224)
+
+    // sha256
     testAllApis(
       "test".sha256(),
       "sha256('test')",
       "SHA256('test')",
       expectedSha256)
 
+    // sha-2 256
+    testAllApis(
+      "test".sha2(256),
+      "sha2('test', 256)",
+      "SHA2('test', 256)",
+      expectedSha256)
+
+    // sha384
     testAllApis(
       "test".sha384(),
       "sha384('test')",
       "SHA384('test')",
       expectedSha384)
 
+    // sha-2 384
+    testAllApis(
+      "test".sha2(384),
+      "sha2('test', 384)",
+      "SHA2('test', 384)",
+      expectedSha384)
+
+    // sha512
     testAllApis(
       "test".sha512(),
       "sha512('test')",
       "SHA512('test')",
       expectedSha512)
 
+    // sha-2 512
+    testAllApis(
+      "test".sha2(512),
+      "sha2('test', 512)",
+      "SHA2('test', 512)",
+      expectedSha512)
+
+    // null tests
     testAllApis(
       'f33.md5(),
       "md5(f33)",
@@ -1899,26 +1934,45 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
     testAllApis(
       'f33.sha224(),
       "sha224(f33)",
-      "SHA224(f33)",
+      "SHA2(f33, 224)",
+      "null")
+
+    testAllApis(
+      'f33.sha2(224),
+      "sha2(f33, 224)",
+      "SHA2(f33, 224)",
       "null")
 
     testAllApis(
       'f33.sha256(),
       "sha256(f33)",
-      "SHA256(f33)",
+      "SHA2(f33, 256)",
       "null")
 
     testAllApis(
       'f33.sha384(),
       "sha384(f33)",
-      "SHA384(f33)",
+      "SHA2(f33, 384)",
       "null")
 
     testAllApis(
       'f33.sha512(),
       "sha512(f33)",
-      "SHA512(f33)",
+      "SHA2(f33, 512)",
+      "null")
+
+    testAllApis(
+      "test".sha2(Null(Types.INT)),
+      "sha2('test', Null(INT))",
+      "SHA2('test', CAST(NULL AS INT))",
       "null")
+
+    // non-constant bit length
+    testAllApis(
+      "test".sha2('f34),
+      "sha2('test', f34)",
+      "SHA2('test', f34)",
+      expectedSha256)
   }
 
   // ----------------------------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
index 81ac02e..d1f5082 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/SqlExpressionTest.scala
@@ -21,6 +21,7 @@ package org.apache.flink.table.expressions
 import org.apache.flink.api.common.typeinfo.TypeInformation
 import org.apache.flink.types.Row
 import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.table.api.ValidationException
 import org.apache.flink.table.expressions.utils.ExpressionTestBase
 import org.junit.Test
 
@@ -146,17 +147,37 @@ class SqlExpressionTest extends ExpressionTestBase {
     testSqlApi("SHA1('test')", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3")
 
     testSqlApi("SHA224('')", "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
+    testSqlApi("SHA2('', 224)", "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
+
     testSqlApi("SHA224('test')", "90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809")
+    testSqlApi("SHA2('test', 224)", "90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809")
 
     testSqlApi("SHA256('')", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+    testSqlApi("SHA2('', 256)", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+
     testSqlApi("SHA256('test')", "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")
+    testSqlApi("SHA2('test', 256)",
+      "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")
 
-    testSqlApi("SHA384('')", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b") // scalastyle:ignore
-    testSqlApi("SHA384('test')", "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9") // scalastyle:ignore
+    testSqlApi("SHA384('')", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc" +
+      "7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
+    testSqlApi("SHA2('', 384)", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0" +
+      "cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
 
-    testSqlApi("SHA512('')", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e") // scalastyle:ignore
-    testSqlApi("SHA512('test')", "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff") // scalastyle:ignore
+    testSqlApi("SHA384('test')", "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc" +
+      "4b7ef1ccb126255d196047dfedf17a0a9")
+    testSqlApi("SHA2('test', 384)", "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8" +
+      "efc4b7ef1ccb126255d196047dfedf17a0a9")
 
+    testSqlApi("SHA512('')", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d" +
+      "0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+    testSqlApi("SHA2('',512)", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce4" +
+      "7d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+
+    testSqlApi("SHA512('test')", "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db" +
+      "27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff")
+    testSqlApi("SHA2('test',512)", "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0" +
+      "db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff")
 
     testSqlApi("MD5(CAST(NULL AS VARCHAR))", "null")
     testSqlApi("SHA1(CAST(NULL AS VARCHAR))", "null")
@@ -164,6 +185,17 @@ class SqlExpressionTest extends ExpressionTestBase {
     testSqlApi("SHA256(CAST(NULL AS VARCHAR))", "null")
     testSqlApi("SHA384(CAST(NULL AS VARCHAR))", "null")
     testSqlApi("SHA512(CAST(NULL AS VARCHAR))", "null")
+    testSqlApi("SHA2(CAST(NULL AS VARCHAR), 256)", "null")
+  }
+
+  @Test(expected = classOf[RuntimeException])
+  def testHashFunctionsUnsupportedLength(): Unit = {
+    testSqlApi("SHA2('', 333)", "")
+  }
+
+  @Test(expected = classOf[ValidationException])
+  def testHashFunctionSha2NoParam(): Unit = {
+    testSqlApi("SHA2('')", "")
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/flink/blob/d5de2bcf/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarTypesTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarTypesTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarTypesTestBase.scala
index 41fe52c..2a90a90 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarTypesTestBase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarTypesTestBase.scala
@@ -28,7 +28,7 @@ import org.apache.flink.types.Row
 class ScalarTypesTestBase extends ExpressionTestBase {
 
   def testData: Row = {
-    val testData = new Row(34)
+    val testData = new Row(35)
     testData.setField(0, "This is a test String.")
     testData.setField(1, true)
     testData.setField(2, 42.toByte)
@@ -63,6 +63,7 @@ class ScalarTypesTestBase extends ExpressionTestBase {
     testData.setField(31, BigDecimal("-0.1231231321321321111").bigDecimal)
     testData.setField(32, -1)
     testData.setField(33, null)
+    testData.setField(34, 256)
     testData
   }
 
@@ -101,6 +102,7 @@ class ScalarTypesTestBase extends ExpressionTestBase {
       Types.INT,
       Types.DECIMAL,
       Types.INT,
-      Types.STRING).asInstanceOf[TypeInformation[Any]]
+      Types.STRING,
+      Types.INT).asInstanceOf[TypeInformation[Any]]
   }
 }