libenchao commented on a change in pull request #11186: URL: https://github.com/apache/flink/pull/11186#discussion_r433697949
########## File path: flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/planner/functions/sql/FlinkSqlOperatorTable.java ########## @@ -1012,4 +1012,12 @@ public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) { public static final SqlPostfixOperator IS_NOT_JSON_OBJECT = SqlStdOperatorTable.IS_NOT_JSON_OBJECT; public static final SqlPostfixOperator IS_NOT_JSON_ARRAY = SqlStdOperatorTable.IS_NOT_JSON_ARRAY; public static final SqlPostfixOperator IS_NOT_JSON_SCALAR = SqlStdOperatorTable.IS_NOT_JSON_SCALAR; + public static final SqlFunction JSON_EXISTS = new SqlFunction( + "JSON_EXISTS", + SqlKind.OTHER_FUNCTION, + ReturnTypes.cascade(ReturnTypes.BOOLEAN, SqlTypeTransforms.FORCE_NULLABLE), null, Review comment: we should keep each param one line. ########## File path: flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/planner/codegen/calls/BuiltInMethods.scala ########## @@ -23,8 +23,8 @@ import org.apache.flink.table.runtime.functions._ import org.apache.calcite.avatica.util.TimeUnitRange import org.apache.calcite.linq4j.tree.Types -import org.apache.calcite.runtime.SqlFunctions - Review comment: keep the original blank line. ########## File path: flink-table/flink-table-planner-blink/src/test/scala/org/apache/flink/table/planner/expressions/JsonFunctionsTest.scala ########## @@ -103,9 +117,9 @@ class JsonFunctionsTest extends ExpressionTestBase { } private def verifyException[T <: Exception]( - candidate: String, - expectedException: Class[T] - ): Unit = { + candidate: String, + expectedException: Class[T] + ): Unit = { Review comment: why add this indent? ########## File path: flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/planner/codegen/calls/StringCallGen.scala ########## @@ -28,11 +28,9 @@ import org.apache.flink.table.planner.functions.sql.FlinkSqlOperatorTable._ import org.apache.flink.table.runtime.functions.SqlFunctionUtils import org.apache.flink.table.runtime.typeutils.TypeCheckUtils.{isCharacterString, isTimestamp, isTimestampWithLocalZone} import org.apache.flink.table.types.logical._ - Review comment: keep the blank line +1, and same for below. ########## File path: flink-table/flink-table-planner-blink/src/test/scala/org/apache/flink/table/planner/expressions/JsonFunctionsTest.scala ########## @@ -117,12 +131,48 @@ class JsonFunctionsTest extends ExpressionTestBase { s"$candidate is not json scalar") for (sql <- sqlCandidates) { - try { - testSqlApi(sql, "null") - } catch { + try testSqlApi(sql, "null") catch { case e: Exception => assertEquals(e.getClass, expectedException) } } } + @Test + def testJsonExists(): Unit = { + testSqlApi("json_exists(f9, '$.info.type')", "false") + + // lax json test + testSqlApi("json_exists(f9, 'lax $')", "true") + testSqlApi("json_exists(f9, 'lax $.info.type')", "true") + testSqlApi("json_exists(f9, 'lax $.info.address.town')", "true") + testSqlApi("json_exists(f9, 'lax $.info.\"address\"')", "false") + testSqlApi("json_exists(f9, 'lax $.info.tags')", "true") + testSqlApi("json_exists(f9, 'lax $.info.type[0]')", "false") + testSqlApi("json_exists(f9, 'lax $.info.none')", "false") + testSqlApi("json_exists(f9, 'lax $' error on error)", "true") + + // strict + no error + testSqlApi("json_exists(f9, 'strict $.info.type')", "true") + testSqlApi("json_exists(f9, 'strict $.info.type1')", "false") + // strict + error + testSqlApi("json_exists(f9, 'strict $.info.type1' false on error)", "false") + testSqlApi("json_exists(f9, 'strict $.info.type1' true on error)", "true") + testSqlApi("json_exists(f9, 'strict $.info.type' true on error)", "true") + testSqlApi("json_exists(f9, 'strict $.info.type' false on error)", "true") + testSqlApi("json_exists(f9, 'strict $.info.type' unknown on error)", "true") + testSqlApi("json_exists(f9, 'strict $.info.\"type\"' unknown on error)", "null") + testSqlApi("json_exists(f9, 'strict $.info.type' error on error)", "true") + + verifyJsonExistsException("json_exists(f7, 'lax aa')", "SQL validation failed") + } + + private def verifyJsonExistsException[T <: Exception]( + sqlExpr: String, + expectedMessage: String + ): Unit = { + expectedException.expect(classOf[ValidationException]) + expectedException.expectMessage(startsWith(expectedMessage)) + testSqlApi(sqlExpr, "null") + expectedException = ExpectedException.none() Review comment: have you verified this test? I seems that if we encounter one exception, it will abort the test no matter it satisfies the expected exception. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org