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 2017/07/13 10:18:10 UTC
[01/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Repository: flink
Updated Branches:
refs/heads/master 9bfc927ea -> f1fafc0e1
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala
new file mode 100644
index 0000000..c800289
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.sinks.validation
+
+import org.apache.flink.table.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.{TableEnvironment, TableException}
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.runtime.datastream.table.TestAppendSink
+import org.junit.Test
+
+class TableSinksValidationTest extends StreamingMultipleProgramsTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testAppendSinkOnUpdatingTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'id, 'num, 'text)
+
+ t.groupBy('text)
+ .select('text, 'id.count, 'num.sum)
+ .writeToSink(new TestAppendSink)
+
+ // must fail because table is not append-only
+ env.execute()
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala
new file mode 100644
index 0000000..b01453d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.sources
+
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.{Assert, Test}
+
+class TableSourceTest extends TableSourceTestBase {
+
+ @Test
+ def testTableSourceScanToString(): Unit = {
+ val (tableSource1, _) = filterableTableSource
+ val (tableSource2, _) = filterableTableSource
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource("table1", tableSource1)
+ tEnv.registerTableSource("table2", tableSource2)
+
+ val table1 = tEnv.scan("table1").where("amount > 2")
+ val table2 = tEnv.scan("table2").where("amount > 2")
+ val result = table1.unionAll(table2)
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ batchFilterableSourceTableNode(
+ "table1",
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ batchFilterableSourceTableNode(
+ "table2",
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("union", "name, id, amount, price")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testCsvTableSourceBuilder(): Unit = {
+ val source1 = CsvTableSource.builder()
+ .path("/path/to/csv")
+ .field("myfield", Types.STRING)
+ .field("myfield2", Types.INT)
+ .quoteCharacter(';')
+ .fieldDelimiter("#")
+ .lineDelimiter("\r\n")
+ .commentPrefix("%%")
+ .ignoreFirstLine()
+ .ignoreParseErrors()
+ .build()
+
+ val source2 = new CsvTableSource(
+ "/path/to/csv",
+ Array("myfield", "myfield2"),
+ Array(Types.STRING, Types.INT),
+ "#",
+ "\r\n",
+ ';',
+ true,
+ "%%",
+ true)
+
+ Assert.assertEquals(source1, source2)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala
new file mode 100644
index 0000000..d408694
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.sources
+
+import org.apache.flink.table.utils.{CommonTestData, TableTestBase, TestFilterableTableSource}
+
+class TableSourceTestBase extends TableTestBase {
+
+ protected val projectedFields: Array[String] = Array("last", "id", "score")
+ protected val noCalcFields: Array[String] = Array("id", "score", "first")
+
+ def filterableTableSource:(TableSource[_], String) = {
+ val tableSource = new TestFilterableTableSource
+ (tableSource, "filterableTable")
+ }
+
+ def csvTable: (CsvTableSource, String) = {
+ val csvTable = CommonTestData.getCsvTableSource
+ val tableName = "csvTable"
+ (csvTable, tableName)
+ }
+
+ def batchSourceTableNode(sourceName: String, fields: Array[String]): String = {
+ s"BatchTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
+ }
+
+ def streamSourceTableNode(sourceName: String, fields: Array[String] ): String = {
+ s"StreamTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
+ }
+
+ def batchFilterableSourceTableNode(
+ sourceName: String,
+ fields: Array[String],
+ exp: String): String = {
+ "BatchTableSourceScan(" +
+ s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+ }
+
+ def streamFilterableSourceTableNode(
+ sourceName: String,
+ fields: Array[String],
+ exp: String): String = {
+ "StreamTableSourceScan(" +
+ s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala
new file mode 100644
index 0000000..f670452
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala
@@ -0,0 +1,421 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.sources.batch
+
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils._
+import org.apache.flink.table.sources.{CsvTableSource, TableSource}
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{CommonTestData, TableTestBase, TestFilterableTableSource}
+import org.junit.{Assert, Test}
+
+class TableSourceTest extends TableTestBase {
+
+ private val projectedFields: Array[String] = Array("last", "id", "score")
+ private val noCalcFields: Array[String] = Array("id", "score", "first")
+
+ @Test
+ def testTableSourceScanToString(): Unit = {
+ val (tableSource1, _) = filterableTableSource
+ val (tableSource2, _) = filterableTableSource
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource("table1", tableSource1)
+ tEnv.registerTableSource("table2", tableSource2)
+
+ val table1 = tEnv.scan("table1").where("amount > 2")
+ val table2 = tEnv.scan("table2").where("amount > 2")
+ val result = table1.unionAll(table2)
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ batchFilterableSourceTableNode(
+ "table1",
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ batchFilterableSourceTableNode(
+ "table2",
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("union", "name, id, amount, price")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ // batch plan
+
+ @Test
+ def testBatchProjectableSourceScanPlanTableApi(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('last.upperCase(), 'id.floor(), 'score * 2)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchSourceTableNode(tableName, projectedFields),
+ term("select", "UPPER(last) AS _c0", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchProjectableSourceScanPlanSQL(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = batchTestUtil()
+
+ util.tableEnv.registerTableSource(tableName, tableSource)
+
+ val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testBatchProjectableSourceScanNoIdentityCalc(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('id, 'score, 'first)
+
+ val expected = batchSourceTableNode(tableName, noCalcFields)
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableWithoutPushDown(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("price * 2 < 32")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price")),
+ term("select", "price", "id", "amount"),
+ term("where", "<(*(price, 2), 32)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterablePartialPushDown(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .where("amount > 2 && price * 2 < 32")
+ .select('price, 'name.lowerCase(), 'amount)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "LOWER(name) AS _c1", "amount"),
+ term("where", "<(*(price, 2), 32)")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableFullyPushedDown(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && amount < 32")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2 && 'amount < 32"),
+ term("select", "price", "id", "amount")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableWithUnconvertedExpression(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && (amount < 32 || amount.cast(LONG) > 10)") // cast can not be converted
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "id", "amount"),
+ term("where", "OR(<(amount, 32), >(CAST(amount), 10))")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableWithUDF(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+ val func = Func0
+ tEnv.registerFunction("func0", func)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && func0(amount) < 32")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "id", "amount"),
+ term("where", s"<(${func.functionIdentifier}(amount), 32)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ // stream plan
+
+ @Test
+ def testStreamProjectableSourceScanPlanTableApi(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('last, 'id.floor(), 'score * 2)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testStreamProjectableSourceScanPlanSQL(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+
+ util.tableEnv.registerTableSource(tableName, tableSource)
+
+ val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testStreamProjectableSourceScanNoIdentityCalc(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('id, 'score, 'first)
+
+ val expected = streamSourceTableNode(tableName, noCalcFields)
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testStreamFilterableSourceScanPlanTableApi(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = streamTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && price * 2 < 32")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "id", "amount"),
+ term("where", "<(*(price, 2), 32)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ // csv builder
+
+ @Test
+ def testCsvTableSourceBuilder(): Unit = {
+ val source1 = CsvTableSource.builder()
+ .path("/path/to/csv")
+ .field("myfield", Types.STRING)
+ .field("myfield2", Types.INT)
+ .quoteCharacter(';')
+ .fieldDelimiter("#")
+ .lineDelimiter("\r\n")
+ .commentPrefix("%%")
+ .ignoreFirstLine()
+ .ignoreParseErrors()
+ .build()
+
+ val source2 = new CsvTableSource(
+ "/path/to/csv",
+ Array("myfield", "myfield2"),
+ Array(Types.STRING, Types.INT),
+ "#",
+ "\r\n",
+ ';',
+ true,
+ "%%",
+ true)
+
+ Assert.assertEquals(source1, source2)
+ }
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithNullPath(): Unit = {
+ CsvTableSource.builder()
+ .field("myfield", Types.STRING)
+ // should fail, path is not defined
+ .build()
+ }
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithDuplicateFieldName(): Unit = {
+ CsvTableSource.builder()
+ .path("/path/to/csv")
+ .field("myfield", Types.STRING)
+ // should fail, field name must no be duplicate
+ .field("myfield", Types.INT)
+ }
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithEmptyField(): Unit = {
+ CsvTableSource.builder()
+ .path("/path/to/csv")
+ // should fail, field can be empty
+ .build()
+ }
+
+ // utils
+
+ def filterableTableSource:(TableSource[_], String) = {
+ val tableSource = new TestFilterableTableSource
+ (tableSource, "filterableTable")
+ }
+
+ def csvTable: (CsvTableSource, String) = {
+ val csvTable = CommonTestData.getCsvTableSource
+ val tableName = "csvTable"
+ (csvTable, tableName)
+ }
+
+ def batchSourceTableNode(sourceName: String, fields: Array[String]): String = {
+ s"BatchTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
+ }
+
+ def streamSourceTableNode(sourceName: String, fields: Array[String] ): String = {
+ s"StreamTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
+ }
+
+ def batchFilterableSourceTableNode(
+ sourceName: String,
+ fields: Array[String],
+ exp: String): String = {
+ "BatchTableSourceScan(" +
+ s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+ }
+
+ def streamFilterableSourceTableNode(
+ sourceName: String,
+ fields: Array[String],
+ exp: String): String = {
+ "StreamTableSourceScan(" +
+ s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala
new file mode 100644
index 0000000..e6d6480
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.sources.stream.sql
+
+import org.apache.flink.table.sources.TableSourceTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class TableSourceTest extends TableSourceTestBase {
+
+ @Test
+ def testProjectableSourceScanPlan(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+
+ util.tableEnv.registerTableSource(tableName, tableSource)
+
+ val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala
new file mode 100644
index 0000000..c43913b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.sources.stream.table
+
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.sources.TableSourceTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class TableSourceTest extends TableSourceTestBase {
+
+ @Test
+ def testProjectableSourceScanPlan(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('last, 'id.floor(), 'score * 2)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProjectableSourceScanNoIdentityCalc(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('id, 'score, 'first)
+
+ val expected = streamSourceTableNode(tableName, noCalcFields)
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testFilterableSourceScanPlan(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = streamTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerTableSource(tableName, tableSource)
+
+ val result = tEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && price * 2 < 32")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "id", "amount"),
+ term("where", "<(*(price, 2), 32)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala
new file mode 100644
index 0000000..e575ab8
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.sources.validation
+
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.sources.CsvTableSource
+import org.apache.flink.table.sources.TableSourceTestBase
+import org.junit.Test
+
+class TableSourceBalidationTest extends TableSourceTestBase {
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithNullPath(): Unit = {
+ CsvTableSource.builder()
+ .field("myfield", Types.STRING)
+ // should fail, path is not defined
+ .build()
+ }
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithDuplicateFieldName(): Unit = {
+ CsvTableSource.builder()
+ .path("/path/to/csv")
+ .field("myfield", Types.STRING)
+ // should fail, field name must no be duplicate
+ .field("myfield", Types.INT)
+ }
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithEmptyField(): Unit = {
+ CsvTableSource.builder()
+ .path("/path/to/csv")
+ // should fail, field can be empty
+ .build()
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
index 402a69d..6657d50 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
@@ -24,6 +24,7 @@ import org.apache.flink.api.java.{DataSet => JDataSet}
import org.apache.flink.table.api.{Table, TableEnvironment}
import org.apache.flink.table.api.scala._
import org.apache.flink.api.scala.{DataSet, ExecutionEnvironment}
+import org.apache.flink.api.java.{ExecutionEnvironment => JExecutionEnvironment}
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.table.expressions.Expression
import org.apache.flink.table.functions.{ScalarFunction, TableFunction}
@@ -62,7 +63,6 @@ class TableTestBase {
LogicalPlanFormatUtils.formatTempTableId(RelOptUtil.toString(expected.getRelNode)),
LogicalPlanFormatUtils.formatTempTableId(RelOptUtil.toString(actual.getRelNode)))
}
-
}
abstract class TableTestUtil {
@@ -75,14 +75,18 @@ abstract class TableTestUtil {
}
def addTable[T: TypeInformation](name: String, fields: Expression*): Table
+
def addFunction[T: TypeInformation](name: String, function: TableFunction[T]): TableFunction[T]
+
def addFunction(name: String, function: ScalarFunction): Unit
def verifySql(query: String, expected: String): Unit
+
def verifyTable(resultTable: Table, expected: String): Unit
// the print methods are for debugging purposes only
def printTable(resultTable: Table): Unit
+
def printSql(query: String): Unit
}
@@ -112,9 +116,9 @@ object TableTestUtil {
s"$term=[${value.mkString(", ")}]"
}
- def tuples(value:List[AnyRef]*): String={
- val listValues = value.map( listValue => s"{ ${listValue.mkString(", ")} }")
- term("tuples","[" + listValues.mkString(", ") + "]")
+ def tuples(value: List[AnyRef]*): String = {
+ val listValues = value.map(listValue => s"{ ${listValue.mkString(", ")} }")
+ term("tuples", "[" + listValues.mkString(", ") + "]")
}
def batchTableNode(idx: Int): String = {
@@ -128,9 +132,10 @@ object TableTestUtil {
}
case class BatchTableTestUtil() extends TableTestUtil {
-
+ val javaEnv = mock(classOf[JExecutionEnvironment])
+ val javaTableEnv = TableEnvironment.getTableEnvironment(javaEnv)
val env = mock(classOf[ExecutionEnvironment])
- val tEnv = TableEnvironment.getTableEnvironment(env)
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
def addTable[T: TypeInformation](
name: String,
@@ -142,8 +147,18 @@ case class BatchTableTestUtil() extends TableTestUtil {
val typeInfo: TypeInformation[T] = implicitly[TypeInformation[T]]
when(jDs.getType).thenReturn(typeInfo)
- val t = ds.toTable(tEnv, fields: _*)
- tEnv.registerTable(name, t)
+ val t = ds.toTable(tableEnv, fields: _*)
+ tableEnv.registerTable(name, t)
+ t
+ }
+
+ def addJavaTable[T](typeInfo: TypeInformation[T], name: String, fields: String): Table = {
+
+ val jDs = mock(classOf[JDataSet[T]])
+ when(jDs.getType).thenReturn(typeInfo)
+
+ val t = javaTableEnv.fromDataSet(jDs, fields)
+ javaTableEnv.registerTable(name, t)
t
}
@@ -151,27 +166,27 @@ case class BatchTableTestUtil() extends TableTestUtil {
name: String,
function: TableFunction[T])
: TableFunction[T] = {
- tEnv.registerFunction(name, function)
+ tableEnv.registerFunction(name, function)
function
}
def addFunction(name: String, function: ScalarFunction): Unit = {
- tEnv.registerFunction(name, function)
+ tableEnv.registerFunction(name, function)
}
- def addFunction[T:TypeInformation, ACC:TypeInformation](
+ def addFunction[T: TypeInformation, ACC: TypeInformation](
name: String,
function: AggregateFunction[T, ACC]): Unit = {
- tEnv.registerFunction(name, function)
+ tableEnv.registerFunction(name, function)
}
def verifySql(query: String, expected: String): Unit = {
- verifyTable(tEnv.sql(query), expected)
+ verifyTable(tableEnv.sql(query), expected)
}
def verifyTable(resultTable: Table, expected: String): Unit = {
val relNode = resultTable.getRelNode
- val optimized = tEnv.optimize(relNode)
+ val optimized = tableEnv.optimize(relNode)
val actual = RelOptUtil.toString(optimized)
assertEquals(
expected.split("\n").map(_.trim).mkString("\n"),
@@ -180,22 +195,24 @@ case class BatchTableTestUtil() extends TableTestUtil {
def printTable(resultTable: Table): Unit = {
val relNode = resultTable.getRelNode
- val optimized = tEnv.optimize(relNode)
+ val optimized = tableEnv.optimize(relNode)
println(RelOptUtil.toString(optimized))
}
def printSql(query: String): Unit = {
- printTable(tEnv.sql(query))
+ printTable(tableEnv.sql(query))
}
+
}
case class StreamTableTestUtil() extends TableTestUtil {
val javaEnv = mock(classOf[JStreamExecutionEnvironment])
when(javaEnv.getStreamTimeCharacteristic).thenReturn(TimeCharacteristic.EventTime)
+ val javaTableEnv = TableEnvironment.getTableEnvironment(javaEnv)
val env = mock(classOf[StreamExecutionEnvironment])
when(env.getWrappedStreamExecutionEnvironment).thenReturn(javaEnv)
- val tEnv = TableEnvironment.getTableEnvironment(env)
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
def addTable[T: TypeInformation](
name: String,
@@ -208,8 +225,18 @@ case class StreamTableTestUtil() extends TableTestUtil {
val typeInfo: TypeInformation[T] = implicitly[TypeInformation[T]]
when(jDs.getType).thenReturn(typeInfo)
- val t = ds.toTable(tEnv, fields: _*)
- tEnv.registerTable(name, t)
+ val t = ds.toTable(tableEnv, fields: _*)
+ tableEnv.registerTable(name, t)
+ t
+ }
+
+ def addJavaTable[T](typeInfo: TypeInformation[T], name: String, fields: String): Table = {
+
+ val jDs = mock(classOf[JDataStream[T]])
+ when(jDs.getType).thenReturn(typeInfo)
+
+ val t = javaTableEnv.fromDataStream(jDs, fields)
+ javaTableEnv.registerTable(name, t)
t
}
@@ -217,27 +244,27 @@ case class StreamTableTestUtil() extends TableTestUtil {
name: String,
function: TableFunction[T])
: TableFunction[T] = {
- tEnv.registerFunction(name, function)
+ tableEnv.registerFunction(name, function)
function
}
def addFunction(name: String, function: ScalarFunction): Unit = {
- tEnv.registerFunction(name, function)
+ tableEnv.registerFunction(name, function)
}
- def addFunction[T:TypeInformation, ACC:TypeInformation](
+ def addFunction[T: TypeInformation, ACC: TypeInformation](
name: String,
function: AggregateFunction[T, ACC]): Unit = {
- tEnv.registerFunction(name, function)
+ tableEnv.registerFunction(name, function)
}
def verifySql(query: String, expected: String): Unit = {
- verifyTable(tEnv.sql(query), expected)
+ verifyTable(tableEnv.sql(query), expected)
}
def verifyTable(resultTable: Table, expected: String): Unit = {
val relNode = resultTable.getRelNode
- val optimized = tEnv.optimize(relNode, updatesAsRetraction = false)
+ val optimized = tableEnv.optimize(relNode, updatesAsRetraction = false)
val actual = RelOptUtil.toString(optimized)
assertEquals(
expected.split("\n").map(_.trim).mkString("\n"),
@@ -247,11 +274,12 @@ case class StreamTableTestUtil() extends TableTestUtil {
// the print methods are for debugging purposes only
def printTable(resultTable: Table): Unit = {
val relNode = resultTable.getRelNode
- val optimized = tEnv.optimize(relNode, updatesAsRetraction = false)
+ val optimized = tableEnv.optimize(relNode, updatesAsRetraction = false)
println(RelOptUtil.toString(optimized))
}
def printSql(query: String): Unit = {
- printTable(tEnv.sql(query))
+ printTable(tableEnv.sql(query))
}
+
}
[21/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala
deleted file mode 100644
index 2f9549e..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.java.utils.Pojos.Pojo1
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableEnvironment, Types}
-import org.apache.flink.table.calcite.table.RelTimeIndicatorConverterTest.TableFunc
-import org.apache.flink.table.expressions.{ExpressionParser, TimeIntervalUnit}
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.runtime.datastream.table.TimeAttributesITCase._
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-/**
- * Tests for access and materialization of time attributes.
- */
-class TimeAttributesITCase extends StreamingMultipleProgramsTestBase {
-
- val data = List(
- (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
- (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
- (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
- (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
- (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
- (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
- (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
-
- @Test
- def testCalcMaterialization(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table.select('rowtime.cast(Types.STRING))
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.001",
- "1970-01-01 00:00:00.002",
- "1970-01-01 00:00:00.003",
- "1970-01-01 00:00:00.004",
- "1970-01-01 00:00:00.007",
- "1970-01-01 00:00:00.008",
- "1970-01-01 00:00:00.016")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testCalcMaterialization2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table
- .filter('rowtime.cast(Types.LONG) > 4)
- .select('rowtime, 'rowtime.floor(TimeIntervalUnit.DAY), 'rowtime.ceil(TimeIntervalUnit.DAY))
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.007,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
- "1970-01-01 00:00:00.008,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
- "1970-01-01 00:00:00.016,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testTableFunction(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(
- tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
- val func = new TableFunc
-
- val t = table.join(func('rowtime, 'proctime, 'string) as 's).select('rowtime, 's)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.001,1trueHi",
- "1970-01-01 00:00:00.002,2trueHallo",
- "1970-01-01 00:00:00.003,3trueHello",
- "1970-01-01 00:00:00.004,4trueHello",
- "1970-01-01 00:00:00.007,7trueHello",
- "1970-01-01 00:00:00.008,8trueHello world",
- "1970-01-01 00:00:00.016,16trueHello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testWindowAfterTableFunction(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(
- tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
- val func = new TableFunc
-
- val t = table
- .join(func('rowtime, 'proctime, 'string) as 's)
- .window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.rowtime, 's.count)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.004,4",
- "1970-01-01 00:00:00.009,2",
- "1970-01-01 00:00:00.019,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(
- tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table.unionAll(table).select('rowtime)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.001",
- "1970-01-01 00:00:00.001",
- "1970-01-01 00:00:00.002",
- "1970-01-01 00:00:00.002",
- "1970-01-01 00:00:00.003",
- "1970-01-01 00:00:00.003",
- "1970-01-01 00:00:00.004",
- "1970-01-01 00:00:00.004",
- "1970-01-01 00:00:00.007",
- "1970-01-01 00:00:00.007",
- "1970-01-01 00:00:00.008",
- "1970-01-01 00:00:00.008",
- "1970-01-01 00:00:00.016",
- "1970-01-01 00:00:00.016")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testWindowWithAggregationOnRowtimeSql(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- tEnv.registerTable("MyTable", table)
-
- val t = tEnv.sql("SELECT COUNT(`rowtime`) FROM MyTable " +
- "GROUP BY TUMBLE(rowtime, INTERVAL '0.003' SECOND)")
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1",
- "2",
- "2",
- "2"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testMultiWindow(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table
- .window(Tumble over 2.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.rowtime as 'rowtime, 'int.count as 'int)
- .window(Tumble over 4.millis on 'rowtime as 'w2)
- .groupBy('w2)
- .select('w2.rowtime, 'w2.end, 'int.count)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.003,1970-01-01 00:00:00.004,2",
- "1970-01-01 00:00:00.007,1970-01-01 00:00:00.008,2",
- "1970-01-01 00:00:00.011,1970-01-01 00:00:00.012,1",
- "1970-01-01 00:00:00.019,1970-01-01 00:00:00.02,1"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testCalcMaterializationWithPojoType(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- tEnv.registerTable("T1", table)
- val querySql = "select rowtime as ts, string as msg from T1"
-
- val results = tEnv.sql(querySql).toAppendStream[Pojo1]
- results.addSink(new StreamITCase.StringSink[Pojo1])
- env.execute()
-
- val expected = Seq(
- "Pojo1{ts=1970-01-01 00:00:00.001, msg='Hi'}",
- "Pojo1{ts=1970-01-01 00:00:00.002, msg='Hallo'}",
- "Pojo1{ts=1970-01-01 00:00:00.003, msg='Hello'}",
- "Pojo1{ts=1970-01-01 00:00:00.004, msg='Hello'}",
- "Pojo1{ts=1970-01-01 00:00:00.007, msg='Hello'}",
- "Pojo1{ts=1970-01-01 00:00:00.008, msg='Hello world'}",
- "Pojo1{ts=1970-01-01 00:00:00.016, msg='Hello world'}")
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testPojoSupport(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val p1 = new TestPojo
- p1.a = 12
- p1.b = 42L
- p1.c = "Test me."
-
- val p2 = new TestPojo
- p2.a = 13
- p2.b = 43L
- p2.c = "And me."
-
- val stream = env
- .fromElements(p1, p2)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermarkPojo)
- // use aliases, swap all attributes, and skip b2
- val table = stream.toTable(tEnv, ('b as 'b).rowtime, 'c as 'c, 'a as 'a)
- // no aliases, no swapping
- val table2 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c)
- // use proctime, no skipping
- val table3 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c, 'b2, 'proctime.proctime)
-
- // Java expressions
-
- // use aliases, swap all attributes, and skip b2
- val table4 = stream.toTable(
- tEnv,
- ExpressionParser.parseExpressionList("(b as b).rowtime, c as c, a as a"): _*)
- // no aliases, no swapping
- val table5 = stream.toTable(
- tEnv,
- ExpressionParser.parseExpressionList("a, b.rowtime, c"): _*)
-
- val t = table.select('b, 'c , 'a)
- .unionAll(table2.select('b, 'c, 'a))
- .unionAll(table3.select('b, 'c, 'a))
- .unionAll(table4.select('b, 'c, 'a))
- .unionAll(table5.select('b, 'c, 'a))
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
-
-object TimeAttributesITCase {
- class TimestampWithEqualWatermark
- extends AssignerWithPunctuatedWatermarks[(Long, Int, Double, Float, BigDecimal, String)] {
-
- override def checkAndGetNextWatermark(
- lastElement: (Long, Int, Double, Float, BigDecimal, String),
- extractedTimestamp: Long)
- : Watermark = {
- new Watermark(extractedTimestamp)
- }
-
- override def extractTimestamp(
- element: (Long, Int, Double, Float, BigDecimal, String),
- previousElementTimestamp: Long): Long = {
- element._1
- }
- }
-
- class TimestampWithEqualWatermarkPojo
- extends AssignerWithPunctuatedWatermarks[TestPojo] {
-
- override def checkAndGetNextWatermark(
- lastElement: TestPojo,
- extractedTimestamp: Long)
- : Watermark = {
- new Watermark(extractedTimestamp)
- }
-
- override def extractTimestamp(
- element: TestPojo,
- previousElementTimestamp: Long): Long = {
- element.b
- }
- }
-
- class TestPojo() {
- var a: Int = _
- var b: Long = _
- var b2: String = "skip me"
- var c: String = _
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala
deleted file mode 100644
index f58b8a2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class UnionITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'd, 'e, 'f)
-
- val unionDs = ds1.unionAll(ds2).select('c)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Hi", "Hello", "Hello world", "Hi", "Hello", "Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnionWithFilter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
-
- val unionDs = ds1.unionAll(ds2.select('a, 'b, 'c)).filter('b < 2).select('c)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Hi", "Hallo")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala
deleted file mode 100644
index f438588..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.runtime.datastream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.expressions.utils.{Func13, Func18, RichFunc2}
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.utils._
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.{Before, Test}
-
-import scala.collection.mutable
-
-class UserDefinedFunctionITCase extends StreamingMultipleProgramsTestBase {
-
- val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv: StreamTableEnvironment = TableEnvironment.getTableEnvironment(env)
-
- @Before
- def clear(): Unit = {
- StreamITCase.clear
- }
-
- @Test
- def testCrossJoin(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
- val pojoFunc0 = new PojoTableFunc()
-
- val result = t
- .join(func0('c) as('d, 'e))
- .select('c, 'd, 'e)
- .join(pojoFunc0('c))
- .where('age > 20)
- .select('c, 'name, 'age)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Jack#22,Jack,22", "Anna#44,Anna,44")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = t
- .leftOuterJoin(func0('c) as('d, 'e))
- .select('c, 'd, 'e)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "nosharp,null,null", "Jack#22,Jack,22",
- "John#19,John,19", "Anna#44,Anna,44")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = t
- .join(func0('c) as('d, 'e))
- .where(Func18('d, "J"))
- .select('c, 'd, 'e)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Jack#22,Jack,22", "John#19,John,19")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUserDefinedTableFunctionWithParameter(): Unit = {
- val tableFunc1 = new RichTableFunc1
- tEnv.registerFunction("RichTableFunc1", tableFunc1)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> " "))
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.getSmall3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(tableFunc1('c) as 's)
- .select('a, 's)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("3,Hello", "3,world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUserDefinedTableFunctionWithUserDefinedScalarFunction(): Unit = {
- val tableFunc1 = new RichTableFunc1
- val richFunc2 = new RichFunc2
- tEnv.registerFunction("RichTableFunc1", tableFunc1)
- tEnv.registerFunction("RichFunc2", richFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(
- env,
- Map("word_separator" -> "#", "string.value" -> "test"))
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.getSmall3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(tableFunc1(richFunc2('c)) as 's)
- .select('a, 's)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,Hi",
- "1,test",
- "2,Hello",
- "2,test",
- "3,Hello world",
- "3,test")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testTableFunctionConstructorWithParams(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val config = Map("key1" -> "value1", "key2" -> "value2")
- val func30 = new TableFunc3(null)
- val func31 = new TableFunc3("OneConf_")
- val func32 = new TableFunc3("TwoConf_", config)
-
- val result = t
- .join(func30('c) as('d, 'e))
- .select('c, 'd, 'e)
- .join(func31('c) as ('f, 'g))
- .select('c, 'd, 'e, 'f, 'g)
- .join(func32('c) as ('h, 'i))
- .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Anna#44,Anna,OneConf_Anna,TwoConf__key=key1_value=value1_Anna,44,44,44",
- "Anna#44,Anna,OneConf_Anna,TwoConf__key=key2_value=value2_Anna,44,44,44",
- "Jack#22,Jack,OneConf_Jack,TwoConf__key=key1_value=value1_Jack,22,22,22",
- "Jack#22,Jack,OneConf_Jack,TwoConf__key=key2_value=value2_Jack,22,22,22",
- "John#19,John,OneConf_John,TwoConf__key=key1_value=value1_John,19,19,19",
- "John#19,John,OneConf_John,TwoConf__key=key2_value=value2_John,19,19,19"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testScalarFunctionConstructorWithParams(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new Func13("default")
- val func1 = new Func13("Sunny")
- val func2 = new Func13("kevin2")
-
- val result = t.select(func0('c), func1('c),func2('c))
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44",
- "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22",
- "default-John#19,Sunny-John#19,kevin2-John#19",
- "default-nosharp,Sunny-nosharp,kevin2-nosharp"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testTableFunctionWithVariableArguments(): Unit = {
- val varArgsFunc0 = new VarArgsFunc0
- tEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
-
- val result = testData(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .select('c)
- .join(varArgsFunc0("1", "2", 'c))
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Anna#44,1",
- "Anna#44,2",
- "Anna#44,Anna#44",
- "Jack#22,1",
- "Jack#22,2",
- "Jack#22,Jack#22",
- "John#19,1",
- "John#19,2",
- "John#19,John#19",
- "nosharp,1",
- "nosharp,2",
- "nosharp,nosharp")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- private def testData(
- env: StreamExecutionEnvironment)
- : DataStream[(Int, Long, String)] = {
-
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Jack#22"))
- data.+=((2, 2L, "John#19"))
- data.+=((3, 2L, "Anna#44"))
- data.+=((4, 3L, "nosharp"))
- env.fromCollection(data)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/HarnessTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/HarnessTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/HarnessTestBase.scala
index 7ffc5f9..80ff55e 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/HarnessTestBase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/HarnessTestBase.scala
@@ -36,13 +36,13 @@ import org.apache.flink.table.runtime.types.{CRow, CRowTypeInfo}
class HarnessTestBase {
- val longMinWithRetractAggFunction =
+ val longMinWithRetractAggFunction: String =
UserDefinedFunctionUtils.serialize(new LongMinWithRetractAggFunction)
- val longMaxWithRetractAggFunction =
+ val longMaxWithRetractAggFunction: String =
UserDefinedFunctionUtils.serialize(new LongMaxWithRetractAggFunction)
- val intSumWithRetractAggFunction =
+ val intSumWithRetractAggFunction: String =
UserDefinedFunctionUtils.serialize(new IntSumWithRetractAggFunction)
protected val MinMaxRowType = new RowTypeInfo(Array[TypeInformation[_]](
@@ -62,11 +62,11 @@ class HarnessTestBase {
protected val minMaxCRowType = new CRowTypeInfo(MinMaxRowType)
protected val sumCRowType = new CRowTypeInfo(SumRowType)
- protected val minMaxAggregates =
+ protected val minMaxAggregates: Array[AggregateFunction[_, _]] =
Array(new LongMinWithRetractAggFunction,
new LongMaxWithRetractAggFunction).asInstanceOf[Array[AggregateFunction[_, _]]]
- protected val sumAggregates =
+ protected val sumAggregates: Array[AggregateFunction[_, _]] =
Array(new IntSumWithRetractAggFunction).asInstanceOf[Array[AggregateFunction[_, _]]]
protected val minMaxAggregationStateType: RowTypeInfo =
@@ -90,11 +90,11 @@ class HarnessTestBase {
|
| fmin = (org.apache.flink.table.functions.aggfunctions.LongMinWithRetractAggFunction)
| org.apache.flink.table.functions.utils.UserDefinedFunctionUtils
- | .deserialize("${longMinWithRetractAggFunction}");
+ | .deserialize("$longMinWithRetractAggFunction");
|
| fmax = (org.apache.flink.table.functions.aggfunctions.LongMaxWithRetractAggFunction)
| org.apache.flink.table.functions.utils.UserDefinedFunctionUtils
- | .deserialize("${longMaxWithRetractAggFunction}");
+ | .deserialize("$longMaxWithRetractAggFunction");
| }
|
| public void setAggregationResults(
@@ -207,7 +207,7 @@ class HarnessTestBase {
|
|sum = (org.apache.flink.table.functions.aggfunctions.IntSumWithRetractAggFunction)
|org.apache.flink.table.functions.utils.UserDefinedFunctionUtils
- |.deserialize("${intSumWithRetractAggFunction}");
+ |.deserialize("$intSumWithRetractAggFunction");
|}
|
| public final void setAggregationResults(
@@ -351,5 +351,4 @@ object HarnessTestBase {
value.row.getField(selectorField).asInstanceOf[T]
}
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/SortProcessFunctionHarnessTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/SortProcessFunctionHarnessTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/SortProcessFunctionHarnessTest.scala
new file mode 100644
index 0000000..0451534
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/harness/SortProcessFunctionHarnessTest.scala
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.harness
+
+import java.lang.{Integer => JInt, Long => JLong}
+import java.util.concurrent.ConcurrentLinkedQueue
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo._
+import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
+import org.apache.flink.api.common.typeutils.{TypeComparator, TypeSerializer}
+import org.apache.flink.api.java.functions.KeySelector
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.java.typeutils.runtime.RowComparator
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.operators.KeyedProcessOperator
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.streaming.runtime.streamrecord.StreamRecord
+import org.apache.flink.streaming.util.{KeyedOneInputStreamOperatorTestHarness, TestHarnessUtil}
+import org.apache.flink.table.runtime.aggregate.{CollectionRowComparator, ProcTimeSortProcessFunction, RowTimeSortProcessFunction}
+import org.apache.flink.table.runtime.harness.SortProcessFunctionHarnessTest.TupleRowSelector
+import org.apache.flink.table.runtime.types.{CRow, CRowTypeInfo}
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class SortProcessFunctionHarnessTest {
+
+ @Test
+ def testSortProcTimeHarnessPartitioned(): Unit = {
+
+ val rT = new RowTypeInfo(Array[TypeInformation[_]](
+ INT_TYPE_INFO,
+ LONG_TYPE_INFO,
+ INT_TYPE_INFO,
+ STRING_TYPE_INFO,
+ LONG_TYPE_INFO),
+ Array("a", "b", "c", "d", "e"))
+
+ val indexes = Array(1, 2)
+
+ val fieldComps = Array[TypeComparator[AnyRef]](
+ LONG_TYPE_INFO.createComparator(true, null).asInstanceOf[TypeComparator[AnyRef]],
+ INT_TYPE_INFO.createComparator(false, null).asInstanceOf[TypeComparator[AnyRef]] )
+ val booleanOrders = Array(true, false)
+
+
+ val rowComp = new RowComparator(
+ rT.getTotalFields,
+ indexes,
+ fieldComps,
+ new Array[TypeSerializer[AnyRef]](0), //used only for serialized comparisons
+ booleanOrders)
+
+ val collectionRowComparator = new CollectionRowComparator(rowComp)
+
+ val inputCRowType = CRowTypeInfo(rT)
+
+ val processFunction = new KeyedProcessOperator[Integer,CRow,CRow](
+ new ProcTimeSortProcessFunction(
+ inputCRowType,
+ collectionRowComparator))
+
+ val testHarness = new KeyedOneInputStreamOperatorTestHarness[Integer,CRow,CRow](
+ processFunction,
+ new TupleRowSelector(0),
+ BasicTypeInfo.INT_TYPE_INFO)
+
+ testHarness.open()
+
+ testHarness.setProcessingTime(3)
+
+ // timestamp is ignored in processing time
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong), true), 1001))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2002))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2003))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2004))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2006))
+
+ //move the timestamp to ensure the execution
+ testHarness.setProcessingTime(1005)
+
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 1L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2007))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 3L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2007))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 2L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2007))
+
+ testHarness.setProcessingTime(1008)
+
+ val result = testHarness.getOutput
+
+ val expectedOutput = new ConcurrentLinkedQueue[Object]()
+
+ // all elements at the same proc timestamp have the same value
+ // elements should be sorted ascending on field 1 and descending on field 2
+ // (10,0) (11,1) (12,2) (12,1) (12,0)
+ // (1,0) (2,0)
+
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong),true), 4))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong),true), 4))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 2: JInt, "aaa", 11L: JLong),true), 4))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong),true), 4))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 0: JInt, "aaa", 11L: JLong),true), 4))
+
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 1L: JLong, 0: JInt, "aaa", 11L: JLong),true), 1006))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 2L: JLong, 0: JInt, "aaa", 11L: JLong),true), 1006))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 3L: JLong, 0: JInt, "aaa", 11L: JLong),true), 1006))
+
+ TestHarnessUtil.assertOutputEquals("Output was not correctly sorted.", expectedOutput, result)
+
+ testHarness.close()
+ }
+
+ @Test
+ def testSortRowTimeHarnessPartitioned(): Unit = {
+
+ val rT = new RowTypeInfo(Array[TypeInformation[_]](
+ INT_TYPE_INFO,
+ LONG_TYPE_INFO,
+ INT_TYPE_INFO,
+ STRING_TYPE_INFO,
+ LONG_TYPE_INFO),
+ Array("a", "b", "c", "d", "e"))
+
+ val indexes = Array(1, 2)
+
+ val fieldComps = Array[TypeComparator[AnyRef]](
+ LONG_TYPE_INFO.createComparator(true, null).asInstanceOf[TypeComparator[AnyRef]],
+ INT_TYPE_INFO.createComparator(false, null).asInstanceOf[TypeComparator[AnyRef]] )
+ val booleanOrders = Array(true, false)
+
+ val rowComp = new RowComparator(
+ rT.getTotalFields,
+ indexes,
+ fieldComps,
+ new Array[TypeSerializer[AnyRef]](0), //used only for serialized comparisons
+ booleanOrders)
+
+ val collectionRowComparator = new CollectionRowComparator(rowComp)
+
+ val inputCRowType = CRowTypeInfo(rT)
+
+ val processFunction = new KeyedProcessOperator[Integer,CRow,CRow](
+ new RowTimeSortProcessFunction(
+ inputCRowType,
+ Some(collectionRowComparator)))
+
+ val testHarness = new KeyedOneInputStreamOperatorTestHarness[Integer, CRow, CRow](
+ processFunction,
+ new TupleRowSelector(0),
+ BasicTypeInfo.INT_TYPE_INFO)
+
+ testHarness.open()
+
+ testHarness.setTimeCharacteristic(TimeCharacteristic.EventTime)
+ testHarness.processWatermark(3)
+
+ // timestamp is ignored in processing time
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong), true), 1001))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2002))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 13L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2002))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong), true), 2002))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 14L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2002))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong), true), 2004))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2006))
+
+ // move watermark forward
+ testHarness.processWatermark(2007)
+
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 20L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2008))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 14L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2002)) // too late
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong), true), 2019)) // too early
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 20L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2008))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2010))
+ testHarness.processElement(new StreamRecord(new CRow(
+ Row.of(1: JInt, 19L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2008))
+
+ // move watermark forward
+ testHarness.processWatermark(2012)
+
+ val result = testHarness.getOutput
+
+ val expectedOutput = new ConcurrentLinkedQueue[Object]()
+
+ // all elements at the same proc timestamp have the same value
+ // elements should be sorted ascending on field 1 and descending on field 2
+ // (10,0) (11,1) (12,2) (12,1) (12,0)
+ expectedOutput.add(new Watermark(3))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong),true), 1001))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong),true), 2002))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong),true), 2002))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 13L: JLong, 2: JInt, "aaa", 11L: JLong),true), 2002))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 14L: JLong, 0: JInt, "aaa", 11L: JLong),true), 2002))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong),true), 2004))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong),true), 2006))
+ expectedOutput.add(new Watermark(2007))
+
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 19L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2008))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 20L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2008))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 20L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2008))
+ expectedOutput.add(new StreamRecord(new CRow(
+ Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2010))
+
+ expectedOutput.add(new Watermark(2012))
+
+ TestHarnessUtil.assertOutputEquals("Output was not correctly sorted.", expectedOutput, result)
+
+ testHarness.close()
+
+ }
+}
+
+object SortProcessFunctionHarnessTest {
+
+ /**
+ * Simple test class that returns a specified field as the selector function
+ */
+ class TupleRowSelector(private val selectorField: Int) extends KeySelector[CRow, Integer] {
+
+ override def getKey(value: CRow): Integer = {
+ value.row.getField(selectorField).asInstanceOf[Integer]
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/TimeAttributesITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/TimeAttributesITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/TimeAttributesITCase.scala
new file mode 100644
index 0000000..4c478de
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/TimeAttributesITCase.scala
@@ -0,0 +1,407 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.runtime.utils.JavaPojos.Pojo1
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.plan.TimeIndicatorConversionTest.TableFunc
+import org.apache.flink.table.api.{TableEnvironment, Types}
+import org.apache.flink.table.expressions.{ExpressionParser, TimeIntervalUnit}
+import org.apache.flink.table.runtime.stream.TimeAttributesITCase.{TestPojo, TimestampWithEqualWatermark, TimestampWithEqualWatermarkPojo}
+import org.apache.flink.table.runtime.utils.StreamITCase
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+/**
+ * Tests for access and materialization of time attributes.
+ */
+class TimeAttributesITCase extends StreamingMultipleProgramsTestBase {
+
+ val data = List(
+ (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
+ (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
+ (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
+ (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
+ (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
+ (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
+ (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
+
+ @Test
+ def testCalcMaterialization(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table.select('rowtime.cast(Types.STRING))
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.001",
+ "1970-01-01 00:00:00.002",
+ "1970-01-01 00:00:00.003",
+ "1970-01-01 00:00:00.004",
+ "1970-01-01 00:00:00.007",
+ "1970-01-01 00:00:00.008",
+ "1970-01-01 00:00:00.016")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testCalcMaterialization2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table
+ .filter('rowtime.cast(Types.LONG) > 4)
+ .select('rowtime, 'rowtime.floor(TimeIntervalUnit.DAY), 'rowtime.ceil(TimeIntervalUnit.DAY))
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.007,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
+ "1970-01-01 00:00:00.008,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
+ "1970-01-01 00:00:00.016,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testTableFunction(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(
+ tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
+ val func = new TableFunc
+
+ val t = table.join(func('rowtime, 'proctime, 'string) as 's).select('rowtime, 's)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.001,1trueHi",
+ "1970-01-01 00:00:00.002,2trueHallo",
+ "1970-01-01 00:00:00.003,3trueHello",
+ "1970-01-01 00:00:00.004,4trueHello",
+ "1970-01-01 00:00:00.007,7trueHello",
+ "1970-01-01 00:00:00.008,8trueHello world",
+ "1970-01-01 00:00:00.016,16trueHello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testWindowAfterTableFunction(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(
+ tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
+ val func = new TableFunc
+
+ val t = table
+ .join(func('rowtime, 'proctime, 'string) as 's)
+ .window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.rowtime, 's.count)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.004,4",
+ "1970-01-01 00:00:00.009,2",
+ "1970-01-01 00:00:00.019,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(
+ tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table.unionAll(table).select('rowtime)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.001",
+ "1970-01-01 00:00:00.001",
+ "1970-01-01 00:00:00.002",
+ "1970-01-01 00:00:00.002",
+ "1970-01-01 00:00:00.003",
+ "1970-01-01 00:00:00.003",
+ "1970-01-01 00:00:00.004",
+ "1970-01-01 00:00:00.004",
+ "1970-01-01 00:00:00.007",
+ "1970-01-01 00:00:00.007",
+ "1970-01-01 00:00:00.008",
+ "1970-01-01 00:00:00.008",
+ "1970-01-01 00:00:00.016",
+ "1970-01-01 00:00:00.016")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testWindowWithAggregationOnRowtimeSql(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ tEnv.registerTable("MyTable", table)
+
+ val t = tEnv.sql("SELECT COUNT(`rowtime`) FROM MyTable " +
+ "GROUP BY TUMBLE(rowtime, INTERVAL '0.003' SECOND)")
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1",
+ "2",
+ "2",
+ "2"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testMultiWindow(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table
+ .window(Tumble over 2.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.rowtime as 'rowtime, 'int.count as 'int)
+ .window(Tumble over 4.millis on 'rowtime as 'w2)
+ .groupBy('w2)
+ .select('w2.rowtime, 'w2.end, 'int.count)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.003,1970-01-01 00:00:00.004,2",
+ "1970-01-01 00:00:00.007,1970-01-01 00:00:00.008,2",
+ "1970-01-01 00:00:00.011,1970-01-01 00:00:00.012,1",
+ "1970-01-01 00:00:00.019,1970-01-01 00:00:00.02,1"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testCalcMaterializationWithPojoType(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ tEnv.registerTable("T1", table)
+ val querySql = "select rowtime as ts, string as msg from T1"
+
+ val results = tEnv.sql(querySql).toAppendStream[Pojo1]
+ results.addSink(new StreamITCase.StringSink[Pojo1])
+ env.execute()
+
+ val expected = Seq(
+ "Pojo1{ts=1970-01-01 00:00:00.001, msg='Hi'}",
+ "Pojo1{ts=1970-01-01 00:00:00.002, msg='Hallo'}",
+ "Pojo1{ts=1970-01-01 00:00:00.003, msg='Hello'}",
+ "Pojo1{ts=1970-01-01 00:00:00.004, msg='Hello'}",
+ "Pojo1{ts=1970-01-01 00:00:00.007, msg='Hello'}",
+ "Pojo1{ts=1970-01-01 00:00:00.008, msg='Hello world'}",
+ "Pojo1{ts=1970-01-01 00:00:00.016, msg='Hello world'}")
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testPojoSupport(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val p1 = new TestPojo
+ p1.a = 12
+ p1.b = 42L
+ p1.c = "Test me."
+
+ val p2 = new TestPojo
+ p2.a = 13
+ p2.b = 43L
+ p2.c = "And me."
+
+ val stream = env
+ .fromElements(p1, p2)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermarkPojo)
+ // use aliases, swap all attributes, and skip b2
+ val table = stream.toTable(tEnv, ('b as 'b).rowtime, 'c as 'c, 'a as 'a)
+ // no aliases, no swapping
+ val table2 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c)
+ // use proctime, no skipping
+ val table3 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c, 'b2, 'proctime.proctime)
+
+ // Java expressions
+
+ // use aliases, swap all attributes, and skip b2
+ val table4 = stream.toTable(
+ tEnv,
+ ExpressionParser.parseExpressionList("(b as b).rowtime, c as c, a as a"): _*)
+ // no aliases, no swapping
+ val table5 = stream.toTable(
+ tEnv,
+ ExpressionParser.parseExpressionList("a, b.rowtime, c"): _*)
+
+ val t = table.select('b, 'c , 'a)
+ .unionAll(table2.select('b, 'c, 'a))
+ .unionAll(table3.select('b, 'c, 'a))
+ .unionAll(table4.select('b, 'c, 'a))
+ .unionAll(table5.select('b, 'c, 'a))
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
+
+object TimeAttributesITCase {
+ class TimestampWithEqualWatermark
+ extends AssignerWithPunctuatedWatermarks[(Long, Int, Double, Float, BigDecimal, String)] {
+
+ override def checkAndGetNextWatermark(
+ lastElement: (Long, Int, Double, Float, BigDecimal, String),
+ extractedTimestamp: Long)
+ : Watermark = {
+ new Watermark(extractedTimestamp)
+ }
+
+ override def extractTimestamp(
+ element: (Long, Int, Double, Float, BigDecimal, String),
+ previousElementTimestamp: Long): Long = {
+ element._1
+ }
+ }
+
+ class TimestampWithEqualWatermarkPojo
+ extends AssignerWithPunctuatedWatermarks[TestPojo] {
+
+ override def checkAndGetNextWatermark(
+ lastElement: TestPojo,
+ extractedTimestamp: Long)
+ : Watermark = {
+ new Watermark(extractedTimestamp)
+ }
+
+ override def extractTimestamp(
+ element: TestPojo,
+ previousElementTimestamp: Long): Long = {
+ element.b
+ }
+ }
+
+ class TestPojo() {
+ var a: Int = _
+ var b: Long = _
+ var b2: String = "skip me"
+ var c: String = _
+ }
+}
[36/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala
deleted file mode 100644
index cc9d786..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMerge
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.plan.logical._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.junit.Test
-
-class WindowAggregateTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- streamUtil.addTable[(Int, String, Long)](
- "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
-
- @Test
- def testGroupbyWithoutWindow() = {
- val sql = "SELECT COUNT(a) FROM MyTable GROUP BY b"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "b", "a")
- ),
- term("groupBy", "b"),
- term("select", "b", "COUNT(a) AS EXPR$0")
- ),
- term("select", "EXPR$0")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testTumbleFunction() = {
- streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
-
- val sql =
- "SELECT " +
- " COUNT(*), weightedAvg(c, a) AS wAvg, " +
- " TUMBLE_START(rowtime, INTERVAL '15' MINUTE), " +
- " TUMBLE_END(rowtime, INTERVAL '15' MINUTE)" +
- "FROM MyTable " +
- "GROUP BY TUMBLE(rowtime, INTERVAL '15' MINUTE)"
- val expected =
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "rowtime", "c", "a")
- ),
- term("window", TumblingGroupWindow('w$, 'rowtime, 900000.millis)),
- term("select",
- "COUNT(*) AS EXPR$0, " +
- "weightedAvg(c, a) AS wAvg, " +
- "start('w$) AS w$start, " +
- "end('w$) AS w$end")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testHoppingFunction() = {
- streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
-
- val sql =
- "SELECT COUNT(*), weightedAvg(c, a) AS wAvg, " +
- " HOP_START(proctime, INTERVAL '15' MINUTE, INTERVAL '1' HOUR), " +
- " HOP_END(proctime, INTERVAL '15' MINUTE, INTERVAL '1' HOUR) " +
- "FROM MyTable " +
- "GROUP BY HOP(proctime, INTERVAL '15' MINUTE, INTERVAL '1' HOUR)"
- val expected =
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "proctime", "c", "a")
- ),
- term("window", SlidingGroupWindow('w$, 'proctime, 3600000.millis, 900000.millis)),
- term("select",
- "COUNT(*) AS EXPR$0, " +
- "weightedAvg(c, a) AS wAvg, " +
- "start('w$) AS w$start, " +
- "end('w$) AS w$end")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testSessionFunction() = {
- streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
-
- val sql =
- "SELECT " +
- " COUNT(*), weightedAvg(c, a) AS wAvg, " +
- " SESSION_START(proctime, INTERVAL '15' MINUTE), " +
- " SESSION_END(proctime, INTERVAL '15' MINUTE) " +
- "FROM MyTable " +
- "GROUP BY SESSION(proctime, INTERVAL '15' MINUTE)"
- val expected =
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "proctime", "c", "a")
- ),
- term("window", SessionGroupWindow('w$, 'proctime, 900000.millis)),
- term("select",
- "COUNT(*) AS EXPR$0, " +
- "weightedAvg(c, a) AS wAvg, " +
- "start('w$) AS w$start, " +
- "end('w$) AS w$end")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testExpressionOnWindowAuxFunction() = {
- val sql =
- "SELECT " +
- " COUNT(*), " +
- " TUMBLE_END(rowtime, INTERVAL '15' MINUTE) + INTERVAL '1' MINUTE " +
- "FROM MyTable " +
- "GROUP BY TUMBLE(rowtime, INTERVAL '15' MINUTE)"
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "rowtime")
- ),
- term("window", TumblingGroupWindow('w$, 'rowtime, 900000.millis)),
- term("select", "COUNT(*) AS EXPR$0", "start('w$) AS w$start", "end('w$) AS w$end")
- ),
- term("select", "EXPR$0", "DATETIME_PLUS(w$end, 60000) AS $f1")
- )
-
- streamUtil.verifySql(sql, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala
deleted file mode 100644
index b1efc09..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql.validation
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.typeutils.CaseClassTypeInfo
-import org.apache.flink.table.api.{Types, ValidationException}
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil.{streamTableNode, term, unaryNode}
-import org.apache.flink.table.expressions.AggFunctionCall
-import org.apache.flink.table.functions.AggregateFunction
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert.{assertEquals, assertTrue}
-import org.junit.{Ignore, Test}
-
-class AggregationsValidationTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c)
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- streamUtil.addFunction("overAgg", new OverAgg0)
-
- val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
-
- streamUtil.tableEnv.sql(sqlQuery)
- }
-
- @Test
- def testDistinct(): Unit = {
- val sql = "SELECT DISTINCT a, b, c FROM MyTable"
-
- val expected =
- unaryNode(
- "DataStreamGroupAggregate",
- streamTableNode(0),
- term("groupBy", "a, b, c"),
- term("select", "a, b, c")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- // TODO: this query should be optimized to only have a single DataStreamGroupAggregate
- // TODO: reopen this until FLINK-7144 fixed
- @Ignore
- @Test
- def testDistinctAfterAggregate(): Unit = {
- val sql = "SELECT DISTINCT a FROM MyTable GROUP BY a, b, c"
-
- val expected =
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a")
- ),
- term("groupBy", "a"),
- term("select", "a")
- )
- streamUtil.verifySql(sql, expected)
- }
-
-
- @Test
- def testUserDefinedAggregateFunctionWithScalaAccumulator(): Unit = {
- streamUtil.addFunction("udag", new MyAgg)
- val call = streamUtil
- .tEnv
- .functionCatalog
- .lookupFunction("udag", Seq())
- .asInstanceOf[AggFunctionCall]
-
- val typeInfo = call.accTypeInfo
- assertTrue(typeInfo.isInstanceOf[CaseClassTypeInfo[_]])
- assertEquals(2, typeInfo.getTotalFields)
- val caseTypeInfo = typeInfo.asInstanceOf[CaseClassTypeInfo[_]]
- assertEquals(Types.LONG, caseTypeInfo.getTypeAt(0))
- assertEquals(Types.LONG, caseTypeInfo.getTypeAt(1))
-
- streamUtil.addFunction("udag2", new MyAgg2)
- val call2 = streamUtil
- .tEnv
- .functionCatalog
- .lookupFunction("udag2", Seq())
- .asInstanceOf[AggFunctionCall]
-
- val typeInfo2 = call2.accTypeInfo
- assertTrue(s"actual type: $typeInfo2", typeInfo2.isInstanceOf[RowTypeInfo])
- assertEquals(2, typeInfo2.getTotalFields)
- val rowTypeInfo = typeInfo2.asInstanceOf[RowTypeInfo]
- assertEquals(Types.LONG, rowTypeInfo.getTypeAt(0))
- assertEquals(Types.INT, rowTypeInfo.getTypeAt(1))
- }
-}
-
-case class MyAccumulator(var sum: Long, var count: Long)
-
-class MyAgg extends AggregateFunction[Long, MyAccumulator] {
-
- //Overloaded accumulate method
- def accumulate(acc: MyAccumulator, value: Long): Unit = {
- }
-
- override def createAccumulator(): MyAccumulator = MyAccumulator(0, 0)
-
- override def getValue(accumulator: MyAccumulator): Long = 1L
-}
-
-class MyAgg2 extends AggregateFunction[Long, Row] {
-
- def accumulate(acc: Row, value: Long): Unit = {}
-
- override def createAccumulator(): Row = new Row(2)
-
- override def getValue(accumulator: Row): Long = 1L
-
- def getAccumulatorType: TypeInformation[_] = new RowTypeInfo(Types.LONG, Types.INT)
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala
deleted file mode 100644
index 3cc13f4..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.apache.flink.types.Row
-import org.junit.Test
-
-class OverWindowValidationTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- streamUtil.addTable[(Int, String, Long)]("T1", 'a, 'b, 'c, 'proctime.proctime)
-
- /**
- * All aggregates must be computed on the same window.
- */
- @Test(expected = classOf[TableException])
- def testMultiWindow(): Unit = {
-
- val sqlQuery = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
- "sum(a) OVER (PARTITION BY b ORDER BY proctime RANGE UNBOUNDED preceding) " +
- "from T1"
-
- streamUtil.tableEnv.sql(sqlQuery).toAppendStream[Row]
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala
deleted file mode 100644
index 0fd8740..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableException, ValidationException}
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.junit.Test
-
-class WindowAggregateValidationTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- streamUtil.addTable[(Int, String, Long)](
- "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- streamUtil.addFunction("overAgg", new OverAgg0)
-
- val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
- streamUtil.tableEnv.sql(sqlQuery)
- }
-
- @Test(expected = classOf[TableException])
- def testTumbleWindowNoOffset(): Unit = {
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM MyTable " +
- "GROUP BY TUMBLE(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testHopWindowNoOffset(): Unit = {
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM MyTable " +
- "GROUP BY HOP(proctime, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testSessionWindowNoOffset(): Unit = {
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM MyTable " +
- "GROUP BY SESSION(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testVariableWindowSize() = {
- val sql = "SELECT COUNT(*) FROM MyTable GROUP BY TUMBLE(proctime, c * INTERVAL '1' MINUTE)"
- streamUtil.verifySql(sql, "n/a")
- }
-
- @Test(expected = classOf[ValidationException])
- def testWindowUdAggInvalidArgs(): Unit = {
- streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, weightedAvg(a, b) AS wAvg " +
- "FROM MyTable " +
- "GROUP BY TUMBLE(proctime(), INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala
deleted file mode 100644
index 20a88fe..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.junit.Assert.assertEquals
-import org.junit._
-
-class ExplainTest
- extends StreamingMultipleProgramsTestBase {
-
- val testFilePath = this.getClass.getResource("/").getFile
-
- @Test
- def testFilter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements((1, "hello"))
- .toTable(tEnv, 'a, 'b)
- .filter("a % 2 = 0")
-
- val result = replaceString(tEnv.explain(table))
-
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testFilterStream0.out").mkString
- val expect = replaceString(source)
- assertEquals(result, expect)
- }
-
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table = table1.unionAll(table2)
-
- val result = replaceString(tEnv.explain(table))
-
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testUnionStream0.out").mkString
- val expect = replaceString(source)
- assertEquals(result, expect)
- }
-
- def replaceString(s: String): String = {
- /* Stage {id} is ignored, because id keeps incrementing in test class
- * while StreamExecutionEnvironment is up
- */
- s.replaceAll("\\r\\n", "\n").replaceAll("Stage \\d+", "")
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala
deleted file mode 100644
index fec25eb..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala
deleted file mode 100644
index 3bf9c33..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.{Upper, WindowReference}
-import org.apache.flink.table.plan.logical.TumblingGroupWindow
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{TableTestBase, _}
-import org.junit.Test
-
-/**
- * Tests for all the situations when we can do fields projection. Like selecting few fields
- * from a large field count source.
- */
-class FieldProjectionTest extends TableTestBase {
-
- val streamUtil: StreamTableTestUtil = streamTestUtil()
-
- @Test
- def testSelectFromWindow(): Unit = {
- val sourceTable = streamUtil
- .addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
- val resultTable = sourceTable
- .window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select(Upper('c).count, 'a.sum)
-
- val expected =
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "c", "a", "rowtime", "UPPER(c) AS $f3")
- ),
- term("window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'rowtime,
- 5.millis)),
- term("select", "COUNT($f3) AS TMP_0", "SUM(a) AS TMP_1")
- )
-
- streamUtil.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectFromGroupedWindow(): Unit = {
- val sourceTable = streamUtil
- .addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
- val resultTable = sourceTable
- .window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'b)
- .select(Upper('c).count, 'a.sum, 'b)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "c", "a", "b", "rowtime", "UPPER(c) AS $f4")
- ),
- term("groupBy", "b"),
- term("window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'rowtime,
- 5.millis)),
- term("select", "b", "COUNT($f4) AS TMP_0", "SUM(a) AS TMP_1")
- ),
- term("select", "TMP_0", "TMP_1", "b")
- )
-
- streamUtil.verifyTable(resultTable, expected)
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala
deleted file mode 100644
index 791f778..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class GroupAggregationsTest extends TableTestBase {
-
- @Test
- def testGroupAggregate() = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val resultTable = table
- .groupBy('b)
- .select('a.count)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b")
- ),
- term("groupBy", "b"),
- term("select", "b", "COUNT(a) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
- util.verifyTable(resultTable, expected)
- }
-
-
- @Test
- def testGroupAggregateWithConstant1(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val resultTable = table
- .select('a, 4 as 'four, 'b)
- .groupBy('four, 'a)
- .select('four, 'b.sum)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "4 AS four", "b", "a")
- ),
- term("groupBy", "four", "a"),
- term("select", "four", "a", "SUM(b) AS TMP_0")
- ),
- term("select", "4 AS four", "TMP_0")
- )
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testGroupAggregateWithConstant2(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val resultTable = table
- .select('b, 4 as 'four, 'a)
- .groupBy('b, 'four)
- .select('four, 'a.sum)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "4 AS four", "a", "b")
- ),
- term("groupBy", "four", "b"),
- term("select", "four", "b", "SUM(a) AS TMP_0")
- ),
- term("select", "4 AS four", "TMP_0")
- )
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testGroupAggregateWithExpressionInSelect(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val resultTable = table
- .select('a as 'a, 'b % 3 as 'd, 'c as 'c)
- .groupBy('d)
- .select('c.min, 'a.avg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "MOD(b, 3) AS d", "c")
- ),
- term("groupBy", "d"),
- term("select", "d", "MIN(c) AS TMP_0", "AVG(a) AS TMP_1")
- ),
- term("select", "TMP_0", "TMP_1")
- )
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testGroupAggregateWithFilter(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val resultTable = table
- .groupBy('b)
- .select('b, 'a.sum)
- .where('b === 2)
-
- val expected =
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "b", "a"),
- term("where", "=(b, 2)")
- ),
- term("groupBy", "b"),
- term("select", "b", "SUM(a) AS TMP_0")
- )
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testGroupAggregateWithAverage(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val resultTable = table
- .groupBy('b)
- .select('b, 'a.cast(BasicTypeInfo.DOUBLE_TYPE_INFO).avg)
-
- val expected =
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "b", "a", "CAST(a) AS a0")
- ),
- term("groupBy", "b"),
- term("select", "b", "AVG(a0) AS TMP_0")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala
deleted file mode 100644
index 92c8522..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.common.time.Time
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.table.GroupWindowAggregationsITCase.TimestampAndWatermarkWithOffset
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-/**
- * We only test some aggregations until better testing of constructed DataStream
- * programs is possible.
- */
-class GroupWindowAggregationsITCase extends StreamingMultipleProgramsTestBase {
- private val queryConfig = new StreamQueryConfig()
- queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
- val data = List(
- (1L, 1, "Hi"),
- (2L, 2, "Hello"),
- (4L, 2, "Hello"),
- (8L, 3, "Hello world"),
- (16L, 3, "Hello world"))
-
- @Test
- def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
-
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, countFun('int), 'int.avg,
- weightAvgFun('long, 'int), weightAvgFun('int, 'int))
-
- val results = windowedTable.toAppendStream[Row](queryConfig)
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("Hello world,1,3,8,3", "Hello world,2,3,12,3", "Hello,1,2,2,2",
- "Hello,2,2,3,2", "Hi,1,1,1,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSessionGroupWindowOverTime(): Unit = {
- //To verify the "merge" functionality, we create this test with the following characteristics:
- // 1. set the Parallelism to 1, and have the test data out of order
- // 2. create a waterMark with 10ms offset to delay the window emission by 10ms
- val sessionWindowTestdata = List(
- (1L, 1, "Hello"),
- (2L, 2, "Hello"),
- (8L, 8, "Hello"),
- (9L, 9, "Hello World"),
- (4L, 4, "Hello"),
- (16L, 16, "Hello"))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvgWithMerge
-
- val stream = env
- .fromCollection(sessionWindowTestdata)
- .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset(10L))
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Session withGap 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, countFun('int), 'int.avg,
- weightAvgFun('long, 'int), weightAvgFun('int, 'int))
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("Hello World,1,9,9,9", "Hello,1,16,16,16", "Hello,4,3,5,5")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w)
- .select(countFun('string), 'int.avg,
- weightAvgFun('long, 'int), weightAvgFun('int, 'int))
-
- val results = windowedTable.toAppendStream[Row](queryConfig)
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("2,1,1,1", "2,2,6,2")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeTumblingWindow(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset(0L))
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, countFun('string), 'int.avg, weightAvgFun('long, 'int),
- weightAvgFun('int, 'int), 'int.min, 'int.max, 'int.sum, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hello world,1,3,8,3,3,3,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01",
- "Hello world,1,3,16,3,3,3,3,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02",
- "Hello,2,2,3,2,2,2,4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hi,1,1,1,1,1,1,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testGroupWindowWithoutKeyInProjection(): Unit = {
- val data = List(
- (1L, 1, "Hi", 1, 1),
- (2L, 2, "Hello", 2, 2),
- (4L, 2, "Hello", 2, 2),
- (8L, 3, "Hello world", 3, 3),
- (16L, 3, "Hello world", 3, 3))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'int2, 'int3, 'proctime.proctime)
-
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'int2, 'int3, 'string)
- .select(weightAvgFun('long, 'int))
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("12", "8", "2", "3", "1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
-
-object GroupWindowAggregationsITCase {
- class TimestampAndWatermarkWithOffset(
- offset: Long) extends AssignerWithPunctuatedWatermarks[(Long, Int, String)] {
-
- override def checkAndGetNextWatermark(
- lastElement: (Long, Int, String),
- extractedTimestamp: Long)
- : Watermark = {
- new Watermark(extractedTimestamp - offset)
- }
-
- override def extractTimestamp(
- element: (Long, Int, String),
- previousElementTimestamp: Long): Long = {
- element._1
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala
deleted file mode 100644
index 6be0e13..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.WindowReference
-import org.apache.flink.table.plan.logical._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil.{streamTableNode, term, unaryNode}
-import org.junit.{Ignore, Test}
-
-class GroupWindowAggregationsTest extends TableTestBase {
-
- @Test
- def testMultiWindow(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 50.milli on 'proctime as 'w1)
- .groupBy('w1, 'string)
- .select('w1.proctime as 'proctime, 'string, 'int.count)
- .window(Slide over 20.milli every 10.milli on 'proctime as 'w2)
- .groupBy('w2)
- .select('string.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w1"),
- 'proctime,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_1", "proctime('w1) AS TMP_0")
- ),
- term("select", "string", "TMP_0 AS proctime")
- ),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w2"),
- 'proctime,
- 20.milli,
- 10.milli)),
- term("select", "COUNT(string) AS TMP_2")
- )
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 50.milli on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeTumblingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(WindowReference("w"), 'proctime, 2.rows)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'long,
- 5.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowWithUdAgg(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val weightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'rowtime,
- 5.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 2.rows,
- 1.rows)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "rowtime")
- ),
- term("groupBy", "string"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- @Ignore // see comments in DataStreamGroupWindowAggregate
- def testEventTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'long,
- 8.milli,
- 10.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowWithUdAgg(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val weightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSessionGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSessionGroupWindowWithUdAgg(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val weightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'rowtime, 7.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 50.milli on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "proctime")
- ),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 2.rows)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "rowtime")
- ),
- term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- @Ignore // see comments in DataStreamGroupWindowAggregate
- def testAllEventTimeTumblingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "long")
- ),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'long,
- 5.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "proctime")
- ),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli,
- 50.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "proctime")
- ),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 2.rows,
- 1.rows)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "rowtime")
- ),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
-// @Ignore // see comments in DataStreamGroupWindowAggregate
- def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "long")
- ),
- term("window", SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeSessionGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "long")
- ),
- term(
- "window",
- SessionGroupWindow(
- WindowReference("w"),
- 'long,
- 7.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testTumbleWindowStartEnd(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "rowtime")
- ),
- term("groupBy", "string"),
- term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
- term("select",
- "string",
- "COUNT(int) AS TMP_0",
- "start('w) AS TMP_1",
- "end('w) AS TMP_2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testSlidingWindowWithUDAF(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String, Int, Int)](
- 'long,
- 'int,
- 'string,
- 'int2,
- 'int3,
- 'proctime.proctime)
-
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'int2, 'int3, 'string)
- .select(weightAvgFun('long, 'int))
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string, int2, int3"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'proctime, 2.rows, 1.rows)),
- term(
- "select",
- "string",
- "int2",
- "int3",
- "WeightedAvg(long, int) AS TMP_0")
- ),
- term("select","TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testSlideWindowStartEnd(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 10.milli every 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "rowtime")
- ),
- term("groupBy", "string"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 10.milli, 5.milli)),
- term("select",
- "string",
- "COUNT(int) AS TMP_0",
- "start('w) AS TMP_1",
- "end('w) AS TMP_2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testSessionWindowStartWithTwoEnd(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Session withGap 3.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('w.end as 'we1, 'string, 'int.count as 'cnt, 'w.start as 'ws, 'w.end as 'we2)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'long, 3.milli)),
- term("select",
- "string",
- "COUNT(int) AS TMP_1",
- "end('w) AS TMP_0",
- "start('w) AS TMP_2")
- ),
- term("select", "TMP_0 AS we1", "string", "TMP_1 AS cnt", "TMP_2 AS ws", "TMP_0 AS we2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testTumbleWindowWithDuplicateAggsAndProps(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.millis on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.sum + 1 as 's1, 'int.sum + 3 as 's2, 'w.start as 'x, 'w.start as 'x2,
- 'w.end as 'x3, 'w.end)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.millis)),
- term("select",
- "string",
- "SUM(int) AS TMP_0",
- "start('w) AS TMP_1",
- "end('w) AS TMP_2")
- ),
- term("select",
- "string",
- "+(CAST(TMP_0), 1) AS s1",
- "+(CAST(TMP_0), 3) AS s2",
- "TMP_1 AS x",
- "TMP_1 AS x2",
- "TMP_2 AS x3",
- "TMP_2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala
deleted file mode 100644
index e11b804..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithRetract
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.Func1
-import org.apache.flink.table.api.Table
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.junit.Test
-
-class OverWindowTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- val table: Table = streamUtil.addTable[(Int, String, Long)]("MyTable",
- 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
-
- @Test
- def testScalarFunctionsOnOverWindow() = {
- val weightedAvg = new WeightedAvgWithRetract
- val plusOne = Func1
-
- val result = table
- .window(Over partitionBy 'b orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
- .select(
- plusOne('a.sum over 'w as 'wsum) as 'd,
- ('a.count over 'w).exp(),
- (weightedAvg('c, 'a) over 'w) + 1,
- "AVG:".toExpr + (weightedAvg('c, 'a) over 'w),
- array(weightedAvg('c, 'a) over 'w, 'a.count over 'w))
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c", "proctime")
- ),
- term("partitionBy", "b"),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "b", "c", "proctime",
- "SUM(a) AS w0$o0",
- "COUNT(a) AS w0$o1",
- "WeightedAvgWithRetract(c, a) AS w0$o2")
- ),
- term("select",
- s"${plusOne.functionIdentifier}(w0$$o0) AS d",
- "EXP(CAST(w0$o1)) AS _c1",
- "+(w0$o2, 1) AS _c2",
- "||('AVG:', CAST(w0$o2)) AS _c3",
- "ARRAY(w0$o2, w0$o1) AS _c4")
- )
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeBoundedPartitionedRowsOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(Over partitionBy 'b orderBy 'proctime preceding 2.rows following CURRENT_ROW as 'w)
- .select('c, weightedAvg('c, 'a) over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c", "proctime")
- ),
- term("partitionBy", "b"),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
- term("select", "a", "b", "c", "proctime", "WeightedAvgWithRetract(c, a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS _c1")
- )
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeBoundedPartitionedRangeOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(
- Over partitionBy 'a orderBy 'proctime preceding 2.hours following CURRENT_RANGE as 'w)
- .select('a, weightedAvg('c, 'a) over 'w as 'myAvg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("partitionBy", "a"),
- term("orderBy", "proctime"),
- term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "proctime",
- "WeightedAvgWithRetract(c, a) AS w0$o0"
- )
- ),
- term("select", "a", "w0$o0 AS myAvg")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeBoundedNonPartitionedRangeOver() = {
- val result = table
- .window(Over orderBy 'proctime preceding 10.second as 'w)
- .select('a, 'c.count over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("orderBy", "proctime"),
- term("range", "BETWEEN 10000 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(c) AS w0$o0")
- ),
- term("select", "a", "w0$o0 AS _c1")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeBoundedNonPartitionedRowsOver() = {
- val result = table
- .window(Over orderBy 'proctime preceding 2.rows as 'w)
- .select('c, 'a.count over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS _c1")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeUnboundedPartitionedRangeOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_RANGE following
- CURRENT_RANGE as 'w)
- .select('a, 'c, 'a.count over 'w, weightedAvg('c, 'a) over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "proctime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "proctime",
- "COUNT(a) AS w0$o0",
- "WeightedAvgWithRetract(c, a) AS w0$o1"
- )
- ),
- term(
- "select",
- "a",
- "c",
- "w0$o0 AS _c2",
- "w0$o1 AS _c3"
- )
- )
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeUnboundedPartitionedRowsOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(
- Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_ROW following CURRENT_ROW as 'w)
- .select('c, 'a.count over 'w, weightedAvg('c, 'a) over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime",
- "COUNT(a) AS w0$o0",
- "WeightedAvgWithRetract(c, a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS _c1", "w0$o1 AS _c2")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRangeOver() = {
- val result = table
- .window(
- Over orderBy 'proctime preceding UNBOUNDED_RANGE as 'w)
- .select('a, 'c, 'a.count over 'w, 'a.sum over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("orderBy", "proctime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "proctime",
- "COUNT(a) AS w0$o0",
- "SUM(a) AS w0$o1"
- )
- ),
- term(
- "select",
- "a",
- "c",
- "w0$o0 AS _c2",
- "w0$o1 AS _c3"
- )
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRowsOver() = {
- val result = table
- .window(Over orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
- .select('c, 'a.count over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS _c1")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRowsOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(
- Over partitionBy 'b orderBy 'rowtime preceding 2.rows following CURRENT_ROW as 'w)
- .select('c, 'b.count over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c", "rowtime")
- ),
- term("partitionBy", "b"),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
- term("select", "a", "b", "c", "rowtime",
- "COUNT(b) AS w0$o0",
- "WeightedAvgWithRetract(c, a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS _c1", "w0$o1 AS wAvg")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRangeOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(
- Over partitionBy 'a orderBy 'rowtime preceding 2.hours following CURRENT_RANGE as 'w)
- .select('a, 'c.avg over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("partitionBy", "a"),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "rowtime",
- "AVG(c) AS w0$o0",
- "WeightedAvgWithRetract(c, a) AS w0$o1"
- )
- ),
- term("select", "a", "w0$o0 AS _c1", "w0$o1 AS wAvg")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRangeOver() = {
- val result = table
- .window(Over orderBy 'rowtime preceding 10.second as 'w)
- .select('a, 'c.count over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN 10000 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(c) AS w0$o0")
- ),
- term("select", "a", "w0$o0 AS _c1")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRowsOver() = {
- val result = table
- .window(Over orderBy 'rowtime preceding 2.rows as 'w)
- .select('c, 'a.count over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS _c1")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeUnboundedPartitionedRangeOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding UNBOUNDED_RANGE following
- CURRENT_RANGE as 'w)
- .select('a, 'c, 'a.count over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "rowtime",
- "COUNT(a) AS w0$o0",
- "WeightedAvgWithRetract(c, a) AS w0$o1"
- )
- ),
- term(
- "select",
- "a",
- "c",
- "w0$o0 AS _c2",
- "w0$o1 AS wAvg"
- )
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeUnboundedPartitionedRowsOver() = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding UNBOUNDED_ROW following
- CURRENT_ROW as 'w)
- .select('c, 'a.count over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime",
- "COUNT(a) AS w0$o0",
- "WeightedAvgWithRetract(c, a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS _c1", "w0$o1 AS wAvg")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeUnboundedNonPartitionedRangeOver() = {
- val result = table
- .window(
- Over orderBy 'rowtime preceding UNBOUNDED_RANGE as 'w)
- .select('a, 'c, 'a.count over 'w, 'a.sum over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "rowtime",
- "COUNT(a) AS w0$o0",
- "SUM(a) AS w0$o1"
- )
- ),
- term(
- "select",
- "a",
- "c",
- "w0$o0 AS _c2",
- "w0$o1 AS _c3"
- )
- )
-
- streamUtil.verifyTable(result, expected)
- }
-
- @Test
- def testRowTimeUnboundedNonPartitionedRowsOver() = {
- val result = table
- .window(Over orderBy 'rowtime preceding UNBOUNDED_ROW as 'w)
- .select('c, 'a.count over 'w)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS _c1")
- )
-
- streamUtil.verifyTable(result, expected)
- }
-}
-
-
[41/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala
new file mode 100644
index 0000000..8bfb61b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala
@@ -0,0 +1,428 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class SingleRowJoinTest extends TableTestBase {
+
+ @Test
+ def testSingleRowCrossJoin(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Int)]("A", 'a1, 'a2)
+
+ val query =
+ "SELECT a1, asum " +
+ "FROM A, (SELECT sum(a1) + sum(a2) AS asum FROM A)"
+
+ val expected =
+ binaryNode(
+ "DataSetSingleRowJoin",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a1")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ batchTableNode(0),
+ tuples(List(null, null)),
+ term("values", "a1", "a2")
+ ),
+ term("union","a1","a2")
+ ),
+ term("select", "SUM(a1) AS $f0", "SUM(a2) AS $f1")
+ ),
+ term("select", "+($f0, $f1) AS asum")
+ ),
+ term("where", "true"),
+ term("join", "a1", "asum"),
+ term("joinType", "NestedLoopInnerJoin")
+ )
+
+ util.verifySql(query, expected)
+ }
+
+ @Test
+ def testSingleRowEquiJoin(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, String)]("A", 'a1, 'a2)
+
+ val query =
+ "SELECT a1, a2 " +
+ "FROM A, (SELECT count(a1) AS cnt FROM A) " +
+ "WHERE a1 = cnt"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetSingleRowJoin",
+ batchTableNode(0),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a1")
+ ),
+ tuples(List(null)),
+ term("values", "a1")
+ ),
+ term("union","a1")
+ ),
+ term("select", "COUNT(a1) AS cnt")
+ ),
+ term("where", "=(CAST(a1), cnt)"),
+ term("join", "a1", "a2", "cnt"),
+ term("joinType", "NestedLoopInnerJoin")
+ ),
+ term("select", "a1", "a2")
+ )
+
+ util.verifySql(query, expected)
+ }
+
+ @Test
+ def testSingleRowNotEquiJoin(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, String)]("A", 'a1, 'a2)
+
+ val query =
+ "SELECT a1, a2 " +
+ "FROM A, (SELECT count(a1) AS cnt FROM A) " +
+ "WHERE a1 < cnt"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetSingleRowJoin",
+ batchTableNode(0),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a1")
+ ),
+ tuples(List(null)),
+ term("values", "a1")
+ ),
+ term("union", "a1")
+ ),
+ term("select", "COUNT(a1) AS cnt")
+ ),
+ term("where", "<(a1, cnt)"),
+ term("join", "a1", "a2", "cnt"),
+ term("joinType", "NestedLoopInnerJoin")
+ ),
+ term("select", "a1", "a2")
+ )
+
+ util.verifySql(query, expected)
+ }
+
+ @Test
+ def testSingleRowJoinWithComplexPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long)]("A", 'a1, 'a2)
+ util.addTable[(Int, Long)]("B", 'b1, 'b2)
+
+ val query =
+ "SELECT a1, a2, b1, b2 " +
+ "FROM A, (SELECT min(b1) AS b1, max(b2) AS b2 FROM B) " +
+ "WHERE a1 < b1 AND a2 = b2"
+
+ val expected = binaryNode(
+ "DataSetSingleRowJoin",
+ batchTableNode(0),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ batchTableNode(1),
+ tuples(List(null, null)),
+ term("values", "b1", "b2")
+ ),
+ term("union","b1","b2")
+ ),
+ term("select", "MIN(b1) AS b1", "MAX(b2) AS b2")
+ ),
+ term("where", "AND(<(a1, b1)", "=(a2, b2))"),
+ term("join", "a1", "a2", "b1", "b2"),
+ term("joinType", "NestedLoopInnerJoin")
+ )
+
+ util.verifySql(query, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinEqualPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Long, Int)]("A", 'a1, 'a2)
+ util.addTable[(Int, Int)]("B", 'b1, 'b2)
+
+ val queryLeftJoin =
+ "SELECT a2 " +
+ "FROM A " +
+ " LEFT JOIN " +
+ "(SELECT COUNT(*) AS cnt FROM B) AS x " +
+ " ON a1 = cnt"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetSingleRowJoin",
+ batchTableNode(0),
+ term("where", "=(a1, cnt)"),
+ term("join", "a1", "a2", "cnt"),
+ term("joinType", "NestedLoopLeftJoin")
+ ),
+ term("select", "a2")
+ ) + "\n" +
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(1),
+ term("select", "0 AS $f0")),
+ tuples(List(null)), term("values", "$f0")
+ ),
+ term("union", "$f0")
+ ),
+ term("select", "COUNT(*) AS cnt")
+ )
+
+ util.verifySql(queryLeftJoin, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinNotEqualPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Long, Int)]("A", 'a1, 'a2)
+ util.addTable[(Int, Int)]("B", 'b1, 'b2)
+
+ val queryLeftJoin =
+ "SELECT a2 " +
+ "FROM A " +
+ " LEFT JOIN " +
+ "(SELECT COUNT(*) AS cnt FROM B) AS x " +
+ " ON a1 > cnt"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetSingleRowJoin",
+ batchTableNode(0),
+ term("where", ">(a1, cnt)"),
+ term("join", "a1", "a2", "cnt"),
+ term("joinType", "NestedLoopLeftJoin")
+ ),
+ term("select", "a2")
+ ) + "\n" +
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(1),
+ term("select", "0 AS $f0")),
+ tuples(List(null)), term("values", "$f0")
+ ),
+ term("union", "$f0")
+ ),
+ term("select", "COUNT(*) AS cnt")
+ )
+
+ util.verifySql(queryLeftJoin, expected)
+ }
+
+ @Test
+ def testLeftSingleRightJoinEqualPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Long, Long)]("A", 'a1, 'a2)
+ util.addTable[(Long, Long)]("B", 'b1, 'b2)
+
+ val queryRightJoin =
+ "SELECT a1 " +
+ "FROM (SELECT COUNT(*) AS cnt FROM B) " +
+ " RIGHT JOIN " +
+ "A " +
+ " ON cnt = a2"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetSingleRowJoin",
+ "",
+ term("where", "=(cnt, a2)"),
+ term("join", "cnt", "a1", "a2"),
+ term("joinType", "NestedLoopRightJoin")
+ ),
+ term("select", "a1")
+ ) + unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(1),
+ term("select", "0 AS $f0")),
+ tuples(List(null)), term("values", "$f0")
+ ),
+ term("union", "$f0")
+ ),
+ term("select", "COUNT(*) AS cnt")
+ ) + "\n" +
+ batchTableNode(0)
+
+ util.verifySql(queryRightJoin, expected)
+ }
+
+ @Test
+ def testLeftSingleRightJoinNotEqualPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Long, Long)]("A", 'a1, 'a2)
+ util.addTable[(Long, Long)]("B", 'b1, 'b2)
+
+ val queryRightJoin =
+ "SELECT a1 " +
+ "FROM (SELECT COUNT(*) AS cnt FROM B) " +
+ " RIGHT JOIN " +
+ "A " +
+ " ON cnt < a2"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetSingleRowJoin",
+ "",
+ term("where", "<(cnt, a2)"),
+ term("join", "cnt", "a1", "a2"),
+ term("joinType", "NestedLoopRightJoin")
+ ),
+ term("select", "a1")
+ ) +
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(1),
+ term("select", "0 AS $f0")),
+ tuples(List(null)), term("values", "$f0")
+ ),
+ term("union", "$f0")
+ ),
+ term("select", "COUNT(*) AS cnt")
+ ) + "\n" +
+ batchTableNode(0)
+
+ util.verifySql(queryRightJoin, expected)
+ }
+
+ @Test
+ def testSingleRowJoinInnerJoin(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Int)]("A", 'a1, 'a2)
+ val query =
+ "SELECT a2, sum(a1) " +
+ "FROM A " +
+ "GROUP BY a2 " +
+ "HAVING sum(a1) > (SELECT sum(a1) * 0.1 FROM A)"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetSingleRowJoin",
+ unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "a2"),
+ term("select", "a2", "SUM(a1) AS EXPR$1")
+ ),
+ term("where", ">(EXPR$1, EXPR$0)"),
+ term("join", "a2", "EXPR$1", "EXPR$0"),
+ term("joinType", "NestedLoopInnerJoin")
+ ),
+ term("select", "a2", "EXPR$1")
+ ) + "\n" +
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a1")
+ ),
+ tuples(List(null)), term("values", "a1")
+ ),
+ term("union", "a1")
+ ),
+ term("select", "SUM(a1) AS $f0")
+ ),
+ term("select", "*($f0, 0.1) AS EXPR$0")
+ )
+
+ util.verifySql(query, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/CalcValidationTest.scala
new file mode 100644
index 0000000..9aada9a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/CalcValidationTest.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidFields(): Unit = {
+
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, foo FROM MyTable"
+
+ util.tableEnv.sql(sqlQuery)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/GroupWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/GroupWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/GroupWindowValidationTest.scala
new file mode 100644
index 0000000..4272170
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/GroupWindowValidationTest.scala
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql.validation
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testHopWindowNoOffset(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM T " +
+ "GROUP BY HOP(ts, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ util.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testSessionWindowNoOffset(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM T " +
+ "GROUP BY SESSION(ts, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ util.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testVariableWindowSize() = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sql = "SELECT COUNT(*) " +
+ "FROM T " +
+ "GROUP BY TUMBLE(ts, b * INTERVAL '1' MINUTE)"
+ util.verifySql(sql, "n/a")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testTumbleWindowWithInvalidUdAggArgs() = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val weightedAvg = new WeightedAvgWithMerge
+ util.tableEnv.registerFunction("weightedAvg", weightedAvg)
+
+ val sql = "SELECT weightedAvg(c, a) AS wAvg " +
+ "FROM T " +
+ "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE)"
+ util.verifySql(sql, "n/a")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/JoinValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/JoinValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/JoinValidationTest.scala
new file mode 100644
index 0000000..90bcfec
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/JoinValidationTest.scala
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class JoinValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinNonExistingKey(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE foo = e"
+
+ util.tableEnv.sql(sqlQuery)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testJoinNonMatchingKeyTypes(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = g"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinWithAmbiguousFields(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testJoinNoEqualityPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE d = f"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testCrossJoin(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, String)]("Table4", 'a1, 'b1, 'c1)
+
+ val sqlQuery = "SELECT a, a1 FROM Table3 CROSS JOIN Table4"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRightOuterJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and a > d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testLeftOuterJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and a > d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testFullOuterJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and a > d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRightOuterJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and e > 3"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testLeftOuterJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and b > 3"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testFullOuterJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and b > 3"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/OverWindowValidationTest.scala
new file mode 100644
index 0000000..7e72a21
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/OverWindowValidationTest.scala
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql.validation
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.OverAgg0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class OverWindowValidationTest extends TableTestBase {
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation(): Unit = {
+
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("T", 'a, 'b, 'c)
+
+ util.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(b, a) FROM T"
+ util.tableEnv.sql(sqlQuery)
+ }
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation2(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+ util.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(b, a) FROM T GROUP BY TUMBLE(ts, INTERVAL '2' HOUR)"
+
+ util.tableEnv.sql(sqlQuery)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/SortValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/SortValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/SortValidationTest.scala
new file mode 100644
index 0000000..d3f9b9f
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/validation/SortValidationTest.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class SortValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testLimitWithoutOrder(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT * FROM MyTable LIMIT 5"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala
new file mode 100644
index 0000000..af001be
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+/**
+ * Test for testing aggregate plans.
+ */
+class AggregateTest extends TableTestBase {
+
+ @Test
+ def testGroupAggregateWithFilter(): Unit = {
+
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val resultTable = sourceTable.groupBy('a)
+ .select('a, 'a.avg, 'b.sum, 'c.count)
+ .where('a === 1)
+
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", "=(a, 1)")
+ )
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ calcNode,
+ term("groupBy", "a"),
+ term("select",
+ "a",
+ "AVG(a) AS TMP_0",
+ "SUM(b) AS TMP_1",
+ "COUNT(c) AS TMP_2")
+ )
+
+ util.verifyTable(resultTable,expected)
+ }
+
+ @Test
+ def testAggregate(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+ val resultTable = sourceTable.select('a.avg,'b.sum,'c.count)
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ batchTableNode(0),
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS TMP_0",
+ "SUM(b) AS TMP_1",
+ "COUNT(c) AS TMP_2")
+ )
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testAggregateWithFilter(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val resultTable = sourceTable.select('a,'b,'c).where('a === 1)
+ .select('a.avg,'b.sum,'c.count)
+
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ // ReduceExpressionsRule will add cast for Project node by force
+ // if the input of the Project node has constant expression.
+ term("select", "CAST(1) AS a", "b", "c"),
+ term("where", "=(a, 1)")
+ )
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ calcNode,
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS TMP_0",
+ "SUM(b) AS TMP_1",
+ "COUNT(c) AS TMP_2")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala
new file mode 100644
index 0000000..ee05547
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala
@@ -0,0 +1,341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.scala.createTypeInformation
+import org.apache.flink.table.api.batch.table.CalcTest.{MyHashCode, TestCaseClass, WC, giveMeCaseClass}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.Upper
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcTest extends TableTestBase {
+
+ @Test
+ def testMultipleFlatteningsTable(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table.select('a.flatten(), 'c, 'b.flatten())
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "a._1 AS a$_1",
+ "a._2 AS a$_2",
+ "c",
+ "b._1 AS b$_1",
+ "b._2 AS b$_2"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testNestedFlattening(): Unit = {
+ val util = batchTestUtil()
+ val table = util
+ .addTable[((((String, TestCaseClass), Boolean), String), String)]("MyTable", 'a, 'b)
+
+ val result = table.select('a.flatten(), 'b.flatten())
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "a._1 AS a$_1",
+ "a._2 AS a$_2",
+ "b"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testScalarFunctionAccess(): Unit = {
+ val util = batchTestUtil()
+ val table = util
+ .addTable[(String, Int)]("MyTable", 'a, 'b)
+
+ val result = table.select(
+ giveMeCaseClass().get("my"),
+ giveMeCaseClass().get("clazz"),
+ giveMeCaseClass().flatten())
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ s"${giveMeCaseClass.functionIdentifier}().my AS _c0",
+ s"${giveMeCaseClass.functionIdentifier}().clazz AS _c1",
+ s"${giveMeCaseClass.functionIdentifier}().my AS _c2",
+ s"${giveMeCaseClass.functionIdentifier}().clazz AS _c3"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Tests for all the situations when we can do fields projection. Like selecting few fields
+ // from a large field count source.
+ // ----------------------------------------------------------------------------------------------
+
+ @Test
+ def testSimpleSelect(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable = sourceTable.select('a, 'b)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectAllFields(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable1 = sourceTable.select('*)
+ val resultTable2 = sourceTable.select('a, 'b, 'c, 'd)
+
+ val expected = batchTableNode(0)
+
+ util.verifyTable(resultTable1, expected)
+ util.verifyTable(resultTable2, expected)
+ }
+
+ @Test
+ def testSelectAggregation(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable = sourceTable.select('a.sum, 'b.max)
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ binaryNode(
+ "DataSetUnion",
+ values(
+ "DataSetValues",
+ tuples(List(null, null)),
+ term("values", "a", "b")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("union", "a", "b")
+ ),
+ term("select", "SUM(a) AS TMP_0", "MAX(b) AS TMP_1")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectFunction(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+
+ util.tableEnv.registerFunction("hashCode", MyHashCode)
+
+ val resultTable = sourceTable.select("hashCode(c), b")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", s"${MyHashCode.functionIdentifier}(c) AS _c0", "b")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectFromGroupedTable(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable = sourceTable.groupBy('a, 'c).select('a)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "c")
+ ),
+ term("distinct", "a", "c")
+ ),
+ term("select", "a")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectAllFieldsFromGroupedTable(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable = sourceTable.groupBy('a, 'c).select('a, 'c)
+
+ val expected = unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "c")
+ ),
+ term("distinct", "a", "c")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectAggregationFromGroupedTable(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable = sourceTable.groupBy('c).select('a.sum)
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "c")
+ ),
+ term("groupBy", "c"),
+ term("select", "c", "SUM(a) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectFromGroupedTableWithNonTrivialKey(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable = sourceTable.groupBy(Upper('c) as 'k).select('a.sum)
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "c", "UPPER(c) AS k")
+ ),
+ term("groupBy", "k"),
+ term("select", "k", "SUM(a) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectFromGroupedTableWithFunctionKey(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
+ val resultTable = sourceTable.groupBy(MyHashCode('c) as 'k).select('a.sum)
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "c", s"${MyHashCode.functionIdentifier}(c) AS k")
+ ),
+ term("groupBy", "k"),
+ term("select", "k", "SUM(a) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectFromAggregatedPojoTable(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[WC]("MyTable", 'word, 'frequency)
+ val resultTable = sourceTable
+ .groupBy('word)
+ .select('word, 'frequency.sum as 'frequency)
+ .filter('frequency === 2)
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "word"),
+ term("select", "word", "SUM(frequency) AS TMP_0")
+ ),
+ term("select", "word, TMP_0 AS frequency"),
+ term("where", "=(TMP_0, 2)")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+}
+
+object CalcTest {
+
+ case class TestCaseClass(my: String, clazz: Int)
+
+ object giveMeCaseClass extends ScalarFunction {
+ def eval(): TestCaseClass = {
+ TestCaseClass("hello", 42)
+ }
+
+ override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
+ createTypeInformation[TestCaseClass]
+ }
+ }
+
+ object MyHashCode extends ScalarFunction {
+ def eval(s: String): Int = s.hashCode()
+ }
+
+ case class WC(word: String, frequency: Long)
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala
new file mode 100644
index 0000000..63ce267
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.runtime.utils._
+import org.apache.flink.table.utils.{TableFunc1, TableTestBase}
+import org.junit.Test
+
+class CorrelateTest extends TableTestBase {
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("func1", new TableFunc1)
+
+ val result1 = table.join(function('c) as 's).select('c, 's)
+
+ val expected1 = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "s")
+ )
+
+ util.verifyTable(result1, expected1)
+
+ // test overloading
+
+ val result2 = table.join(function('c, "$") as 's).select('c, 's)
+
+ val expected2 = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2, '$$')"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "s")
+ )
+
+ util.verifyTable(result2, expected2)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("func1", new TableFunc1)
+
+ val result = table.leftOuterJoin(function('c) as 's).select('c, 's)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
+ term("joinType", "LEFT")
+ ),
+ term("select", "c", "s")
+ )
+
+ util.verifyTable(result, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala
new file mode 100644
index 0000000..e441203
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMerge
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.WindowReference
+import org.apache.flink.table.plan.logical._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowTest extends TableTestBase {
+
+ //===============================================================================================
+ // Common test
+ //===============================================================================================
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'long, 2.rows)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverTimeWithUdAgg(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, myWeightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "int", "long")
+ ),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "int", "long")
+ ),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'long, 2.rows)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ //===============================================================================================
+ // Sliding Windows
+ //===============================================================================================
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window",
+ SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window",
+ SlidingGroupWindow(WindowReference("w"), 'long, 2.rows, 1.rows)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeWithUdAgg(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, myWeightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window",
+ SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "int", "long")
+ ),
+ term("window",
+ SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "int", "long")
+ ),
+ term("window",
+ SlidingGroupWindow(WindowReference("w"), 'long, 2.rows, 1.rows)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ //===============================================================================================
+ // Session Windows
+ //===============================================================================================
+
+ @Test
+ def testEventTimeSessionGroupWindowOverTime(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindowOverTimeWithUdAgg(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, myWeightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/AggregateStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/AggregateStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/AggregateStringExpressionTest.scala
new file mode 100644
index 0000000..e148b47
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/AggregateStringExpressionTest.scala
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMergeAndReset
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.utils.TableTestBase
+import org.junit._
+
+class AggregateStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testAggregationTypes(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
+
+ val t1 = t.select('_1.sum, '_1.sum0, '_1.min, '_1.max, '_1.count, '_1.avg)
+ val t2 = t.select("_1.sum, _1.sum0, _1.min, _1.max, _1.count, _1.avg")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testWorkingAggregationDataTypes(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Byte, Short, Int, Long, Float, Double, String)]("Table7")
+
+ val t1 = t.select('_1.avg, '_2.avg, '_3.avg, '_4.avg, '_5.avg, '_6.avg, '_7.count)
+ val t2 = t.select("_1.avg, _2.avg, _3.avg, _4.avg, _5.avg, _6.avg, _7.count")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testProjection(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Byte, Short)]("Table2")
+
+ val t1 = t.select('_1.avg, '_1.sum, '_1.count, '_2.avg, '_2.sum)
+ val t2 = t.select("_1.avg, _1.sum, _1.count, _2.avg, _2.sum")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testAggregationWithArithmetic(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2")
+
+ val t1 = t.select(('_1 + 2).avg + 2, '_2.count + 5)
+ val t2 = t.select("(_1 + 2).avg + 2, _2.count + 5")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testAggregationWithTwoCount(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2")
+
+ val t1 = t.select('_1.count, '_2.count)
+ val t2 = t.select("_1.count, _2.count")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testAggregationAfterProjection(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Byte, Short, Int, Long, Float, Double, String)]("Table7")
+
+ val t1 = t.select('_1, '_2, '_3)
+ .select('_1.avg, '_2.sum, '_3.count)
+
+ val t2 = t.select("_1, _2, _3")
+ .select("_1.avg, _2.sum, _3.count")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testDistinct(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val distinct = ds.select('b).distinct()
+ val distinct2 = ds.select("b").distinct()
+
+ verifyTableEquals(distinct, distinct2)
+ }
+
+ @Test
+ def testDistinctAfterAggregate(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
+
+ val distinct = ds.groupBy('a, 'e).select('e).distinct()
+ val distinct2 = ds.groupBy("a, e").select("e").distinct()
+
+ verifyTableEquals(distinct, distinct2)
+ }
+
+ @Test
+ def testGroupedAggregate(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val t1 = t.groupBy('b).select('b, 'a.sum)
+ val t2 = t.groupBy("b").select("b, a.sum")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testGroupingKeyForwardIfNotUsed(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val t1 = t.groupBy('b).select('a.sum)
+ val t2 = t.groupBy("b").select("a.sum")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testGroupNoAggregation(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val t1 = t
+ .groupBy('b)
+ .select('a.sum as 'd, 'b)
+ .groupBy('b, 'd)
+ .select('b)
+
+ val t2 = t
+ .groupBy("b")
+ .select("a.sum as d, b")
+ .groupBy("b, d")
+ .select("b")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testGroupedAggregateWithConstant1(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val t1 = t.select('a, 4 as 'four, 'b)
+ .groupBy('four, 'a)
+ .select('four, 'b.sum)
+
+ val t2 = t.select("a, 4 as four, b")
+ .groupBy("four, a")
+ .select("four, b.sum")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testGroupedAggregateWithConstant2(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val t1 = t.select('b, 4 as 'four, 'a)
+ .groupBy('b, 'four)
+ .select('four, 'a.sum)
+ val t2 = t.select("b, 4 as four, a")
+ .groupBy("b, four")
+ .select("four, a.sum")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testGroupedAggregateWithExpression(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
+
+ val t1 = t.groupBy('e, 'b % 3)
+ .select('c.min, 'e, 'a.avg, 'd.count)
+ val t2 = t.groupBy("e, b % 3")
+ .select("c.min, e, a.avg, d.count")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testGroupedAggregateWithFilter(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val t1 = t.groupBy('b)
+ .select('b, 'a.sum)
+ .where('b === 2)
+ val t2 = t.groupBy("b")
+ .select("b, a.sum")
+ .where("b = 2")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testAnalyticAggregation(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, Float, Double)]('_1, '_2, '_3, '_4)
+
+ val resScala = t.select(
+ '_1.stddevPop, '_2.stddevPop, '_3.stddevPop, '_4.stddevPop,
+ '_1.stddevSamp, '_2.stddevSamp, '_3.stddevSamp, '_4.stddevSamp,
+ '_1.varPop, '_2.varPop, '_3.varPop, '_4.varPop,
+ '_1.varSamp, '_2.varSamp, '_3.varSamp, '_4.varSamp)
+ val resJava = t.select("""
+ _1.stddevPop, _2.stddevPop, _3.stddevPop, _4.stddevPop,
+ _1.stddevSamp, _2.stddevSamp, _3.stddevSamp, _4.stddevSamp,
+ _1.varPop, _2.varPop, _3.varPop, _4.varPop,
+ _1.varSamp, _2.varSamp, _3.varSamp, _4.varSamp""")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testAggregateWithUDAGG(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val myCnt = new CountAggFunction
+ util.tableEnv.registerFunction("myCnt", myCnt)
+ val myWeightedAvg = new WeightedAvgWithMergeAndReset
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+
+ val t1 = t.select(myCnt('a) as 'aCnt, myWeightedAvg('b, 'a) as 'wAvg)
+ val t2 = t.select("myCnt(a) as aCnt, myWeightedAvg(b, a) as wAvg")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testGroupedAggregateWithUDAGG(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+
+ val myCnt = new CountAggFunction
+ util.tableEnv.registerFunction("myCnt", myCnt)
+ val myWeightedAvg = new WeightedAvgWithMergeAndReset
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+
+ val t1 = t.groupBy('b)
+ .select('b, myCnt('a) + 9 as 'aCnt, myWeightedAvg('b, 'a) * 2 as 'wAvg, myWeightedAvg('a, 'a))
+ val t2 = t.groupBy("b")
+ .select("b, myCnt(a) + 9 as aCnt, myWeightedAvg(b, a) * 2 as wAvg, myWeightedAvg(a, a)")
+
+ verifyTableEquals(t1, t2)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CalcStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CalcStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CalcStringExpressionTest.scala
new file mode 100644
index 0000000..901b2f4
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CalcStringExpressionTest.scala
@@ -0,0 +1,365 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.stringexpr
+
+import java.sql.{Date, Time, Timestamp}
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets.CustomType
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.Types._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.utils.TableTestBase
+import org.junit._
+
+class CalcStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testSimpleSelectAllWithAs(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = t.select('a, 'b, 'c)
+ val t2 = t.select("a, b, c")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testSimpleSelectWithNaming(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
+
+ val t1 = t
+ .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
+ .select('a, 'b)
+
+ val t2 = t
+ .select("_1 as a, _2 as b, _1 as c")
+ .select("a, b")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testSimpleSelectRenameAll(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
+
+ val t1 = t
+ .select('_1 as 'a, '_2 as 'b, '_3 as 'c)
+ .select('a, 'b)
+
+ val t2 = t
+ .select("_1 as a, _2 as b, _3 as c")
+ .select("a, b")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testSelectStar(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = t.select('*)
+ val t2 = t.select("*")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = ds.filter( Literal(false) )
+ val t2 = ds.filter("faLsE")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = ds.filter( Literal(true) )
+ val t2 = ds.filter("trUe")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testFilterOnStringTupleField(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = ds.filter( 'c.like("%world%") )
+ val t2 = ds.filter("c.like('%world%')")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testFilterOnIntegerTupleField(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = ds.filter( 'a % 2 === 0 )
+ val t2 = ds.filter( "a % 2 = 0 ")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testNotEquals(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = ds.filter( 'a % 2 !== 0 )
+ val t2 = ds.filter("a % 2 <> 0")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testDisjunctivePredicate(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = ds.filter( 'a < 2 || 'a > 20)
+ val t2 = ds.filter("a < 2 || a > 20")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testConsecutiveFilters(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = ds.filter('a % 2 !== 0).filter('b % 2 === 0)
+ val t2 = ds.filter("a % 2 != 0").filter("b % 2 = 0")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testFilterBasicType(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[String]("Table3",'a)
+
+ val t1 = ds.filter( 'a.like("H%") )
+ val t2 = ds.filter( "a.like('H%')" )
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testFilterOnCustomType(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[CustomType]("Table3",'myInt as 'i, 'myLong as 'l, 'myString as 's)
+
+ val t1 = t.filter( 's.like("%a%") )
+ val t2 = t.filter("s.like('%a%')")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testSimpleCalc(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
+
+ val t1 = t.select('_1, '_2, '_3)
+ .where('_1 < 7)
+ .select('_1, '_3)
+
+ val t2 = t.select("_1, _2, _3")
+ .where("_1 < 7")
+ .select("_1, _3")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testCalcWithTwoFilters(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
+
+ val t1 = t.select('_1, '_2, '_3)
+ .where('_1 < 7 && '_2 === 3)
+ .select('_1, '_3)
+ .where('_1 === 4)
+ .select('_1)
+
+ val t2 = t.select("_1, _2, _3")
+ .where("_1 < 7 && _2 = 3")
+ .select("_1, _3")
+ .where("_1 === 4")
+ .select("_1")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testCalcWithAggregation(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
+
+ val t1 = t.select('_1, '_2, '_3)
+ .where('_1 < 15)
+ .groupBy('_2)
+ .select('_1.min, '_2.count as 'cnt)
+ .where('cnt > 3)
+
+
+ val t2 = t.select("_1, _2, _3")
+ .where("_1 < 15")
+ .groupBy("_2")
+ .select("_1.min, _2.count as cnt")
+ .where("cnt > 3")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testCalcJoin(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.select('a, 'b).join(ds2).where('b === 'e).select('a, 'b, 'd, 'e, 'f)
+ .where('b > 1).select('a, 'd).where('d === 2)
+ val t2 = ds1.select("a, b").join(ds2).where("b = e").select("a, b, d, e, f")
+ .where("b > 1").select("a, d").where("d = 2")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testAdvancedDataTypes(): Unit = {
+ val util = batchTestUtil()
+ val t = util
+ .addTable[(BigDecimal, BigDecimal, Date, Time, Timestamp)]("Table5", 'a, 'b, 'c, 'd, 'e)
+
+ val t1 = t.select('a, 'b, 'c, 'd, 'e, BigDecimal("11.2"), BigDecimal("11.2").bigDecimal,
+ "1984-07-12".cast(Types.SQL_DATE), "14:34:24".cast(Types.SQL_TIME),
+ "1984-07-12 14:34:24".cast(Types.SQL_TIMESTAMP))
+ val t2 = t.select("a, b, c, d, e, 11.2p, 11.2p," +
+ "'1984-07-12'.toDate, '14:34:24'.toTime," +
+ "'1984-07-12 14:34:24'.toTimestamp")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testIntegerBiggerThan128(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val t1 = t.filter('a === 300)
+ val t2 = t.filter("a = 300")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testNumericAutoCastInArithmetic() {
+ val util = batchTestUtil()
+ val table = util.addTable[(Byte, Short, Int, Long, Float, Double, Long, Double)](
+ "Table",
+ '_1, '_2, '_3, '_4, '_5, '_6, '_7, '_8)
+
+ val t1 = table.select('_1 + 1, '_2 + 1, '_3 + 1L, '_4 + 1.0f,
+ '_5 + 1.0d, '_6 + 1, '_7 + 1.0d, '_8 + '_1)
+ val t2 = table.select("_1 + 1, _2 +" +
+ " 1, _3 + 1L, _4 + 1.0f, _5 + 1.0d, _6 + 1, _7 + 1.0d, _8 + _1")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ @throws[Exception]
+ def testNumericAutoCastInComparison() {
+ val util = batchTestUtil()
+ val table = util.addTable[(Byte, Short, Int, Long, Float, Double)](
+ "Table",
+ 'a, 'b, 'c, 'd, 'e, 'f)
+
+ val t1 = table.filter('a > 1 && 'b > 1 && 'c > 1L &&
+ 'd > 1.0f && 'e > 1.0d && 'f > 1)
+ val t2 = table
+ .filter("a > 1 && b > 1 && c > 1L && d > 1.0f && e > 1.0d && f > 1")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ @throws[Exception]
+ def testCasting() {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Double, Long, Boolean)](
+ "Table",
+ '_1, '_2, '_3, '_4)
+
+ val t1 = table .select(
+ // * -> String
+ '_1.cast(STRING), '_2.cast(STRING), '_3.cast(STRING), '_4.cast(STRING),
+ // NUMERIC TYPE -> Boolean
+ '_1.cast(BOOLEAN), '_2.cast(BOOLEAN), '_3.cast(BOOLEAN),
+ // NUMERIC TYPE -> NUMERIC TYPE
+ '_1.cast(DOUBLE), '_2.cast(INT), '_3.cast(SHORT),
+ // Boolean -> NUMERIC TYPE
+ '_4.cast(DOUBLE), // identity casting
+ '_1.cast(INT), '_2.cast(DOUBLE), '_3.cast(LONG), '_4.cast(BOOLEAN))
+ val t2 = table.select(
+ // * -> String
+ "_1.cast(STRING), _2.cast(STRING), _3.cast(STRING), _4.cast(STRING)," +
+ // NUMERIC TYPE -> Boolean
+ "_1.cast(BOOLEAN), _2.cast(BOOLEAN), _3.cast(BOOLEAN)," +
+ // NUMERIC TYPE -> NUMERIC TYPE
+ "_1.cast(DOUBLE), _2.cast(INT), _3.cast(SHORT)," +
+ // Boolean -> NUMERIC TYPE
+ "_4.cast(DOUBLE)," +
+ // identity casting
+ "_1.cast(INT), _2.cast(DOUBLE), _3.cast(LONG), _4.cast(BOOLEAN)")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ @throws[Exception]
+ def testCastFromString() {
+ val util = batchTestUtil()
+ val table = util.addTable[(String, String, String)](
+ "Table",
+ '_1, '_2, '_3)
+
+ val t1 = table .select('_1.cast(BYTE), '_1.cast(SHORT), '_1.cast(INT), '_1.cast(LONG),
+ '_3.cast(DOUBLE), '_3.cast(FLOAT), '_2.cast(BOOLEAN))
+ val t2 = table.select(
+ "_1.cast(BYTE), _1.cast(SHORT), _1.cast(INT), _1.cast(LONG), " +
+ "_3.cast(DOUBLE), _3.cast(FLOAT), _2.cast(BOOLEAN)")
+
+ verifyTableEquals(t1, t2)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala
new file mode 100644
index 0000000..6ef46af
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.stringexpr
+
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{Table, Types}
+import org.apache.flink.table.utils.{PojoTableFunc, TableFunc2, _}
+import org.apache.flink.table.utils._
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class CorrelateStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testCorrelateJoins(): Unit = {
+ val util = batchTestUtil()
+
+ val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
+ val sTab = util.addTable[(Int, Long, String)]("Table1", 'a, 'b, 'c)
+ val jTab = util.addJavaTable[Row](typeInfo, "Table2", "a, b, c")
+
+ // test cross join
+ val func1 = new TableFunc1
+ util.javaTableEnv.registerFunction("func1", func1)
+ var scalaTable = sTab.join(func1('c) as 's).select('c, 's)
+ var javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c).as(s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test left outer join
+ scalaTable = sTab.leftOuterJoin(func1('c) as 's).select('c, 's)
+ javaTable = jTab.leftOuterJoin(new Table(util.javaTableEnv, "as(func1(c), s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test overloading
+ scalaTable = sTab.join(func1('c, "$") as 's).select('c, 's)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test custom result type
+ val func2 = new TableFunc2
+ util.javaTableEnv.registerFunction("func2", func2)
+ scalaTable = sTab.join(func2('c) as('name, 'len)).select('c, 'name, 'len)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test hierarchy generic type
+ val hierarchy = new HierarchyTableFunction
+ util.javaTableEnv.registerFunction("hierarchy", hierarchy)
+ scalaTable = sTab.join(hierarchy('c) as('name, 'adult, 'len)).select('c, 'name, 'len, 'adult)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
+ .select("c, name, len, adult")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test pojo type
+ val pojo = new PojoTableFunc
+ util.javaTableEnv.registerFunction("pojo", pojo)
+ scalaTable = sTab.join(pojo('c)).select('c, 'name, 'age)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "pojo(c)")).select("c, name, age")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with filter
+ scalaTable = sTab.join(func2('c) as('name, 'len)).select('c, 'name, 'len).filter('len > 2)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func2(c) as (name, len)"))
+ .select("c, name, len").filter("len > 2")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with scalar function
+ scalaTable = sTab.join(func1('c.substring(2)) as 's).select('a, 'c, 's)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func1(substring(c, 2)) as (s)")).select("a, c, s")
+ verifyTableEquals(scalaTable, javaTable)
+ }
+}
[19/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/GroupWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/GroupWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/GroupWindowITCase.scala
new file mode 100644
index 0000000..1561da0
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/GroupWindowITCase.scala
@@ -0,0 +1,445 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.common.time.Time
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.runtime.stream.table.GroupWindowITCase._
+import org.apache.flink.table.runtime.utils.StreamITCase
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+/**
+ * We only test some aggregations until better testing of constructed DataStream
+ * programs is possible.
+ */
+class GroupWindowITCase extends StreamingMultipleProgramsTestBase {
+ private val queryConfig = new StreamQueryConfig()
+ queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
+
+ val data = List(
+ (1L, 1, "Hi"),
+ (2L, 2, "Hello"),
+ (4L, 2, "Hello"),
+ (8L, 3, "Hello world"),
+ (16L, 3, "Hello world"))
+
+ val data2 = List(
+ (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
+ (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
+ (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
+ (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
+ (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
+ (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
+ (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
+
+ @Test
+ def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
+
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, countFun('int), 'int.avg,
+ weightAvgFun('long, 'int), weightAvgFun('int, 'int))
+
+ val results = windowedTable.toAppendStream[Row](queryConfig)
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("Hello world,1,3,8,3", "Hello world,2,3,12,3", "Hello,1,2,2,2",
+ "Hello,2,2,3,2", "Hi,1,1,1,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindowOverTime(): Unit = {
+ //To verify the "merge" functionality, we create this test with the following characteristics:
+ // 1. set the Parallelism to 1, and have the test data out of order
+ // 2. create a waterMark with 10ms offset to delay the window emission by 10ms
+ val sessionWindowTestdata = List(
+ (1L, 1, "Hello"),
+ (2L, 2, "Hello"),
+ (8L, 8, "Hello"),
+ (9L, 9, "Hello World"),
+ (4L, 4, "Hello"),
+ (16L, 16, "Hello"))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvgWithMerge
+
+ val stream = env
+ .fromCollection(sessionWindowTestdata)
+ .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset[(Long, Int, String)](10L))
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Session withGap 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, countFun('int), 'int.avg,
+ weightAvgFun('long, 'int), weightAvgFun('int, 'int))
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("Hello World,1,9,9,9", "Hello,1,16,16,16", "Hello,4,3,5,5")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w)
+ .select(countFun('string), 'int.avg,
+ weightAvgFun('long, 'int), weightAvgFun('int, 'int))
+
+ val results = windowedTable.toAppendStream[Row](queryConfig)
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("2,1,1,1", "2,2,6,2")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeTumblingWindow(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset[(Long, Int, String)](0L))
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, countFun('string), 'int.avg, weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int), 'int.min, 'int.max, 'int.sum, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hello world,1,3,8,3,3,3,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01",
+ "Hello world,1,3,16,3,3,3,3,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02",
+ "Hello,2,2,3,2,2,2,4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hi,1,1,1,1,1,1,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testGroupWindowWithoutKeyInProjection(): Unit = {
+ val data = List(
+ (1L, 1, "Hi", 1, 1),
+ (2L, 2, "Hello", 2, 2),
+ (4L, 2, "Hello", 2, 2),
+ (8L, 3, "Hello world", 3, 3),
+ (16L, 3, "Hello world", 3, 3))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'int2, 'int3, 'proctime.proctime)
+
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'int2, 'int3, 'string)
+ .select(weightAvgFun('long, 'int))
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("12", "8", "2", "3", "1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+
+
+ // ----------------------------------------------------------------------------------------------
+ // Sliding windows
+ // ----------------------------------------------------------------------------------------------
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 2.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
+ "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
+ "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019",
+ "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
+ "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003",
+ "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011",
+ "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007",
+ "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
+ "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 10.milli every 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
+ "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
+ "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
+ "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02",
+ "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025",
+ "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
+ "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
+ "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
+ "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 4.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
+ "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
+ "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
+ "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 3.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeGroupWindowWithoutExplicitTimeField(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ .map(t => (t._2, t._6))
+ val table = stream.toTable(tEnv, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 3.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
+
+object GroupWindowITCase {
+
+ class TimestampAndWatermarkWithOffset[T <: Product](
+ offset: Long) extends AssignerWithPunctuatedWatermarks[T] {
+
+ override def checkAndGetNextWatermark(
+ lastElement: T,
+ extractedTimestamp: Long): Watermark = {
+ new Watermark(extractedTimestamp - offset)
+ }
+
+ override def extractTimestamp(
+ element: T,
+ previousElementTimestamp: Long): Long = {
+ element.productElement(0).asInstanceOf[Long]
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/OverWindowITCase.scala
new file mode 100644
index 0000000..73484d2
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/OverWindowITCase.scala
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.source.SourceFunction
+import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvg
+import org.apache.flink.table.runtime.utils.JavaUserDefinedScalarFunctions.JavaFunc0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.runtime.stream.table.OverWindowITCase._
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class OverWindowITCase extends StreamingWithStateTestBase {
+
+ @Test
+ def testProcTimeUnBoundedPartitionedRowOver(): Unit = {
+
+ val data = List(
+ (1L, 1, "Hello"),
+ (2L, 2, "Hello"),
+ (3L, 3, "Hello"),
+ (4L, 4, "Hello"),
+ (5L, 5, "Hello"),
+ (6L, 6, "Hello"),
+ (7L, 7, "Hello World"),
+ (8L, 8, "Hello World"),
+ (20L, 20, "Hello World"))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ StreamITCase.clear
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(
+ Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
+ .select('c, countFun('b) over 'w as 'mycount, weightAvgFun('a, 'b) over 'w as 'wAvg)
+ .select('c, 'mycount, 'wAvg)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hello World,1,7", "Hello World,2,7", "Hello World,3,14",
+ "Hello,1,1", "Hello,2,1", "Hello,3,2", "Hello,4,3", "Hello,5,3", "Hello,6,4")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.testResults = mutable.MutableList()
+ StreamITCase.clear
+ env.setParallelism(1)
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (1, 1L, "Hello")),
+ Left(14000002L, (1, 2L, "Hello")),
+ Left(14000002L, (1, 3L, "Hello world")),
+ Left(14000003L, (2, 2L, "Hello world")),
+ Left(14000003L, (2, 3L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 4L, "Hello world")),
+ Left(14000022L, (1, 5L, "Hello world")),
+ Left(14000022L, (1, 6L, "Hello world")),
+ Left(14000022L, (1, 7L, "Hello world")),
+ Left(14000023L, (2, 4L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000030L)
+ )
+ val table = env
+ .addSource(new RowTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+ val plusOne = new JavaFunc0
+
+ val windowedTable = table
+ .window(Over partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_RANGE following
+ CURRENT_RANGE as 'w)
+ .select(
+ 'a, 'b, 'c,
+ 'b.sum over 'w,
+ "SUM:".toExpr + ('b.sum over 'w),
+ countFun('b) over 'w,
+ (countFun('b) over 'w) + 1,
+ plusOne(countFun('b) over 'w),
+ array('b.avg over 'w, 'b.max over 'w),
+ 'b.avg over 'w,
+ 'b.max over 'w,
+ 'b.min over 'w,
+ ('b.min over 'w).abs(),
+ weightAvgFun('b, 'a) over 'w)
+
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,2,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,1,Hi,7,SUM:7,4,5,5,[1, 3],1,3,1,1,1",
+ "2,1,Hello,1,SUM:1,1,2,2,[1, 1],1,1,1,1,1",
+ "2,2,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "2,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,4,Hello world,11,SUM:11,5,6,6,[2, 4],2,4,1,1,2",
+ "1,5,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
+ "1,6,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
+ "1,7,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
+ "2,4,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3",
+ "2,5,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3"
+ )
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeBoundedPartitionedRowsOver(): Unit = {
+
+ val data = List(
+ (1, 1L, 0, "Hallo", 1L),
+ (2, 2L, 1, "Hallo Welt", 2L),
+ (2, 3L, 2, "Hallo Welt wie", 1L),
+ (3, 4L, 3, "Hallo Welt wie gehts?", 2L),
+ (3, 5L, 4, "ABC", 2L),
+ (3, 6L, 5, "BCD", 3L),
+ (4, 7L, 6, "CDE", 2L),
+ (4, 8L, 7, "DEF", 1L),
+ (4, 9L, 8, "EFG", 1L),
+ (4, 10L, 9, "FGH", 2L),
+ (5, 11L, 10, "GHI", 1L),
+ (5, 12L, 11, "HIJ", 3L),
+ (5, 13L, 12, "IJK", 3L),
+ (5, 14L, 13, "JKL", 2L),
+ (5, 15L, 14, "KLM", 2L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setParallelism(1)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Over partitionBy 'a orderBy 'proctime preceding 4.rows following CURRENT_ROW as 'w)
+ .select('a, 'c.sum over 'w, 'c.min over 'w)
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,0,0",
+ "2,1,1",
+ "2,3,1",
+ "3,3,3",
+ "3,7,3",
+ "3,12,3",
+ "4,6,6",
+ "4,13,6",
+ "4,21,6",
+ "4,30,6",
+ "5,10,10",
+ "5,21,10",
+ "5,33,10",
+ "5,46,10",
+ "5,60,10")
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRowOver(): Unit = {
+ val data = Seq(
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((3L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Right(2L),
+ Left((3L, (3L, 3, "Hello"))),
+ Left((4L, (4L, 4, "Hello"))),
+ Left((5L, (5L, 5, "Hello"))),
+ Left((6L, (6L, 6, "Hello"))),
+ Left((20L, (20L, 20, "Hello World"))),
+ Right(6L),
+ Left((8L, (8L, 8, "Hello World"))),
+ Left((7L, (7L, 7, "Hello World"))),
+ Right(20L))
+
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val table = env.addSource[(Long, Int, String)](
+ new RowTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_ROW as 'w)
+ .select('c, 'a, 'a.count over 'w, 'a.sum over 'w)
+
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
+ "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
+ "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
+ "Hello,6,3,15",
+ "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
+ "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRangeOver(): Unit = {
+ val data = Seq(
+ Left((1500L, (1L, 15, "Hello"))),
+ Left((1600L, (1L, 16, "Hello"))),
+ Left((1000L, (1L, 1, "Hello"))),
+ Left((2000L, (2L, 2, "Hello"))),
+ Right(1000L),
+ Left((2000L, (2L, 2, "Hello"))),
+ Left((2000L, (2L, 3, "Hello"))),
+ Left((3000L, (3L, 3, "Hello"))),
+ Right(2000L),
+ Left((4000L, (4L, 4, "Hello"))),
+ Right(3000L),
+ Left((5000L, (5L, 5, "Hello"))),
+ Right(5000L),
+ Left((6000L, (6L, 6, "Hello"))),
+ Left((6500L, (6L, 65, "Hello"))),
+ Right(7000L),
+ Left((9000L, (6L, 9, "Hello"))),
+ Left((9500L, (6L, 18, "Hello"))),
+ Left((9000L, (6L, 9, "Hello"))),
+ Right(10000L),
+ Left((10000L, (7L, 7, "Hello World"))),
+ Left((11000L, (7L, 17, "Hello World"))),
+ Left((11000L, (7L, 77, "Hello World"))),
+ Right(12000L),
+ Left((14000L, (7L, 18, "Hello World"))),
+ Right(14000L),
+ Left((15000L, (8L, 8, "Hello World"))),
+ Right(17000L),
+ Left((20000L, (20L, 20, "Hello World"))),
+ Right(19000L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val table = env.addSource[(Long, Int, String)](
+ new RowTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(
+ Over partitionBy 'c orderBy 'rowtime preceding 1.seconds following CURRENT_RANGE as 'w)
+ .select('c, 'b, 'a.count over 'w, 'a.sum over 'w)
+
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
+ "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
+ "Hello,3,4,9",
+ "Hello,4,2,7",
+ "Hello,5,2,9",
+ "Hello,6,2,11", "Hello,65,2,12",
+ "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
+ "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
+ "Hello World,8,2,15",
+ "Hello World,20,1,20")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
+
+object OverWindowITCase {
+
+ class RowTimeSourceFunction[T](
+ dataWithTimestampList: Seq[Either[(Long, T), Long]]) extends SourceFunction[T] {
+ override def run(ctx: SourceContext[T]): Unit = {
+ dataWithTimestampList.foreach {
+ case Left(t) => ctx.collectWithTimestamp(t._2, t._1)
+ case Right(w) => ctx.emitWatermark(new Watermark(w))
+ }
+ }
+
+ override def cancel(): Unit = ???
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/RetractionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/RetractionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/RetractionITCase.scala
new file mode 100644
index 0000000..7e948f4
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/RetractionITCase.scala
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.table.utils.TableFunc0
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+/**
+ * tests for retraction
+ */
+class RetractionITCase extends StreamingWithStateTestBase {
+ // input data
+ val data = List(
+ ("Hello", 1),
+ ("word", 1),
+ ("Hello", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("flink", 1)
+ )
+
+ // keyed groupby + keyed groupby
+ @Test
+ def testWordCount(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .groupBy('word)
+ .select('num.sum as 'count)
+ .groupBy('count)
+ .select('count, 'count.count as 'frequency)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = Seq("1,2", "2,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ // keyed groupby + non-keyed groupby
+ @Test
+ def testGroupByAndNonKeyedGroupBy(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .groupBy('word)
+ .select('word as 'word, 'num.sum as 'cnt)
+ .select('cnt.sum)
+
+ val results = resultTable.toRetractStream[Row]
+
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = Seq("10")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ // non-keyed groupby + keyed groupby
+ @Test
+ def testNonKeyedGroupByAndGroupBy(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .select('num.sum as 'count)
+ .groupBy('count)
+ .select('count, 'count.count)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = Seq("10,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ // test unique process, if the current output message of unbounded groupby equals the
+ // previous message, unbounded groupby will ignore the current one.
+ @Test
+ def testUniqueProcess(): Unit = {
+ // data input
+ val data = List(
+ (1, 1L),
+ (2, 2L),
+ (3, 3L),
+ (3, 3L),
+ (4, 1L),
+ (4, 0L),
+ (4, 0L),
+ (4, 0L),
+ (5, 1L),
+ (6, 6L),
+ (6, 6L),
+ (6, 6L),
+ (7, 8L)
+ )
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'pk, 'value)
+ val resultTable = table
+ .groupBy('pk)
+ .select('pk as 'pk, 'value.sum as 'sum)
+ .groupBy('sum)
+ .select('sum, 'pk.count as 'count)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractMessagesSink)
+ env.execute()
+
+ val expected = Seq(
+ "+1,1", "+2,1", "+3,1", "-3,1", "+6,1", "-1,1", "+1,2", "-1,2", "+1,3", "-6,1", "+6,2",
+ "-6,2", "+6,1", "+12,1", "-12,1", "+18,1", "+8,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ // correlate should handle retraction messages correctly
+ @Test
+ def testCorrelate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val func0 = new TableFunc0
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .groupBy('word)
+ .select('word as 'word, 'num.sum as 'cnt)
+ .leftOuterJoin(func0('word))
+ .groupBy('cnt)
+ .select('cnt, 'word.count as 'frequency)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = Seq("1,2", "2,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/SetOperatorsITCase.scala
new file mode 100644
index 0000000..688849e
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/SetOperatorsITCase.scala
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamTestData}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class SetOperatorsITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'd, 'e, 'f)
+
+ val unionDs = ds1.unionAll(ds2).select('c)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Hi", "Hello", "Hello world", "Hi", "Hello", "Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnionWithFilter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
+
+ val unionDs = ds1.unionAll(ds2.select('a, 'b, 'c)).filter('b < 2).select('c)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Hi", "Hallo")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSinkITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSinkITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSinkITCase.scala
new file mode 100644
index 0000000..4121754
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSinkITCase.scala
@@ -0,0 +1,509 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import java.io.File
+import java.lang.{Boolean => JBool}
+
+import org.apache.flink.api.common.functions.MapFunction
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.tuple.{Tuple2 => JTuple2}
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.datastream.DataStream
+import org.apache.flink.streaming.api.functions.sink.SinkFunction
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.runtime.utils.StreamTestData
+import org.apache.flink.table.sinks._
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class TableSinkITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testStreamTableSink(): Unit = {
+
+ val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
+ tmpFile.deleteOnExit()
+ val path = tmpFile.toURI.toString
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setParallelism(4)
+
+ val input = StreamTestData.get3TupleDataStream(env)
+ .map(x => x).setParallelism(4) // increase DOP to 4
+
+ val results = input.toTable(tEnv, 'a, 'b, 'c)
+ .where('a < 5 || 'a > 17)
+ .select('c, 'b)
+ .writeToSink(new CsvTableSink(path))
+
+ env.execute()
+
+ val expected = Seq(
+ "Hi,1", "Hello,2", "Hello world,2", "Hello world, how are you?,3",
+ "Comment#12,6", "Comment#13,6", "Comment#14,6", "Comment#15,6").mkString("\n")
+
+ TestBaseUtils.compareResultsByLinesInMemory(expected, path)
+ }
+
+ @Test
+ def testAppendSinkOnAppendTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.end, 'id.count, 'num.sum)
+ .writeToSink(new TestAppendSink)
+
+ env.execute()
+
+ val result = RowCollector.getAndClearValues.map(_.f1.toString).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.005,4,8",
+ "1970-01-01 00:00:00.01,5,18",
+ "1970-01-01 00:00:00.015,5,24",
+ "1970-01-01 00:00:00.02,5,29",
+ "1970-01-01 00:00:00.025,2,12")
+ .sorted
+ assertEquals(expected, result)
+ }
+
+ @Test
+ def testRetractSinkOnUpdatingTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text)
+
+ t.select('id, 'num, 'text.charLength() as 'len)
+ .groupBy('len)
+ .select('len, 'id.count, 'num.sum)
+ .writeToSink(new TestRetractSink)
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ val retracted = restractResults(results).sorted
+ val expected = List(
+ "2,1,1",
+ "5,1,2",
+ "11,1,2",
+ "25,1,3",
+ "10,7,39",
+ "14,1,3",
+ "9,9,41").sorted
+ assertEquals(expected, retracted)
+
+ }
+
+ @Test
+ def testRetractSinkOnAppendTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.end, 'id.count, 'num.sum)
+ .writeToSink(new TestRetractSink)
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = restractResults(results).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.005,4,8",
+ "1970-01-01 00:00:00.01,5,18",
+ "1970-01-01 00:00:00.015,5,24",
+ "1970-01-01 00:00:00.02,5,29",
+ "1970-01-01 00:00:00.025,2,12")
+ .sorted
+ assertEquals(expected, retracted)
+
+ }
+
+ @Test
+ def testUpsertSinkOnUpdatingTableWithFullKey(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text)
+
+ t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
+ .groupBy('len, 'cTrue)
+ .select('len, 'id.count as 'cnt, 'cTrue)
+ .groupBy('cnt, 'cTrue)
+ .select('cnt, 'len.count, 'cTrue)
+ .writeToSink(new TestUpsertSink(Array("cnt", "cTrue"), false))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertTrue(
+ "Results must include delete messages",
+ results.exists(_.f0 == false)
+ )
+
+ val retracted = upsertResults(results, Array(0, 2)).sorted
+ val expected = List(
+ "1,5,true",
+ "7,1,true",
+ "9,1,true").sorted
+ assertEquals(expected, retracted)
+
+ }
+
+
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithFullKey1(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('num, 'w.end as 'wend, 'id.count)
+ .writeToSink(new TestUpsertSink(Array("wend", "num"), true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = upsertResults(results, Array(0, 1, 2)).sorted
+ val expected = List(
+ "1,1970-01-01 00:00:00.005,1",
+ "2,1970-01-01 00:00:00.005,2",
+ "3,1970-01-01 00:00:00.005,1",
+ "3,1970-01-01 00:00:00.01,2",
+ "4,1970-01-01 00:00:00.01,3",
+ "4,1970-01-01 00:00:00.015,1",
+ "5,1970-01-01 00:00:00.015,4",
+ "5,1970-01-01 00:00:00.02,1",
+ "6,1970-01-01 00:00:00.02,4",
+ "6,1970-01-01 00:00:00.025,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithFullKey2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('w.start as 'wstart, 'w.end as 'wend, 'num, 'id.count)
+ .writeToSink(new TestUpsertSink(Array("wstart", "wend", "num"), true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = upsertResults(results, Array(0, 1, 2)).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,1,1",
+ "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,2,2",
+ "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,3,1",
+ "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,3,2",
+ "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,4,3",
+ "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,4,1",
+ "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,5,4",
+ "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,5,1",
+ "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,6,4",
+ "1970-01-01 00:00:00.02,1970-01-01 00:00:00.025,6,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithoutFullKey1(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('w.end as 'wend, 'id.count as 'cnt)
+ .writeToSink(new TestUpsertSink(null, true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = results.map(_.f1.toString).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.005,1",
+ "1970-01-01 00:00:00.005,2",
+ "1970-01-01 00:00:00.005,1",
+ "1970-01-01 00:00:00.01,2",
+ "1970-01-01 00:00:00.01,3",
+ "1970-01-01 00:00:00.015,1",
+ "1970-01-01 00:00:00.015,4",
+ "1970-01-01 00:00:00.02,1",
+ "1970-01-01 00:00:00.02,4",
+ "1970-01-01 00:00:00.025,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithoutFullKey2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('num, 'id.count as 'cnt)
+ .writeToSink(new TestUpsertSink(null, true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = results.map(_.f1.toString).sorted
+ val expected = List(
+ "1,1",
+ "2,2",
+ "3,1",
+ "3,2",
+ "4,3",
+ "4,1",
+ "5,4",
+ "5,1",
+ "6,4",
+ "6,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ /** Converts a list of retraction messages into a list of final results. */
+ private def restractResults(results: List[JTuple2[JBool, Row]]): List[String] = {
+
+ val retracted = results
+ .foldLeft(Map[String, Int]()){ (m: Map[String, Int], v: JTuple2[JBool, Row]) =>
+ val cnt = m.getOrElse(v.f1.toString, 0)
+ if (v.f0) {
+ m + (v.f1.toString -> (cnt + 1))
+ } else {
+ m + (v.f1.toString -> (cnt - 1))
+ }
+ }.filter{ case (_, c: Int) => c != 0 }
+
+ assertFalse(
+ "Received retracted rows which have not been accumulated.",
+ retracted.exists{ case (_, c: Int) => c < 0})
+
+ retracted.flatMap { case (r: String, c: Int) => (0 until c).map(_ => r) }.toList
+ }
+
+ /** Converts a list of upsert messages into a list of final results. */
+ private def upsertResults(results: List[JTuple2[JBool, Row]], keys: Array[Int]): List[String] = {
+
+ def getKeys(r: Row): List[String] =
+ keys.foldLeft(List[String]())((k, i) => r.getField(i).toString :: k)
+
+ val upserted = results.foldLeft(Map[String, String]()){ (o: Map[String, String], r) =>
+ val key = getKeys(r.f1).mkString("")
+ if (r.f0) {
+ o + (key -> r.f1.toString)
+ } else {
+ o - key
+ }
+ }
+
+ upserted.values.toList
+ }
+
+}
+
+private[flink] class TestAppendSink extends AppendStreamTableSink[Row] {
+
+ var fNames: Array[String] = _
+ var fTypes: Array[TypeInformation[_]] = _
+
+ override def emitDataStream(s: DataStream[Row]): Unit = {
+ s.map(
+ new MapFunction[Row, JTuple2[JBool, Row]] {
+ override def map(value: Row): JTuple2[JBool, Row] = new JTuple2(true, value)
+ })
+ .addSink(new RowSink)
+ }
+
+ override def getOutputType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
+
+ override def getFieldNames: Array[String] = fNames
+
+ override def getFieldTypes: Array[TypeInformation[_]] = fTypes
+
+ override def configure(
+ fieldNames: Array[String],
+ fieldTypes: Array[TypeInformation[_]]): TableSink[Row] = {
+ val copy = new TestAppendSink
+ copy.fNames = fieldNames
+ copy.fTypes = fieldTypes
+ copy
+ }
+}
+
+private[flink] class TestRetractSink extends RetractStreamTableSink[Row] {
+
+ var fNames: Array[String] = _
+ var fTypes: Array[TypeInformation[_]] = _
+
+ override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
+ s.addSink(new RowSink)
+ }
+
+ override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
+
+ override def getFieldNames: Array[String] = fNames
+
+ override def getFieldTypes: Array[TypeInformation[_]] = fTypes
+
+ override def configure(
+ fieldNames: Array[String],
+ fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
+ val copy = new TestRetractSink
+ copy.fNames = fieldNames
+ copy.fTypes = fieldTypes
+ copy
+ }
+
+}
+
+private[flink] class TestUpsertSink(
+ expectedKeys: Array[String],
+ expectedIsAppendOnly: Boolean)
+ extends UpsertStreamTableSink[Row] {
+
+ var fNames: Array[String] = _
+ var fTypes: Array[TypeInformation[_]] = _
+
+ override def setKeyFields(keys: Array[String]): Unit =
+ if (keys != null) {
+ assertEquals("Provided key fields do not match expected keys",
+ expectedKeys.sorted.mkString(","),
+ keys.sorted.mkString(","))
+ } else {
+ assertNull("Provided key fields should not be null.", expectedKeys)
+ }
+
+ override def setIsAppendOnly(isAppendOnly: JBool): Unit =
+ assertEquals(
+ "Provided isAppendOnly does not match expected isAppendOnly",
+ expectedIsAppendOnly,
+ isAppendOnly)
+
+ override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
+
+ override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
+ s.addSink(new RowSink)
+ }
+
+ override def getFieldNames: Array[String] = fNames
+
+ override def getFieldTypes: Array[TypeInformation[_]] = fTypes
+
+ override def configure(
+ fieldNames: Array[String],
+ fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
+ val copy = new TestUpsertSink(expectedKeys, expectedIsAppendOnly)
+ copy.fNames = fieldNames
+ copy.fTypes = fieldTypes
+ copy
+ }
+}
+
+class RowSink extends SinkFunction[JTuple2[JBool, Row]] {
+ override def invoke(value: JTuple2[JBool, Row]): Unit = RowCollector.addValue(value)
+}
+
+object RowCollector {
+ private val sink: mutable.ArrayBuffer[JTuple2[JBool, Row]] =
+ new mutable.ArrayBuffer[JTuple2[JBool, Row]]()
+
+ def addValue(value: JTuple2[JBool, Row]): Unit = {
+ sink.synchronized {
+ sink += value
+ }
+ }
+
+ def getAndClearValues: List[JTuple2[JBool, Row]] = {
+ val out = sink.toList
+ sink.clear()
+ out
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala
new file mode 100644
index 0000000..297e9cf
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.{CommonTestData, StreamITCase}
+import org.apache.flink.table.utils.TestFilterableTableSource
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class TableSourceITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testCsvTableSource(): Unit = {
+
+ val csvTable = CommonTestData.getCsvTableSource
+ StreamITCase.testResults = mutable.MutableList()
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ tEnv.registerTableSource("csvTable", csvTable)
+ tEnv.scan("csvTable")
+ .where('id > 4)
+ .select('last, 'score * 2)
+ .toAppendStream[Row]
+ .addSink(new StreamITCase.StringSink[Row])
+
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Williams,69.0",
+ "Miller,13.56",
+ "Smith,180.2",
+ "Williams,4.68")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testCsvTableSourceWithFilterable(): Unit = {
+ StreamITCase.testResults = mutable.MutableList()
+ val tableName = "MyTable"
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerTableSource(tableName, new TestFilterableTableSource)
+ tEnv.scan(tableName)
+ .where("amount > 4 && price < 9")
+ .select("id, name")
+ .addSink(new StreamITCase.StringSink[Row])
+
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/CommonTestData.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/CommonTestData.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/CommonTestData.scala
new file mode 100644
index 0000000..d716d5d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/CommonTestData.scala
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import java.io.{File, FileOutputStream, OutputStreamWriter}
+import java.util
+
+import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
+import org.apache.flink.api.java.typeutils.TypeExtractor
+import org.apache.flink.api.java.{DataSet, ExecutionEnvironment}
+import org.apache.flink.table.api.TableSchema
+import org.apache.flink.table.catalog._
+import org.apache.flink.table.sources.{BatchTableSource, CsvTableSource}
+
+object CommonTestData {
+
+ def getCsvTableSource: CsvTableSource = {
+ val csvRecords = Seq(
+ "First#Id#Score#Last",
+ "Mike#1#12.3#Smith",
+ "Bob#2#45.6#Taylor",
+ "Sam#3#7.89#Miller",
+ "Peter#4#0.12#Smith",
+ "% Just a comment",
+ "Liz#5#34.5#Williams",
+ "Sally#6#6.78#Miller",
+ "Alice#7#90.1#Smith",
+ "Kelly#8#2.34#Williams"
+ )
+
+ val tempFilePath = writeToTempFile(csvRecords.mkString("$"), "csv-test", "tmp")
+ new CsvTableSource(
+ tempFilePath,
+ Array("first", "id", "score", "last"),
+ Array(
+ BasicTypeInfo.STRING_TYPE_INFO,
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.DOUBLE_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO
+ ),
+ fieldDelim = "#",
+ rowDelim = "$",
+ ignoreFirstLine = true,
+ ignoreComments = "%"
+ )
+ }
+
+ def getInMemoryTestCatalog: ExternalCatalog = {
+ val csvRecord1 = Seq(
+ "1#1#Hi",
+ "2#2#Hello",
+ "3#2#Hello world"
+ )
+ val tempFilePath1 = writeToTempFile(csvRecord1.mkString("$"), "csv-test1", "tmp")
+ val properties1 = new util.HashMap[String, String]()
+ properties1.put("path", tempFilePath1)
+ properties1.put("fieldDelim", "#")
+ properties1.put("rowDelim", "$")
+ val externalCatalogTable1 = ExternalCatalogTable(
+ "csv",
+ new TableSchema(
+ Array("a", "b", "c"),
+ Array(
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.LONG_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO)),
+ properties1
+ )
+
+ val csvRecord2 = Seq(
+ "1#1#0#Hallo#1",
+ "2#2#1#Hallo Welt#2",
+ "2#3#2#Hallo Welt wie#1",
+ "3#4#3#Hallo Welt wie gehts?#2",
+ "3#5#4#ABC#2",
+ "3#6#5#BCD#3",
+ "4#7#6#CDE#2",
+ "4#8#7#DEF#1",
+ "4#9#8#EFG#1",
+ "4#10#9#FGH#2",
+ "5#11#10#GHI#1",
+ "5#12#11#HIJ#3",
+ "5#13#12#IJK#3",
+ "5#14#13#JKL#2",
+ "5#15#14#KLM#2"
+ )
+ val tempFilePath2 = writeToTempFile(csvRecord2.mkString("$"), "csv-test2", "tmp")
+ val properties2 = new util.HashMap[String, String]()
+ properties2.put("path", tempFilePath2)
+ properties2.put("fieldDelim", "#")
+ properties2.put("rowDelim", "$")
+ val externalCatalogTable2 = ExternalCatalogTable(
+ "csv",
+ new TableSchema(
+ Array("d", "e", "f", "g", "h"),
+ Array(
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.LONG_TYPE_INFO,
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO,
+ BasicTypeInfo.LONG_TYPE_INFO)
+ ),
+ properties2
+ )
+ val catalog = new InMemoryExternalCatalog("test")
+ val db1 = new InMemoryExternalCatalog("db1")
+ val db2 = new InMemoryExternalCatalog("db2")
+ catalog.createSubCatalog("db1", db1, ignoreIfExists = false)
+ catalog.createSubCatalog("db2", db2, ignoreIfExists = false)
+
+ // Register the table with both catalogs
+ catalog.createTable("tb1", externalCatalogTable1, ignoreIfExists = false)
+ db1.createTable("tb1", externalCatalogTable1, ignoreIfExists = false)
+ db2.createTable("tb2", externalCatalogTable2, ignoreIfExists = false)
+ catalog
+ }
+
+ private def writeToTempFile(
+ contents: String,
+ filePrefix: String,
+ fileSuffix: String,
+ charset: String = "UTF-8"): String = {
+ val tempFile = File.createTempFile(filePrefix, fileSuffix)
+ tempFile.deleteOnExit()
+ val tmpWriter = new OutputStreamWriter(new FileOutputStream(tempFile), charset)
+ tmpWriter.write(contents)
+ tmpWriter.close()
+ tempFile.getAbsolutePath
+ }
+
+ def getNestedTableSource: BatchTableSource[Person] = {
+ new BatchTableSource[Person] {
+ override def getDataSet(execEnv: ExecutionEnvironment): DataSet[Person] = {
+ val executionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ executionEnvironment.fromCollection(
+ util.Arrays.asList(
+ new Person("Mike", "Smith", new Address("5th Ave", "New-York")),
+ new Person("Sally", "Miller", new Address("Potsdamer Platz", "Berlin")),
+ new Person("Bob", "Taylor", new Address("Pearse Street", "Dublin"))),
+ getReturnType
+ )
+ }
+
+ override def getReturnType: TypeInformation[Person] = {
+ TypeExtractor.getForClass(classOf[Person])
+ }
+ }
+ }
+
+ class Person(var firstName: String, var lastName: String, var address: Address) {
+ def this() {
+ this(null, null, null)
+ }
+ }
+
+ class Address(var street: String, var city: String) {
+ def this() {
+ this(null, null)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/SortTestUtils.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/SortTestUtils.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/SortTestUtils.scala
new file mode 100644
index 0000000..f102f53
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/SortTestUtils.scala
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+object SortTestUtils {
+
+ val tupleDataSetStrings = List((1, 1L, "Hi")
+ ,(2, 2L, "Hello")
+ ,(3, 2L, "Hello world")
+ ,(4, 3L, "Hello world, how are you?")
+ ,(5, 3L, "I am fine.")
+ ,(6, 3L, "Luke Skywalker")
+ ,(7, 4L, "Comment#1")
+ ,(8, 4L, "Comment#2")
+ ,(9, 4L, "Comment#3")
+ ,(10, 4L, "Comment#4")
+ ,(11, 5L, "Comment#5")
+ ,(12, 5L, "Comment#6")
+ ,(13, 5L, "Comment#7")
+ ,(14, 5L, "Comment#8")
+ ,(15, 5L, "Comment#9")
+ ,(16, 6L, "Comment#10")
+ ,(17, 6L, "Comment#11")
+ ,(18, 6L, "Comment#12")
+ ,(19, 6L, "Comment#13")
+ ,(20, 6L, "Comment#14")
+ ,(21, 6L, "Comment#15"))
+
+ def sortExpectedly(dataSet: List[Product])
+ (implicit ordering: Ordering[Product]): String =
+ sortExpectedly(dataSet, 0, dataSet.length)
+
+ def sortExpectedly(dataSet: List[Product], start: Int, end: Int)
+ (implicit ordering: Ordering[Product]): String = {
+ dataSet
+ .sorted(ordering)
+ .slice(start, end)
+ .mkString("\n")
+ .replaceAll("[\\(\\)]", "")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamITCase.scala
new file mode 100644
index 0000000..5386b40
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamITCase.scala
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import java.util.Collections
+
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction
+import org.apache.flink.types.Row
+import org.junit.Assert._
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+import scala.collection.mutable.ArrayBuffer
+
+object StreamITCase {
+
+ var testResults: mutable.MutableList[String] = mutable.MutableList.empty[String]
+ var retractedResults: ArrayBuffer[String] = mutable.ArrayBuffer.empty[String]
+
+ def clear = {
+ StreamITCase.testResults.clear()
+ StreamITCase.retractedResults.clear()
+ }
+
+ def compareWithList(expected: java.util.List[String]): Unit = {
+ Collections.sort(expected)
+ assertEquals(expected.asScala, StreamITCase.testResults.sorted)
+ }
+
+ final class StringSink[T] extends RichSinkFunction[T]() {
+ def invoke(value: T) {
+ testResults.synchronized {
+ testResults += value.toString
+ }
+ }
+ }
+
+ final class RetractMessagesSink extends RichSinkFunction[(Boolean, Row)]() {
+ def invoke(v: (Boolean, Row)) {
+ testResults.synchronized {
+ testResults += (if (v._1) "+" else "-") + v._2
+ }
+ }
+ }
+
+ final class RetractingSink() extends RichSinkFunction[(Boolean, Row)] {
+ def invoke(v: (Boolean, Row)) {
+ retractedResults.synchronized {
+ val value = v._2.toString
+ if (v._1) {
+ retractedResults += value
+ } else {
+ val idx = retractedResults.indexOf(value)
+ if (idx >= 0) {
+ retractedResults.remove(idx)
+ } else {
+ throw new RuntimeException("Tried to retract a value that wasn't added first. " +
+ "This is probably an incorrectly implemented test. " +
+ "Try to set the parallelism of the sink to 1.")
+ }
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamTestData.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamTestData.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamTestData.scala
new file mode 100644
index 0000000..94ced19
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamTestData.scala
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
+
+import scala.collection.mutable
+
+object StreamTestData {
+
+ def getSmall3TupleDataStream(env: StreamExecutionEnvironment): DataStream[(Int, Long, String)] = {
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Hi"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((3, 2L, "Hello world"))
+ env.fromCollection(data)
+ }
+
+ def get3TupleDataStream(env: StreamExecutionEnvironment): DataStream[(Int, Long, String)] = {
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Hi"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((3, 2L, "Hello world"))
+ data.+=((4, 3L, "Hello world, how are you?"))
+ data.+=((5, 3L, "I am fine."))
+ data.+=((6, 3L, "Luke Skywalker"))
+ data.+=((7, 4L, "Comment#1"))
+ data.+=((8, 4L, "Comment#2"))
+ data.+=((9, 4L, "Comment#3"))
+ data.+=((10, 4L, "Comment#4"))
+ data.+=((11, 5L, "Comment#5"))
+ data.+=((12, 5L, "Comment#6"))
+ data.+=((13, 5L, "Comment#7"))
+ data.+=((14, 5L, "Comment#8"))
+ data.+=((15, 5L, "Comment#9"))
+ data.+=((16, 6L, "Comment#10"))
+ data.+=((17, 6L, "Comment#11"))
+ data.+=((18, 6L, "Comment#12"))
+ data.+=((19, 6L, "Comment#13"))
+ data.+=((20, 6L, "Comment#14"))
+ data.+=((21, 6L, "Comment#15"))
+ env.fromCollection(data)
+ }
+
+ def get5TupleDataStream(env: StreamExecutionEnvironment):
+ DataStream[(Int, Long, Int, String, Long)] = {
+
+ val data = new mutable.MutableList[(Int, Long, Int, String, Long)]
+ data.+=((1, 1L, 0, "Hallo", 1L))
+ data.+=((2, 2L, 1, "Hallo Welt", 2L))
+ data.+=((2, 3L, 2, "Hallo Welt wie", 1L))
+ data.+=((3, 4L, 3, "Hallo Welt wie gehts?", 2L))
+ data.+=((3, 5L, 4, "ABC", 2L))
+ data.+=((3, 6L, 5, "BCD", 3L))
+ data.+=((4, 7L, 6, "CDE", 2L))
+ data.+=((4, 8L, 7, "DEF", 1L))
+ data.+=((4, 9L, 8, "EFG", 1L))
+ data.+=((4, 10L, 9, "FGH", 2L))
+ data.+=((5, 11L, 10, "GHI", 1L))
+ data.+=((5, 12L, 11, "HIJ", 3L))
+ data.+=((5, 13L, 12, "IJK", 3L))
+ data.+=((5, 14L, 13, "JKL", 2L))
+ data.+=((5, 15L, 14, "KLM", 2L))
+ env.fromCollection(data)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamingWithStateTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamingWithStateTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamingWithStateTestBase.scala
new file mode 100644
index 0000000..8c41f22
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/StreamingWithStateTestBase.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.runtime.utils
+
+import org.apache.flink.contrib.streaming.state.RocksDBStateBackend
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.junit.Rule
+import org.junit.rules.TemporaryFolder
+
+class StreamingWithStateTestBase extends StreamingMultipleProgramsTestBase {
+
+ val _tempFolder = new TemporaryFolder
+
+ @Rule
+ def tempFolder: TemporaryFolder = _tempFolder
+
+ def getStateBackend: RocksDBStateBackend = {
+ val dbPath = tempFolder.newFolder().getAbsolutePath
+ val checkpointPath = tempFolder.newFolder().toURI.toString
+ val backend = new RocksDBStateBackend(checkpointPath)
+ backend.setDbStoragePath(dbPath)
+ backend
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsClusterTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsClusterTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsClusterTestBase.scala
new file mode 100644
index 0000000..77b58a7
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsClusterTestBase.scala
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import java.util
+
+import org.apache.flink.table.runtime.batch.table.GroupWindowITCase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConversions._
+
+/**
+ * This test base provides full cluster-like integration tests for batch programs. Only runtime
+ * operator tests should use this test base as they are expensive.
+ * (e.g. [[GroupWindowITCase]])
+ */
+class TableProgramsClusterTestBase(
+ executionMode: TestExecutionMode,
+ tableConfigMode: TableConfigMode)
+ extends TableProgramsTestBase(executionMode, tableConfigMode) {
+}
+
+object TableProgramsClusterTestBase {
+
+ @Parameterized.Parameters(name = "Execution mode = {0}, Table config = {1}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](
+ Array(TestExecutionMode.CLUSTER, TableProgramsTestBase.DEFAULT),
+ Array(TestExecutionMode.CLUSTER_OBJECT_REUSE, TableProgramsTestBase.DEFAULT)
+ )
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsCollectionTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsCollectionTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsCollectionTestBase.scala
new file mode 100644
index 0000000..8947855
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsCollectionTestBase.scala
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import java.util
+
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConversions._
+
+/**
+ * This test base provides lightweight integration tests for batch programs. However, it does
+ * not test everything (e.g. combiners). Runtime operator tests should
+ * use [[TableProgramsClusterTestBase]].
+ */
+class TableProgramsCollectionTestBase(
+ tableConfigMode: TableConfigMode)
+ extends TableProgramsTestBase(TestExecutionMode.COLLECTION, tableConfigMode) {
+}
+
+object TableProgramsCollectionTestBase {
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](Array(TableProgramsTestBase.DEFAULT))
+ }
+}
[29/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramExtractorTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramExtractorTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramExtractorTest.scala
new file mode 100644
index 0000000..840be17
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramExtractorTest.scala
@@ -0,0 +1,524 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import java.math.BigDecimal
+
+import org.apache.calcite.rex.{RexBuilder, RexProgram, RexProgramBuilder}
+import org.apache.calcite.sql.SqlPostfixOperator
+import org.apache.calcite.sql.`type`.SqlTypeName.{BIGINT, INTEGER, VARCHAR}
+import org.apache.calcite.sql.fun.SqlStdOperatorTable
+import org.apache.flink.table.expressions._
+import org.apache.flink.table.plan.util.RexProgramExtractor
+import org.apache.flink.table.utils.InputTypeBuilder.inputOf
+import org.apache.flink.table.validate.FunctionCatalog
+import org.hamcrest.CoreMatchers.is
+import org.junit.Assert.{assertArrayEquals, assertEquals, assertThat}
+import org.junit.Test
+
+import scala.collection.JavaConverters._
+
+class RexProgramExtractorTest extends RexProgramTestBase {
+
+ private val functionCatalog: FunctionCatalog = FunctionCatalog.withBuiltIns
+
+ @Test
+ def testExtractRefInputFields(): Unit = {
+ val usedFields = RexProgramExtractor.extractRefInputFields(buildSimpleRexProgram())
+ assertArrayEquals(usedFields, Array(2, 3, 1))
+ }
+
+ @Test
+ def testExtractSimpleCondition(): Unit = {
+ val builder: RexBuilder = new RexBuilder(typeFactory)
+ val program = buildSimpleRexProgram()
+
+ val firstExp = ExpressionParser.parseExpression("id > 6")
+ val secondExp = ExpressionParser.parseExpression("amount * price < 100")
+ val expected: Array[Expression] = Array(firstExp, secondExp)
+
+ val (convertedExpressions, unconvertedRexNodes) =
+ RexProgramExtractor.extractConjunctiveConditions(
+ program,
+ builder,
+ functionCatalog)
+
+ assertExpressionArrayEquals(expected, convertedExpressions)
+ assertEquals(0, unconvertedRexNodes.length)
+ }
+
+ @Test
+ def testExtractSingleCondition(): Unit = {
+ val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ // amount
+ val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
+ // id
+ val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
+
+ // a = amount >= id
+ val a = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, t0, t1))
+ builder.addCondition(a)
+
+ val program = builder.getProgram
+ val relBuilder: RexBuilder = new RexBuilder(typeFactory)
+ val (convertedExpressions, unconvertedRexNodes) =
+ RexProgramExtractor.extractConjunctiveConditions(
+ program,
+ relBuilder,
+ functionCatalog)
+
+ val expected: Array[Expression] = Array(ExpressionParser.parseExpression("amount >= id"))
+ assertExpressionArrayEquals(expected, convertedExpressions)
+ assertEquals(0, unconvertedRexNodes.length)
+ }
+
+ // ((a AND b) OR c) AND (NOT d) => (a OR c) AND (b OR c) AND (NOT d)
+ @Test
+ def testExtractCnfCondition(): Unit = {
+ val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ // amount
+ val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
+ // id
+ val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
+ // price
+ val t2 = rexBuilder.makeInputRef(allFieldTypes.get(3), 3)
+ // 100
+ val t3 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
+
+ // a = amount < 100
+ val a = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, t0, t3))
+ // b = id > 100
+ val b = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, t1, t3))
+ // c = price == 100
+ val c = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, t2, t3))
+ // d = amount <= id
+ val d = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, t0, t1))
+
+ // a AND b
+ val and = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.AND, List(a, b).asJava))
+ // (a AND b) or c
+ val or = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.OR, List(and, c).asJava))
+ // not d
+ val not = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.NOT, List(d).asJava))
+
+ // (a AND b) OR c) AND (NOT d)
+ builder.addCondition(builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.AND, List(or, not).asJava)))
+
+ val program = builder.getProgram
+ val relBuilder: RexBuilder = new RexBuilder(typeFactory)
+ val (convertedExpressions, unconvertedRexNodes) =
+ RexProgramExtractor.extractConjunctiveConditions(
+ program,
+ relBuilder,
+ functionCatalog)
+
+ val expected: Array[Expression] = Array(
+ ExpressionParser.parseExpression("amount < 100 || price == 100"),
+ ExpressionParser.parseExpression("id > 100 || price == 100"),
+ ExpressionParser.parseExpression("!(amount <= id)"))
+ assertExpressionArrayEquals(expected, convertedExpressions)
+ assertEquals(0, unconvertedRexNodes.length)
+ }
+
+ @Test
+ def testExtractArithmeticConditions(): Unit = {
+ val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ // amount
+ val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
+ // id
+ val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
+ // 100
+ val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
+
+ val condition = List(
+ // amount < id
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, t0, t1)),
+ // amount <= id
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, t0, t1)),
+ // amount <> id
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.NOT_EQUALS, t0, t1)),
+ // amount == id
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, t0, t1)),
+ // amount >= id
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, t0, t1)),
+ // amount > id
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, t0, t1)),
+ // amount + id == 100
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+ rexBuilder.makeCall(SqlStdOperatorTable.PLUS, t0, t1), t2)),
+ // amount - id == 100
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+ rexBuilder.makeCall(SqlStdOperatorTable.MINUS, t0, t1), t2)),
+ // amount * id == 100
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+ rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, t0, t1), t2)),
+ // amount / id == 100
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+ rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, t0, t1), t2)),
+ // -amount == 100
+ builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+ rexBuilder.makeCall(SqlStdOperatorTable.UNARY_MINUS, t0), t2))
+ ).asJava
+
+ builder.addCondition(builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.AND, condition)))
+ val program = builder.getProgram
+ val relBuilder: RexBuilder = new RexBuilder(typeFactory)
+ val (convertedExpressions, unconvertedRexNodes) =
+ RexProgramExtractor.extractConjunctiveConditions(
+ program,
+ relBuilder,
+ functionCatalog)
+
+ val expected: Array[Expression] = Array(
+ ExpressionParser.parseExpression("amount < id"),
+ ExpressionParser.parseExpression("amount <= id"),
+ ExpressionParser.parseExpression("amount <> id"),
+ ExpressionParser.parseExpression("amount == id"),
+ ExpressionParser.parseExpression("amount >= id"),
+ ExpressionParser.parseExpression("amount > id"),
+ ExpressionParser.parseExpression("amount + id == 100"),
+ ExpressionParser.parseExpression("amount - id == 100"),
+ ExpressionParser.parseExpression("amount * id == 100"),
+ ExpressionParser.parseExpression("amount / id == 100"),
+ ExpressionParser.parseExpression("-amount == 100")
+ )
+ assertExpressionArrayEquals(expected, convertedExpressions)
+ assertEquals(0, unconvertedRexNodes.length)
+ }
+
+ @Test
+ def testExtractPostfixConditions(): Unit = {
+ testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_NULL, "('flag).isNull")
+ // IS_NOT_NULL will be eliminated since flag is not nullable
+ // testExtractSinglePostfixCondition(SqlStdOperatorTable.IS_NOT_NULL, "('flag).isNotNull")
+ testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_TRUE, "('flag).isTrue")
+ testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_NOT_TRUE, "('flag).isNotTrue")
+ testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_FALSE, "('flag).isFalse")
+ testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_NOT_FALSE, "('flag).isNotFalse")
+ }
+
+ @Test
+ def testExtractConditionWithFunctionCalls(): Unit = {
+ val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ // amount
+ val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
+ // id
+ val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
+ // 100
+ val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
+
+ // sum(amount) > 100
+ val condition1 = builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN,
+ rexBuilder.makeCall(SqlStdOperatorTable.SUM, t0), t2))
+
+ // min(id) == 100
+ val condition2 = builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+ rexBuilder.makeCall(SqlStdOperatorTable.MIN, t1), t2))
+
+ builder.addCondition(builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.AND, condition1, condition2)))
+
+ val program = builder.getProgram
+ val relBuilder: RexBuilder = new RexBuilder(typeFactory)
+ val (convertedExpressions, unconvertedRexNodes) =
+ RexProgramExtractor.extractConjunctiveConditions(
+ program,
+ relBuilder,
+ functionCatalog)
+
+ val expected: Array[Expression] = Array(
+ GreaterThan(Sum(UnresolvedFieldReference("amount")), Literal(100)),
+ EqualTo(Min(UnresolvedFieldReference("id")), Literal(100))
+ )
+ assertExpressionArrayEquals(expected, convertedExpressions)
+ assertEquals(0, unconvertedRexNodes.length)
+ }
+
+ @Test
+ def testExtractWithUnsupportedConditions(): Unit = {
+ val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ // amount
+ val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
+ // id
+ val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
+ // 100
+ val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
+
+ // unsupported now: amount.cast(BigInteger)
+ val cast = builder.addExpr(rexBuilder.makeCast(allFieldTypes.get(1), t0))
+
+ // unsupported now: amount.cast(BigInteger) > 100
+ val condition1 = builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, cast, t2))
+
+ // amount <= id
+ val condition2 = builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, t0, t1))
+
+ // contains unsupported condition: (amount.cast(BigInteger) > 100 OR amount <= id)
+ val condition3 = builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.OR, condition1, condition2))
+
+ // only condition2 can be translated
+ builder.addCondition(
+ rexBuilder.makeCall(SqlStdOperatorTable.AND, condition1, condition2, condition3))
+
+ val program = builder.getProgram
+ val relBuilder: RexBuilder = new RexBuilder(typeFactory)
+ val (convertedExpressions, unconvertedRexNodes) =
+ RexProgramExtractor.extractConjunctiveConditions(
+ program,
+ relBuilder,
+ functionCatalog)
+
+ val expected: Array[Expression] = Array(
+ ExpressionParser.parseExpression("amount <= id")
+ )
+ assertExpressionArrayEquals(expected, convertedExpressions)
+ assertEquals(2, unconvertedRexNodes.length)
+ assertEquals(">(CAST($2):BIGINT NOT NULL, 100)", unconvertedRexNodes(0).toString)
+ assertEquals("OR(>(CAST($2):BIGINT NOT NULL, 100), <=($2, $1))",
+ unconvertedRexNodes(1).toString)
+ }
+
+ @Test
+ def testExtractRefNestedInputFields(): Unit = {
+ val rexProgram = buildRexProgramWithNesting()
+
+ val usedFields = RexProgramExtractor.extractRefInputFields(rexProgram)
+ val usedNestedFields = RexProgramExtractor.extractRefNestedInputFields(rexProgram, usedFields)
+
+ val expected = Array(Array("amount"), Array("*"))
+ assertThat(usedNestedFields, is(expected))
+ }
+
+ @Test
+ def testExtractRefNestedInputFieldsWithNoNesting(): Unit = {
+ val rexProgram = buildSimpleRexProgram()
+
+ val usedFields = RexProgramExtractor.extractRefInputFields(rexProgram)
+ val usedNestedFields = RexProgramExtractor.extractRefNestedInputFields(rexProgram, usedFields)
+
+ val expected = Array(Array("*"), Array("*"), Array("*"))
+ assertThat(usedNestedFields, is(expected))
+ }
+
+ @Test
+ def testExtractDeepRefNestedInputFields(): Unit = {
+ val rexProgram = buildRexProgramWithDeepNesting()
+
+ val usedFields = RexProgramExtractor.extractRefInputFields(rexProgram)
+ val usedNestedFields = RexProgramExtractor.extractRefNestedInputFields(rexProgram, usedFields)
+
+ val expected = Array(
+ Array("amount"),
+ Array("*"),
+ Array("with.deeper.entry", "with.deep.entry"))
+
+ assertThat(usedFields, is(Array(1, 0, 2)))
+ assertThat(usedNestedFields, is(expected))
+ }
+
+ private def buildRexProgramWithDeepNesting(): RexProgram = {
+
+ // person input
+ val passportRow = inputOf(typeFactory)
+ .field("id", VARCHAR)
+ .field("status", VARCHAR)
+ .build
+
+ val personRow = inputOf(typeFactory)
+ .field("name", VARCHAR)
+ .field("age", INTEGER)
+ .nestedField("passport", passportRow)
+ .build
+
+ // payment input
+ val paymentRow = inputOf(typeFactory)
+ .field("id", BIGINT)
+ .field("amount", INTEGER)
+ .build
+
+ // deep field input
+ val deepRowType = inputOf(typeFactory)
+ .field("entry", VARCHAR)
+ .build
+
+ val entryRowType = inputOf(typeFactory)
+ .nestedField("inside", deepRowType)
+ .build
+
+ val deeperRowType = inputOf(typeFactory)
+ .nestedField("entry", entryRowType)
+ .build
+
+ val withRowType = inputOf(typeFactory)
+ .nestedField("deep", deepRowType)
+ .nestedField("deeper", deeperRowType)
+ .build
+
+ val fieldRowType = inputOf(typeFactory)
+ .nestedField("with", withRowType)
+ .build
+
+ // main input
+ val inputRowType = inputOf(typeFactory)
+ .nestedField("persons", personRow)
+ .nestedField("payments", paymentRow)
+ .nestedField("field", fieldRowType)
+ .build
+
+ // inputRowType
+ //
+ // [ persons: [ name: VARCHAR, age: INT, passport: [id: VARCHAR, status: VARCHAR ] ],
+ // payments: [ id: BIGINT, amount: INT ],
+ // field: [ with: [ deep: [ entry: VARCHAR ],
+ // deeper: [ entry: [ inside: [entry: VARCHAR ] ] ]
+ // ] ]
+ // ]
+
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ val t0 = rexBuilder.makeInputRef(personRow, 0)
+ val t1 = rexBuilder.makeInputRef(paymentRow, 1)
+ val t2 = rexBuilder.makeInputRef(fieldRowType, 2)
+ val t3 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(10L))
+
+ // person
+ val person$pass = rexBuilder.makeFieldAccess(t0, "passport", false)
+ val person$pass$stat = rexBuilder.makeFieldAccess(person$pass, "status", false)
+
+ // payment
+ val pay$amount = rexBuilder.makeFieldAccess(t1, "amount", false)
+ val multiplyAmount = builder.addExpr(
+ rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, pay$amount, t3))
+
+ // field
+ val field$with = rexBuilder.makeFieldAccess(t2, "with", false)
+ val field$with$deep = rexBuilder.makeFieldAccess(field$with, "deep", false)
+ val field$with$deeper = rexBuilder.makeFieldAccess(field$with, "deeper", false)
+ val field$with$deep$entry = rexBuilder.makeFieldAccess(field$with$deep, "entry", false)
+ val field$with$deeper$entry = rexBuilder.makeFieldAccess(field$with$deeper, "entry", false)
+ val field$with$deeper$entry$inside = rexBuilder
+ .makeFieldAccess(field$with$deeper$entry, "inside", false)
+ val field$with$deeper$entry$inside$entry = rexBuilder
+ .makeFieldAccess(field$with$deeper$entry$inside, "entry", false)
+
+ builder.addProject(multiplyAmount, "amount")
+ builder.addProject(person$pass$stat, "status")
+ builder.addProject(field$with$deep$entry, "entry")
+ builder.addProject(field$with$deeper$entry$inside$entry, "entry")
+ builder.addProject(field$with$deeper$entry, "entry2")
+ builder.addProject(t0, "person")
+
+ // Program
+ // (
+ // payments.amount * 10),
+ // persons.passport.status,
+ // field.with.deep.entry
+ // field.with.deeper.entry.inside.entry
+ // field.with.deeper.entry
+ // persons
+ // )
+
+ builder.getProgram
+
+ }
+
+ private def buildRexProgramWithNesting(): RexProgram = {
+
+ val personRow = inputOf(typeFactory)
+ .field("name", INTEGER)
+ .field("age", VARCHAR)
+ .build
+
+ val paymentRow = inputOf(typeFactory)
+ .field("id", BIGINT)
+ .field("amount", INTEGER)
+ .build
+
+ val types = List(personRow, paymentRow).asJava
+ val names = List("persons", "payments").asJava
+ val inputRowType = typeFactory.createStructType(types, names)
+
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ val t0 = rexBuilder.makeInputRef(types.get(0), 0)
+ val t1 = rexBuilder.makeInputRef(types.get(1), 1)
+ val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
+
+ val payment$amount = rexBuilder.makeFieldAccess(t1, "amount", false)
+
+ builder.addProject(payment$amount, "amount")
+ builder.addProject(t0, "persons")
+ builder.addProject(t2, "number")
+ builder.getProgram
+ }
+
+ private def testExtractSinglePostfixCondition(
+ fieldIndex: Integer,
+ op: SqlPostfixOperator,
+ expr: String) : Unit = {
+
+ val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+ rexBuilder = new RexBuilder(typeFactory)
+
+ // flag
+ val t0 = rexBuilder.makeInputRef(allFieldTypes.get(fieldIndex), fieldIndex)
+ builder.addCondition(builder.addExpr(rexBuilder.makeCall(op, t0)))
+
+ val program = builder.getProgram(false)
+ val relBuilder: RexBuilder = new RexBuilder(typeFactory)
+ val (convertedExpressions, unconvertedRexNodes) =
+ RexProgramExtractor.extractConjunctiveConditions(
+ program,
+ relBuilder,
+ functionCatalog)
+
+ assertEquals(1, convertedExpressions.length)
+ assertEquals(expr, convertedExpressions.head.toString)
+ assertEquals(0, unconvertedRexNodes.length)
+ }
+
+ private def assertExpressionArrayEquals(
+ expected: Array[Expression],
+ actual: Array[Expression]) = {
+ val sortedExpected = expected.sortBy(e => e.toString)
+ val sortedActual = actual.sortBy(e => e.toString)
+
+ assertEquals(sortedExpected.length, sortedActual.length)
+ sortedExpected.zip(sortedActual).foreach {
+ case (l, r) => assertEquals(l.toString, r.toString)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramRewriterTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramRewriterTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramRewriterTest.scala
new file mode 100644
index 0000000..dc91a82
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramRewriterTest.scala
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import org.apache.flink.table.plan.util.RexProgramRewriter
+import org.junit.Assert.assertTrue
+import org.junit.Test
+
+import scala.collection.JavaConverters._
+
+class RexProgramRewriterTest extends RexProgramTestBase {
+
+ @Test
+ def testRewriteRexProgram(): Unit = {
+ val rexProgram = buildSimpleRexProgram()
+ assertTrue(extractExprStrList(rexProgram) == wrapRefArray(Array(
+ "$0",
+ "$1",
+ "$2",
+ "$3",
+ "$4",
+ "*($t2, $t3)",
+ "100",
+ "<($t5, $t6)",
+ "6",
+ ">($t1, $t8)",
+ "AND($t7, $t9)")))
+
+ // use amount, id, price fields to create a new RexProgram
+ val usedFields = Array(2, 3, 1)
+ val types = usedFields.map(allFieldTypes.get).toList.asJava
+ val names = usedFields.map(allFieldNames.get).toList.asJava
+ val inputRowType = typeFactory.createStructType(types, names)
+ val newRexProgram = RexProgramRewriter.rewriteWithFieldProjection(
+ rexProgram, inputRowType, rexBuilder, usedFields)
+ assertTrue(extractExprStrList(newRexProgram) == wrapRefArray(Array(
+ "$0",
+ "$1",
+ "$2",
+ "*($t0, $t1)",
+ "100",
+ "<($t3, $t4)",
+ "6",
+ ">($t2, $t6)",
+ "AND($t5, $t7)")))
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramTestBase.scala
new file mode 100644
index 0000000..b711604
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RexProgramTestBase.scala
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import java.math.BigDecimal
+
+import org.apache.calcite.adapter.java.JavaTypeFactory
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl
+import org.apache.calcite.rel.`type`.{RelDataType, RelDataTypeSystem}
+import org.apache.calcite.rex.{RexBuilder, RexProgram, RexProgramBuilder}
+import org.apache.calcite.sql.`type`.SqlTypeName._
+import org.apache.calcite.sql.fun.SqlStdOperatorTable
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+abstract class RexProgramTestBase {
+
+ val typeFactory: JavaTypeFactory = new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT)
+
+ val allFieldNames: java.util.List[String] = List("name", "id", "amount", "price", "flag").asJava
+
+ val allFieldTypes: java.util.List[RelDataType] =
+ List(VARCHAR, BIGINT, INTEGER, DOUBLE, BOOLEAN).map(typeFactory.createSqlType).asJava
+
+ var rexBuilder: RexBuilder = new RexBuilder(typeFactory)
+
+ /**
+ * extract all expression string list from input RexProgram expression lists
+ *
+ * @param rexProgram input RexProgram instance to analyze
+ * @return all expression string list of input RexProgram expression lists
+ */
+ protected def extractExprStrList(rexProgram: RexProgram): mutable.Buffer[String] = {
+ rexProgram.getExprList.asScala.map(_.toString)
+ }
+
+ // select amount, amount * price as total where amount * price < 100 and id > 6
+ protected def buildSimpleRexProgram(): RexProgram = {
+ val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
+ val builder = new RexProgramBuilder(inputRowType, rexBuilder)
+
+ val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
+ val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
+ val t2 = rexBuilder.makeInputRef(allFieldTypes.get(3), 3)
+ val t3 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, t0, t2))
+ val t4 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
+ val t5 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(6L))
+
+ // project: amount, amount * price as total
+ builder.addProject(t0, "amount")
+ builder.addProject(t3, "total")
+
+ // condition: amount * price < 100 and id > 6
+ val t6 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, t3, t4))
+ val t7 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, t1, t5))
+ val t8 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.AND, List(t6, t7).asJava))
+ builder.addCondition(t8)
+
+ builder.getProgram
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala
new file mode 100644
index 0000000..7885160
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala
@@ -0,0 +1,398 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.{TimeIntervalUnit, WindowReference}
+import org.apache.flink.table.functions.TableFunction
+import org.apache.flink.table.plan.TimeIndicatorConversionTest.TableFunc
+import org.apache.flink.table.plan.logical.TumblingGroupWindow
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Tests for [[org.apache.flink.table.calcite.RelTimeIndicatorConverter]].
+ */
+class TimeIndicatorConversionTest extends TableTestBase {
+
+ @Test
+ def testSimpleMaterialization(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+
+ val result = t
+ .select('rowtime.floor(TimeIntervalUnit.DAY) as 'rowtime, 'long)
+ .filter('long > 0)
+ .select('rowtime)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "FLOOR(TIME_MATERIALIZATION(rowtime)", "FLAG(DAY)) AS rowtime"),
+ term("where", ">(long, 0)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testSelectAll(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+
+ val result = t.select('*)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long", "int",
+ "TIME_MATERIALIZATION(proctime) AS proctime")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testFilteringOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .filter('rowtime > "1990-12-02 12:11:11".toTimestamp)
+ .select('rowtime)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime"),
+ term("where", ">(TIME_MATERIALIZATION(rowtime), 1990-12-02 12:11:11)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testGroupingOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+
+ val result = t
+ .groupBy('rowtime)
+ .select('long.count)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "long", "TIME_MATERIALIZATION(rowtime) AS rowtime")
+ ),
+ term("groupBy", "rowtime"),
+ term("select", "rowtime", "COUNT(long) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testAggregationOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .groupBy('long)
+ .select('rowtime.min)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long")
+ ),
+ term("groupBy", "long"),
+ term("select", "long", "MIN(rowtime) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testTableFunction(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+ val func = new TableFunc
+
+ val result = t.join(func('rowtime, 'proctime, "") as 's).select('rowtime, 'proctime, 's)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation",
+ s"${func.functionIdentifier}(TIME_MATERIALIZATION($$0), TIME_MATERIALIZATION($$3), '')"),
+ term("function", func),
+ term("rowType", "RecordType(TIMESTAMP(3) rowtime, BIGINT long, INTEGER int, " +
+ "TIMESTAMP(3) proctime, VARCHAR(2147483647) s)"),
+ term("joinType", "INNER")
+ ),
+ term("select",
+ "TIME_MATERIALIZATION(rowtime) AS rowtime",
+ "TIME_MATERIALIZATION(proctime) AS proctime",
+ "s")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testWindow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .window(Tumble over 100.millis on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ .select('w.end as 'rowtime, 'long, 'int.sum)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w,
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "SUM(int) AS TMP_1", "end('w) AS TMP_0")
+ ),
+ term("select", "TMP_0 AS rowtime", "long", "TMP_1")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+
+ val result = t.unionAll(t).select('rowtime)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ binaryNode(
+ "DataStreamUnion",
+ streamTableNode(0),
+ streamTableNode(0),
+ term("union all", "rowtime", "long", "int")
+ ),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testMultiWindow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .window(Tumble over 100.millis on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ .select('w.rowtime as 'newrowtime, 'long, 'int.sum as 'int)
+ .window(Tumble over 1.second on 'newrowtime as 'w2)
+ .groupBy('w2, 'long)
+ .select('w2.end, 'long, 'int.sum)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w,
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "SUM(int) AS TMP_1", "rowtime('w) AS TMP_0")
+ ),
+ term("select", "TMP_0 AS newrowtime", "long", "TMP_1 AS int")
+ ),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w2,
+ 'newrowtime,
+ 1000.millis)),
+ term("select", "long", "SUM(int) AS TMP_3", "end('w2) AS TMP_2")
+ ),
+ term("select", "TMP_2", "long", "TMP_3")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testGroupingOnProctime(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
+
+ val result = util.tableEnv.sql("SELECT COUNT(long) FROM MyTable GROUP BY proctime")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(proctime) AS proctime", "long")
+ ),
+ term("groupBy", "proctime"),
+ term("select", "proctime", "COUNT(long) AS EXPR$0")
+ ),
+ term("select", "EXPR$0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testAggregationOnProctime(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
+
+ val result = util.tableEnv.sql("SELECT MIN(proctime) FROM MyTable GROUP BY long")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "long", "TIME_MATERIALIZATION(proctime) AS proctime")
+ ),
+ term("groupBy", "long"),
+ term("select", "long", "MIN(proctime) AS EXPR$0")
+ ),
+ term("select", "EXPR$0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testWindowSql(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+
+ val result = util.tableEnv.sql(
+ "SELECT TUMBLE_END(rowtime, INTERVAL '0.1' SECOND) AS `rowtime`, `long`, " +
+ "SUM(`int`) FROM MyTable " +
+ "GROUP BY `long`, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w$"),
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "SUM(int) AS EXPR$2", "start('w$) AS w$start", "end('w$) AS w$end")
+ ),
+ term("select", "w$end", "long", "EXPR$2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testWindowWithAggregationOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+
+ val result = util.tableEnv.sql("SELECT MIN(rowtime), long FROM MyTable " +
+ "GROUP BY long, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "long", "rowtime", "TIME_MATERIALIZATION(rowtime) AS $f2")
+ ),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w$,
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "MIN($f2) AS EXPR$0")
+ ),
+ term("select", "EXPR$0", "long")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
+
+object TimeIndicatorConversionTest {
+
+ class TableFunc extends TableFunction[String] {
+ val t = new Timestamp(0L)
+ def eval(time1: Long, time2: Timestamp, string: String): Unit = {
+ collect(time1.toString + time2.after(t) + string)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala
deleted file mode 100644
index c307de5..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.plan.rules
-
-import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule
-import org.apache.calcite.tools.RuleSets
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.calcite.{CalciteConfig, CalciteConfigBuilder}
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class NormalizationRulesTest extends TableTestBase {
-
- @Test
- def testApplyNormalizationRuleForBatchSQL(): Unit = {
- val util = batchTestUtil()
-
- // rewrite distinct aggregate
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceNormRuleSet(RuleSets.ofList(AggregateExpandDistinctAggregatesRule.JOIN))
- .replaceLogicalOptRuleSet(RuleSets.ofList())
- .replacePhysicalOptRuleSet(RuleSets.ofList())
- .build()
- util.tableEnv.getConfig.setCalciteConfig(cc)
-
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "COUNT(DISTINCT a)" +
- "FROM MyTable group by b"
-
- // expect double aggregate
- val expected = unaryNode("LogicalProject",
- unaryNode("LogicalAggregate",
- unaryNode("LogicalAggregate",
- unaryNode("LogicalProject",
- values("LogicalTableScan", term("table", "[_DataSetTable_0]")),
- term("b", "$1"), term("a", "$0")),
- term("group", "{0, 1}")),
- term("group", "{0}"), term("EXPR$0", "COUNT($1)")
- ),
- term("EXPR$0", "$1")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testApplyNormalizationRuleForStreamSQL(): Unit = {
- val util = streamTestUtil()
-
- // rewrite distinct aggregate
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceNormRuleSet(RuleSets.ofList(AggregateExpandDistinctAggregatesRule.JOIN))
- .replaceLogicalOptRuleSet(RuleSets.ofList())
- .replacePhysicalOptRuleSet(RuleSets.ofList())
- .build()
- util.tableEnv.getConfig.setCalciteConfig(cc)
-
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "COUNT(DISTINCT a)" +
- "FROM MyTable group by b"
-
- // expect double aggregate
- val expected = unaryNode(
- "LogicalProject",
- unaryNode("LogicalAggregate",
- unaryNode("LogicalAggregate",
- unaryNode("LogicalProject",
- values("LogicalTableScan", term("table", "[_DataStreamTable_0]")),
- term("b", "$1"), term("a", "$0")),
- term("group", "{0, 1}")),
- term("group", "{0}"), term("EXPR$0", "COUNT($1)")
- ),
- term("EXPR$0", "$1")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala
deleted file mode 100644
index 75d2f22..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.plan.rules
-
-import org.apache.calcite.rel.RelNode
-import org.apache.flink.table.api.Table
-import org.apache.flink.table.plan.nodes.datastream._
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Assert._
-import org.junit.{Ignore, Test}
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-
-
-class RetractionRulesTest extends TableTestBase {
-
- def streamTestForRetractionUtil(): StreamTableTestForRetractionUtil = {
- new StreamTableTestForRetractionUtil()
- }
-
- @Test
- def testSelect(): Unit = {
- val util = streamTestForRetractionUtil()
- val table = util.addTable[(String, Int)]('word, 'number)
-
- val resultTable = table.select('word, 'number)
-
- val expected = s"DataStreamScan(false, Acc)"
-
- util.verifyTableTrait(resultTable, expected)
- }
-
- // one level unbounded groupBy
- @Test
- def testGroupBy(): Unit = {
- val util = streamTestForRetractionUtil()
- val table = util.addTable[(String, Int)]('word, 'number)
- val defaultStatus = "false, Acc"
-
- val resultTable = table
- .groupBy('word)
- .select('number.count)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- "DataStreamScan(true, Acc)",
- s"$defaultStatus"
- ),
- s"$defaultStatus"
- )
-
- util.verifyTableTrait(resultTable, expected)
- }
-
- // two level unbounded groupBy
- @Test
- def testTwoGroupBy(): Unit = {
- val util = streamTestForRetractionUtil()
- val table = util.addTable[(String, Int)]('word, 'number)
- val defaultStatus = "false, Acc"
-
- val resultTable = table
- .groupBy('word)
- .select('word, 'number.count as 'count)
- .groupBy('count)
- .select('count, 'count.count as 'frequency)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- "DataStreamScan(true, Acc)",
- "true, AccRetract"
- ),
- "true, AccRetract"
- ),
- s"$defaultStatus"
- ),
- s"$defaultStatus"
- )
-
- util.verifyTableTrait(resultTable, expected)
- }
-
- // group window
- @Test
- def testGroupWindow(): Unit = {
- val util = streamTestForRetractionUtil()
- val table = util.addTable[(String, Int)]('word, 'number, 'rowtime.rowtime)
- val defaultStatus = "false, Acc"
-
- val resultTable = table
- .window(Tumble over 50.milli on 'rowtime as 'w)
- .groupBy('w, 'word)
- .select('word, 'number.count as 'count)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- "DataStreamScan(true, Acc)",
- s"$defaultStatus"
- ),
- s"$defaultStatus"
- )
-
- util.verifyTableTrait(resultTable, expected)
- }
-
- // group window after unbounded groupBy
- @Test
- @Ignore // cannot pass rowtime through non-windowed aggregation
- def testGroupWindowAfterGroupBy(): Unit = {
- val util = streamTestForRetractionUtil()
- val table = util.addTable[(String, Int)]('word, 'number, 'rowtime.rowtime)
- val defaultStatus = "false, Acc"
-
- val resultTable = table
- .groupBy('word)
- .select('word, 'number.count as 'count)
- .window(Tumble over 50.milli on 'rowtime as 'w)
- .groupBy('w, 'count)
- .select('count, 'count.count as 'frequency)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- "DataStreamScan(true, Acc)",
- "true, AccRetract"
- ),
- "true, AccRetract"
- ),
- s"$defaultStatus"
- ),
- s"$defaultStatus"
- )
-
- util.verifyTableTrait(resultTable, expected)
- }
-
- // over window
- @Test
- def testOverWindow(): Unit = {
- val util = streamTestForRetractionUtil()
- util.addTable[(String, Int)]("T1", 'word, 'number, 'proctime.proctime)
- val defaultStatus = "false, Acc"
-
- val sqlQuery =
- "SELECT " +
- "word, count(number) " +
- "OVER (PARTITION BY word ORDER BY proctime " +
- "ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW)" +
- "FROM T1"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- "DataStreamScan(true, Acc)",
- s"$defaultStatus"
- ),
- s"$defaultStatus"
- )
-
- util.verifySqlTrait(sqlQuery, expected)
- }
-
-
- // over window after unbounded groupBy
- @Test
- @Ignore // cannot pass rowtime through non-windowed aggregation
- def testOverWindowAfterGroupBy(): Unit = {
- val util = streamTestForRetractionUtil()
- util.addTable[(String, Int)]("T1", 'word, 'number, 'proctime.proctime)
- val defaultStatus = "false, Acc"
-
- val sqlQuery =
- "SELECT " +
- "_count, count(word) " +
- "OVER (PARTITION BY _count ORDER BY proctime " +
- "ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW)" +
- "FROM " +
- "(SELECT word, count(number) as _count FROM T1 GROUP BY word) "
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- "DataStreamScan(true, Acc)",
- "true, AccRetract"
- ),
- "true, AccRetract"
- ),
- s"$defaultStatus"
- ),
- s"$defaultStatus"
- )
-
- util.verifySqlTrait(sqlQuery, expected)
- }
-
- // test binaryNode
- @Test
- def testBinaryNode(): Unit = {
- val util = streamTestForRetractionUtil()
- val lTable = util.addTable[(String, Int)]('word, 'number)
- val rTable = util.addTable[(String, Long)]('word_r, 'count_r)
- val defaultStatus = "false, Acc"
-
- val resultTable = lTable
- .groupBy('word)
- .select('word, 'number.count as 'count)
- .unionAll(rTable)
- .groupBy('count)
- .select('count, 'count.count as 'frequency)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- binaryNode(
- "DataStreamUnion",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- "DataStreamScan(true, Acc)",
- "true, AccRetract"
- ),
- "true, AccRetract"
- ),
- "DataStreamScan(true, Acc)",
- "true, AccRetract"
- ),
- "true, AccRetract"
- ),
- s"$defaultStatus"
- ),
- s"$defaultStatus"
- )
-
- util.verifyTableTrait(resultTable, expected)
- }
-}
-
-class StreamTableTestForRetractionUtil extends StreamTableTestUtil {
-
- def verifySqlTrait(query: String, expected: String): Unit = {
- verifyTableTrait(tableEnv.sql(query), expected)
- }
-
- def verifyTableTrait(resultTable: Table, expected: String): Unit = {
- val relNode = resultTable.getRelNode
- val optimized = tableEnv.optimize(relNode, updatesAsRetraction = false)
- val actual = TraitUtil.toString(optimized)
- assertEquals(
- expected.split("\n").map(_.trim).mkString("\n"),
- actual.split("\n").map(_.trim).mkString("\n"))
- }
-}
-
-object TraitUtil {
- def toString(rel: RelNode): String = {
- val className = rel.getClass.getSimpleName
- var childString: String = ""
- var i = 0
- while (i < rel.getInputs.size()) {
- childString += TraitUtil.toString(rel.getInput(i))
- i += 1
- }
-
- val retractString = rel.getTraitSet.getTrait(UpdateAsRetractionTraitDef.INSTANCE).toString
- val accModetString = rel.getTraitSet.getTrait(AccModeTraitDef.INSTANCE).toString
-
- s"""$className($retractString, $accModetString)
- |$childString
- |""".stripMargin.stripLineEnd
- }
-}
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramExtractorTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramExtractorTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramExtractorTest.scala
deleted file mode 100644
index 5d5eece..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramExtractorTest.scala
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.plan.util
-
-import java.math.BigDecimal
-
-import org.apache.calcite.rex.{RexBuilder, RexProgram, RexProgramBuilder}
-import org.apache.calcite.sql.SqlPostfixOperator
-import org.apache.calcite.sql.`type`.SqlTypeName.{BIGINT, INTEGER, VARCHAR}
-import org.apache.calcite.sql.fun.SqlStdOperatorTable
-import org.apache.flink.table.expressions._
-import org.apache.flink.table.utils.InputTypeBuilder.inputOf
-import org.apache.flink.table.validate.FunctionCatalog
-import org.hamcrest.CoreMatchers.is
-import org.junit.Assert.{assertArrayEquals, assertEquals, assertThat}
-import org.junit.Test
-
-import scala.collection.JavaConverters._
-
-class RexProgramExtractorTest extends RexProgramTestBase {
-
- private val functionCatalog: FunctionCatalog = FunctionCatalog.withBuiltIns
-
- @Test
- def testExtractRefInputFields(): Unit = {
- val usedFields = RexProgramExtractor.extractRefInputFields(buildSimpleRexProgram())
- assertArrayEquals(usedFields, Array(2, 3, 1))
- }
-
- @Test
- def testExtractSimpleCondition(): Unit = {
- val builder: RexBuilder = new RexBuilder(typeFactory)
- val program = buildSimpleRexProgram()
-
- val firstExp = ExpressionParser.parseExpression("id > 6")
- val secondExp = ExpressionParser.parseExpression("amount * price < 100")
- val expected: Array[Expression] = Array(firstExp, secondExp)
-
- val (convertedExpressions, unconvertedRexNodes) =
- RexProgramExtractor.extractConjunctiveConditions(
- program,
- builder,
- functionCatalog)
-
- assertExpressionArrayEquals(expected, convertedExpressions)
- assertEquals(0, unconvertedRexNodes.length)
- }
-
- @Test
- def testExtractSingleCondition(): Unit = {
- val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- // amount
- val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
- // id
- val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
-
- // a = amount >= id
- val a = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, t0, t1))
- builder.addCondition(a)
-
- val program = builder.getProgram
- val relBuilder: RexBuilder = new RexBuilder(typeFactory)
- val (convertedExpressions, unconvertedRexNodes) =
- RexProgramExtractor.extractConjunctiveConditions(
- program,
- relBuilder,
- functionCatalog)
-
- val expected: Array[Expression] = Array(ExpressionParser.parseExpression("amount >= id"))
- assertExpressionArrayEquals(expected, convertedExpressions)
- assertEquals(0, unconvertedRexNodes.length)
- }
-
- // ((a AND b) OR c) AND (NOT d) => (a OR c) AND (b OR c) AND (NOT d)
- @Test
- def testExtractCnfCondition(): Unit = {
- val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- // amount
- val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
- // id
- val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
- // price
- val t2 = rexBuilder.makeInputRef(allFieldTypes.get(3), 3)
- // 100
- val t3 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
-
- // a = amount < 100
- val a = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, t0, t3))
- // b = id > 100
- val b = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, t1, t3))
- // c = price == 100
- val c = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, t2, t3))
- // d = amount <= id
- val d = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, t0, t1))
-
- // a AND b
- val and = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.AND, List(a, b).asJava))
- // (a AND b) or c
- val or = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.OR, List(and, c).asJava))
- // not d
- val not = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.NOT, List(d).asJava))
-
- // (a AND b) OR c) AND (NOT d)
- builder.addCondition(builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.AND, List(or, not).asJava)))
-
- val program = builder.getProgram
- val relBuilder: RexBuilder = new RexBuilder(typeFactory)
- val (convertedExpressions, unconvertedRexNodes) =
- RexProgramExtractor.extractConjunctiveConditions(
- program,
- relBuilder,
- functionCatalog)
-
- val expected: Array[Expression] = Array(
- ExpressionParser.parseExpression("amount < 100 || price == 100"),
- ExpressionParser.parseExpression("id > 100 || price == 100"),
- ExpressionParser.parseExpression("!(amount <= id)"))
- assertExpressionArrayEquals(expected, convertedExpressions)
- assertEquals(0, unconvertedRexNodes.length)
- }
-
- @Test
- def testExtractArithmeticConditions(): Unit = {
- val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- // amount
- val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
- // id
- val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
- // 100
- val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
-
- val condition = List(
- // amount < id
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, t0, t1)),
- // amount <= id
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, t0, t1)),
- // amount <> id
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.NOT_EQUALS, t0, t1)),
- // amount == id
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, t0, t1)),
- // amount >= id
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, t0, t1)),
- // amount > id
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, t0, t1)),
- // amount + id == 100
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
- rexBuilder.makeCall(SqlStdOperatorTable.PLUS, t0, t1), t2)),
- // amount - id == 100
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
- rexBuilder.makeCall(SqlStdOperatorTable.MINUS, t0, t1), t2)),
- // amount * id == 100
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
- rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, t0, t1), t2)),
- // amount / id == 100
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
- rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, t0, t1), t2)),
- // -amount == 100
- builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
- rexBuilder.makeCall(SqlStdOperatorTable.UNARY_MINUS, t0), t2))
- ).asJava
-
- builder.addCondition(builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.AND, condition)))
- val program = builder.getProgram
- val relBuilder: RexBuilder = new RexBuilder(typeFactory)
- val (convertedExpressions, unconvertedRexNodes) =
- RexProgramExtractor.extractConjunctiveConditions(
- program,
- relBuilder,
- functionCatalog)
-
- val expected: Array[Expression] = Array(
- ExpressionParser.parseExpression("amount < id"),
- ExpressionParser.parseExpression("amount <= id"),
- ExpressionParser.parseExpression("amount <> id"),
- ExpressionParser.parseExpression("amount == id"),
- ExpressionParser.parseExpression("amount >= id"),
- ExpressionParser.parseExpression("amount > id"),
- ExpressionParser.parseExpression("amount + id == 100"),
- ExpressionParser.parseExpression("amount - id == 100"),
- ExpressionParser.parseExpression("amount * id == 100"),
- ExpressionParser.parseExpression("amount / id == 100"),
- ExpressionParser.parseExpression("-amount == 100")
- )
- assertExpressionArrayEquals(expected, convertedExpressions)
- assertEquals(0, unconvertedRexNodes.length)
- }
-
- @Test
- def testExtractPostfixConditions(): Unit = {
- testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_NULL, "('flag).isNull")
- // IS_NOT_NULL will be eliminated since flag is not nullable
- // testExtractSinglePostfixCondition(SqlStdOperatorTable.IS_NOT_NULL, "('flag).isNotNull")
- testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_TRUE, "('flag).isTrue")
- testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_NOT_TRUE, "('flag).isNotTrue")
- testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_FALSE, "('flag).isFalse")
- testExtractSinglePostfixCondition(4, SqlStdOperatorTable.IS_NOT_FALSE, "('flag).isNotFalse")
- }
-
- @Test
- def testExtractConditionWithFunctionCalls(): Unit = {
- val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- // amount
- val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
- // id
- val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
- // 100
- val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
-
- // sum(amount) > 100
- val condition1 = builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN,
- rexBuilder.makeCall(SqlStdOperatorTable.SUM, t0), t2))
-
- // min(id) == 100
- val condition2 = builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
- rexBuilder.makeCall(SqlStdOperatorTable.MIN, t1), t2))
-
- builder.addCondition(builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.AND, condition1, condition2)))
-
- val program = builder.getProgram
- val relBuilder: RexBuilder = new RexBuilder(typeFactory)
- val (convertedExpressions, unconvertedRexNodes) =
- RexProgramExtractor.extractConjunctiveConditions(
- program,
- relBuilder,
- functionCatalog)
-
- val expected: Array[Expression] = Array(
- GreaterThan(Sum(UnresolvedFieldReference("amount")), Literal(100)),
- EqualTo(Min(UnresolvedFieldReference("id")), Literal(100))
- )
- assertExpressionArrayEquals(expected, convertedExpressions)
- assertEquals(0, unconvertedRexNodes.length)
- }
-
- @Test
- def testExtractWithUnsupportedConditions(): Unit = {
- val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- // amount
- val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
- // id
- val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
- // 100
- val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
-
- // unsupported now: amount.cast(BigInteger)
- val cast = builder.addExpr(rexBuilder.makeCast(allFieldTypes.get(1), t0))
-
- // unsupported now: amount.cast(BigInteger) > 100
- val condition1 = builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, cast, t2))
-
- // amount <= id
- val condition2 = builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, t0, t1))
-
- // contains unsupported condition: (amount.cast(BigInteger) > 100 OR amount <= id)
- val condition3 = builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.OR, condition1, condition2))
-
- // only condition2 can be translated
- builder.addCondition(
- rexBuilder.makeCall(SqlStdOperatorTable.AND, condition1, condition2, condition3))
-
- val program = builder.getProgram
- val relBuilder: RexBuilder = new RexBuilder(typeFactory)
- val (convertedExpressions, unconvertedRexNodes) =
- RexProgramExtractor.extractConjunctiveConditions(
- program,
- relBuilder,
- functionCatalog)
-
- val expected: Array[Expression] = Array(
- ExpressionParser.parseExpression("amount <= id")
- )
- assertExpressionArrayEquals(expected, convertedExpressions)
- assertEquals(2, unconvertedRexNodes.length)
- assertEquals(">(CAST($2):BIGINT NOT NULL, 100)", unconvertedRexNodes(0).toString)
- assertEquals("OR(>(CAST($2):BIGINT NOT NULL, 100), <=($2, $1))",
- unconvertedRexNodes(1).toString)
- }
-
- @Test
- def testExtractRefNestedInputFields(): Unit = {
- val rexProgram = buildRexProgramWithNesting()
-
- val usedFields = RexProgramExtractor.extractRefInputFields(rexProgram)
- val usedNestedFields = RexProgramExtractor.extractRefNestedInputFields(rexProgram, usedFields)
-
- val expected = Array(Array("amount"), Array("*"))
- assertThat(usedNestedFields, is(expected))
- }
-
- @Test
- def testExtractRefNestedInputFieldsWithNoNesting(): Unit = {
- val rexProgram = buildSimpleRexProgram()
-
- val usedFields = RexProgramExtractor.extractRefInputFields(rexProgram)
- val usedNestedFields = RexProgramExtractor.extractRefNestedInputFields(rexProgram, usedFields)
-
- val expected = Array(Array("*"), Array("*"), Array("*"))
- assertThat(usedNestedFields, is(expected))
- }
-
- @Test
- def testExtractDeepRefNestedInputFields(): Unit = {
- val rexProgram = buildRexProgramWithDeepNesting()
-
- val usedFields = RexProgramExtractor.extractRefInputFields(rexProgram)
- val usedNestedFields = RexProgramExtractor.extractRefNestedInputFields(rexProgram, usedFields)
-
- val expected = Array(
- Array("amount"),
- Array("*"),
- Array("with.deeper.entry", "with.deep.entry"))
-
- assertThat(usedFields, is(Array(1, 0, 2)))
- assertThat(usedNestedFields, is(expected))
- }
-
- private def buildRexProgramWithDeepNesting(): RexProgram = {
-
- // person input
- val passportRow = inputOf(typeFactory)
- .field("id", VARCHAR)
- .field("status", VARCHAR)
- .build
-
- val personRow = inputOf(typeFactory)
- .field("name", VARCHAR)
- .field("age", INTEGER)
- .nestedField("passport", passportRow)
- .build
-
- // payment input
- val paymentRow = inputOf(typeFactory)
- .field("id", BIGINT)
- .field("amount", INTEGER)
- .build
-
- // deep field input
- val deepRowType = inputOf(typeFactory)
- .field("entry", VARCHAR)
- .build
-
- val entryRowType = inputOf(typeFactory)
- .nestedField("inside", deepRowType)
- .build
-
- val deeperRowType = inputOf(typeFactory)
- .nestedField("entry", entryRowType)
- .build
-
- val withRowType = inputOf(typeFactory)
- .nestedField("deep", deepRowType)
- .nestedField("deeper", deeperRowType)
- .build
-
- val fieldRowType = inputOf(typeFactory)
- .nestedField("with", withRowType)
- .build
-
- // main input
- val inputRowType = inputOf(typeFactory)
- .nestedField("persons", personRow)
- .nestedField("payments", paymentRow)
- .nestedField("field", fieldRowType)
- .build
-
- // inputRowType
- //
- // [ persons: [ name: VARCHAR, age: INT, passport: [id: VARCHAR, status: VARCHAR ] ],
- // payments: [ id: BIGINT, amount: INT ],
- // field: [ with: [ deep: [ entry: VARCHAR ],
- // deeper: [ entry: [ inside: [entry: VARCHAR ] ] ]
- // ] ]
- // ]
-
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- val t0 = rexBuilder.makeInputRef(personRow, 0)
- val t1 = rexBuilder.makeInputRef(paymentRow, 1)
- val t2 = rexBuilder.makeInputRef(fieldRowType, 2)
- val t3 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(10L))
-
- // person
- val person$pass = rexBuilder.makeFieldAccess(t0, "passport", false)
- val person$pass$stat = rexBuilder.makeFieldAccess(person$pass, "status", false)
-
- // payment
- val pay$amount = rexBuilder.makeFieldAccess(t1, "amount", false)
- val multiplyAmount = builder.addExpr(
- rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, pay$amount, t3))
-
- // field
- val field$with = rexBuilder.makeFieldAccess(t2, "with", false)
- val field$with$deep = rexBuilder.makeFieldAccess(field$with, "deep", false)
- val field$with$deeper = rexBuilder.makeFieldAccess(field$with, "deeper", false)
- val field$with$deep$entry = rexBuilder.makeFieldAccess(field$with$deep, "entry", false)
- val field$with$deeper$entry = rexBuilder.makeFieldAccess(field$with$deeper, "entry", false)
- val field$with$deeper$entry$inside = rexBuilder
- .makeFieldAccess(field$with$deeper$entry, "inside", false)
- val field$with$deeper$entry$inside$entry = rexBuilder
- .makeFieldAccess(field$with$deeper$entry$inside, "entry", false)
-
- builder.addProject(multiplyAmount, "amount")
- builder.addProject(person$pass$stat, "status")
- builder.addProject(field$with$deep$entry, "entry")
- builder.addProject(field$with$deeper$entry$inside$entry, "entry")
- builder.addProject(field$with$deeper$entry, "entry2")
- builder.addProject(t0, "person")
-
- // Program
- // (
- // payments.amount * 10),
- // persons.passport.status,
- // field.with.deep.entry
- // field.with.deeper.entry.inside.entry
- // field.with.deeper.entry
- // persons
- // )
-
- builder.getProgram
-
- }
-
- private def buildRexProgramWithNesting(): RexProgram = {
-
- val personRow = inputOf(typeFactory)
- .field("name", INTEGER)
- .field("age", VARCHAR)
- .build
-
- val paymentRow = inputOf(typeFactory)
- .field("id", BIGINT)
- .field("amount", INTEGER)
- .build
-
- val types = List(personRow, paymentRow).asJava
- val names = List("persons", "payments").asJava
- val inputRowType = typeFactory.createStructType(types, names)
-
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- val t0 = rexBuilder.makeInputRef(types.get(0), 0)
- val t1 = rexBuilder.makeInputRef(types.get(1), 1)
- val t2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
-
- val payment$amount = rexBuilder.makeFieldAccess(t1, "amount", false)
-
- builder.addProject(payment$amount, "amount")
- builder.addProject(t0, "persons")
- builder.addProject(t2, "number")
- builder.getProgram
- }
-
- private def testExtractSinglePostfixCondition(
- fieldIndex: Integer,
- op: SqlPostfixOperator,
- expr: String) : Unit = {
-
- val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
- rexBuilder = new RexBuilder(typeFactory)
-
- // flag
- val t0 = rexBuilder.makeInputRef(allFieldTypes.get(fieldIndex), fieldIndex)
- builder.addCondition(builder.addExpr(rexBuilder.makeCall(op, t0)))
-
- val program = builder.getProgram(false)
- val relBuilder: RexBuilder = new RexBuilder(typeFactory)
- val (convertedExpressions, unconvertedRexNodes) =
- RexProgramExtractor.extractConjunctiveConditions(
- program,
- relBuilder,
- functionCatalog)
-
- assertEquals(1, convertedExpressions.length)
- assertEquals(expr, convertedExpressions.head.toString)
- assertEquals(0, unconvertedRexNodes.length)
- }
-
- private def assertExpressionArrayEquals(
- expected: Array[Expression],
- actual: Array[Expression]) = {
- val sortedExpected = expected.sortBy(e => e.toString)
- val sortedActual = actual.sortBy(e => e.toString)
-
- assertEquals(sortedExpected.length, sortedActual.length)
- sortedExpected.zip(sortedActual).foreach {
- case (l, r) => assertEquals(l.toString, r.toString)
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramRewriterTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramRewriterTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramRewriterTest.scala
deleted file mode 100644
index 899eed2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramRewriterTest.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.plan.util
-
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-import scala.collection.JavaConverters._
-
-class RexProgramRewriterTest extends RexProgramTestBase {
-
- @Test
- def testRewriteRexProgram(): Unit = {
- val rexProgram = buildSimpleRexProgram()
- assertTrue(extractExprStrList(rexProgram) == wrapRefArray(Array(
- "$0",
- "$1",
- "$2",
- "$3",
- "$4",
- "*($t2, $t3)",
- "100",
- "<($t5, $t6)",
- "6",
- ">($t1, $t8)",
- "AND($t7, $t9)")))
-
- // use amount, id, price fields to create a new RexProgram
- val usedFields = Array(2, 3, 1)
- val types = usedFields.map(allFieldTypes.get).toList.asJava
- val names = usedFields.map(allFieldNames.get).toList.asJava
- val inputRowType = typeFactory.createStructType(types, names)
- val newRexProgram = RexProgramRewriter.rewriteWithFieldProjection(
- rexProgram, inputRowType, rexBuilder, usedFields)
- assertTrue(extractExprStrList(newRexProgram) == wrapRefArray(Array(
- "$0",
- "$1",
- "$2",
- "*($t0, $t1)",
- "100",
- "<($t3, $t4)",
- "6",
- ">($t2, $t6)",
- "AND($t5, $t7)")))
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramTestBase.scala
deleted file mode 100644
index 6ef3d82..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/util/RexProgramTestBase.scala
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.plan.util
-
-import java.math.BigDecimal
-import java.util
-
-import org.apache.calcite.adapter.java.JavaTypeFactory
-import org.apache.calcite.jdbc.JavaTypeFactoryImpl
-import org.apache.calcite.rel.`type`.{RelDataType, RelDataTypeSystem}
-import org.apache.calcite.rex.{RexBuilder, RexProgram, RexProgramBuilder}
-import org.apache.calcite.sql.`type`.SqlTypeName.{BIGINT, DOUBLE, INTEGER, VARCHAR, BOOLEAN}
-import org.apache.calcite.sql.fun.SqlStdOperatorTable
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-abstract class RexProgramTestBase {
-
- val typeFactory: JavaTypeFactory = new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT)
-
- val allFieldNames: util.List[String] = List("name", "id", "amount", "price", "flag").asJava
-
- val allFieldTypes: util.List[RelDataType] =
- List(VARCHAR, BIGINT, INTEGER, DOUBLE, BOOLEAN).map(typeFactory.createSqlType).asJava
-
- var rexBuilder: RexBuilder = new RexBuilder(typeFactory)
-
- /**
- * extract all expression string list from input RexProgram expression lists
- *
- * @param rexProgram input RexProgram instance to analyze
- * @return all expression string list of input RexProgram expression lists
- */
- protected def extractExprStrList(rexProgram: RexProgram): mutable.Buffer[String] = {
- rexProgram.getExprList.asScala.map(_.toString)
- }
-
- // select amount, amount * price as total where amount * price < 100 and id > 6
- protected def buildSimpleRexProgram(): RexProgram = {
- val inputRowType = typeFactory.createStructType(allFieldTypes, allFieldNames)
- val builder = new RexProgramBuilder(inputRowType, rexBuilder)
-
- val t0 = rexBuilder.makeInputRef(allFieldTypes.get(2), 2)
- val t1 = rexBuilder.makeInputRef(allFieldTypes.get(1), 1)
- val t2 = rexBuilder.makeInputRef(allFieldTypes.get(3), 3)
- val t3 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, t0, t2))
- val t4 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(100L))
- val t5 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(6L))
-
- // project: amount, amount * price as total
- builder.addProject(t0, "amount")
- builder.addProject(t3, "total")
-
- // condition: amount * price < 100 and id > 6
- val t6 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, t3, t4))
- val t7 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, t1, t5))
- val t8 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.AND, List(t6, t7).asJava))
- builder.addCondition(t8)
-
- builder.getProgram
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AggFunctionTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AggFunctionTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AggFunctionTestBase.scala
new file mode 100644
index 0000000..458f80d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AggFunctionTestBase.scala
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.lang.reflect.Method
+import java.math.BigDecimal
+import java.util.{ArrayList => JArrayList, List => JList}
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions.{DecimalAvgAccumulator, DecimalSumWithRetractAccumulator}
+import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils._
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Base class for aggregate function test
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class AggFunctionTestBase[T, ACC] {
+ def inputValueSets: Seq[Seq[_]]
+
+ def expectedResults: Seq[T]
+
+ def aggregator: AggregateFunction[T, ACC]
+
+ val accType = aggregator.getClass.getMethod("createAccumulator").getReturnType
+
+ def accumulateFunc: Method = aggregator.getClass.getMethod("accumulate", accType, classOf[Any])
+
+ def retractFunc: Method = null
+
+ @Test
+ // test aggregate and retract functions without partial merge
+ def testAccumulateAndRetractWithoutMerge(): Unit = {
+ // iterate over input sets
+ for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
+ val accumulator = accumulateVals(vals)
+ val result = aggregator.getValue(accumulator)
+ validateResult[T](expected, result)
+
+ if (ifMethodExistInFunction("retract", aggregator)) {
+ retractVals(accumulator, vals)
+ val expectedAccum = aggregator.createAccumulator()
+ //The two accumulators should be exactly same
+ validateResult[ACC](expectedAccum, accumulator)
+ }
+ }
+ }
+
+ @Test
+ def testAggregateWithMerge(): Unit = {
+
+ if (ifMethodExistInFunction("merge", aggregator)) {
+ val mergeFunc =
+ aggregator.getClass.getMethod("merge", accType, classOf[java.lang.Iterable[ACC]])
+ // iterate over input sets
+ for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
+ //equally split the vals sequence into two sequences
+ val (firstVals, secondVals) = vals.splitAt(vals.length / 2)
+
+ //1. verify merge with accumulate
+ val accumulators: JList[ACC] = new JArrayList[ACC]()
+ accumulators.add(accumulateVals(secondVals))
+
+ val acc = accumulateVals(firstVals)
+
+ mergeFunc.invoke(aggregator, acc.asInstanceOf[Object], accumulators)
+ val result = aggregator.getValue(acc)
+ validateResult[T](expected, result)
+
+ //2. verify merge with accumulate & retract
+ if (ifMethodExistInFunction("retract", aggregator)) {
+ retractVals(acc, vals)
+ val expectedAccum = aggregator.createAccumulator()
+ //The two accumulators should be exactly same
+ validateResult[ACC](expectedAccum, acc)
+ }
+ }
+
+ // iterate over input sets
+ for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
+ //3. test partial merge with an empty accumulator
+ val accumulators: JList[ACC] = new JArrayList[ACC]()
+ accumulators.add(aggregator.createAccumulator())
+
+ val acc = accumulateVals(vals)
+
+ mergeFunc.invoke(aggregator, acc.asInstanceOf[Object], accumulators)
+ val result = aggregator.getValue(acc)
+ validateResult[T](expected, result)
+ }
+ }
+ }
+
+ @Test
+ // test aggregate functions with resetAccumulator
+ def testResetAccumulator(): Unit = {
+
+ if (ifMethodExistInFunction("resetAccumulator", aggregator)) {
+ val resetAccFunc = aggregator.getClass.getMethod("resetAccumulator", accType)
+ // iterate over input sets
+ for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
+ val accumulator = accumulateVals(vals)
+ resetAccFunc.invoke(aggregator, accumulator.asInstanceOf[Object])
+ val expectedAccum = aggregator.createAccumulator()
+ //The accumulator after reset should be exactly same as the new accumulator
+ validateResult[ACC](expectedAccum, accumulator)
+ }
+ }
+ }
+
+ private def validateResult[T](expected: T, result: T): Unit = {
+ (expected, result) match {
+ case (e: DecimalSumWithRetractAccumulator, r: DecimalSumWithRetractAccumulator) =>
+ // BigDecimal.equals() value and scale but we are only interested in value.
+ assert(e.f0.compareTo(r.f0) == 0 && e.f1 == r.f1)
+ case (e: DecimalAvgAccumulator, r: DecimalAvgAccumulator) =>
+ // BigDecimal.equals() value and scale but we are only interested in value.
+ assert(e.f0.compareTo(r.f0) == 0 && e.f1 == r.f1)
+ case (e: BigDecimal, r: BigDecimal) =>
+ // BigDecimal.equals() value and scale but we are only interested in value.
+ assert(e.compareTo(r) == 0)
+ case _ =>
+ assertEquals(expected, result)
+ }
+ }
+
+ private def accumulateVals(vals: Seq[_]): ACC = {
+ val accumulator = aggregator.createAccumulator()
+ vals.foreach(
+ v =>
+ accumulateFunc.invoke(aggregator, accumulator.asInstanceOf[Object], v.asInstanceOf[Object])
+ )
+ accumulator
+ }
+
+ private def retractVals(accumulator:ACC, vals: Seq[_]) = {
+ vals.foreach(
+ v => retractFunc.invoke(aggregator, accumulator.asInstanceOf[Object], v.asInstanceOf[Object])
+ )
+ }
+}
[39/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DistinctAggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DistinctAggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DistinctAggregateTest.scala
deleted file mode 100644
index 85cfb18..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DistinctAggregateTest.scala
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class DistinctAggregateTest extends TableTestBase {
-
- @Test
- def testSingleDistinctAggregate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT COUNT(DISTINCT a) FROM MyTable"
-
- val expected = unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a")
- ),
- term("distinct", "a")
- ),
- tuples(List(null)),
- term("values", "a")
- ),
- term("union", "a")
- ),
- term("select", "COUNT(a) AS EXPR$0")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testMultiDistinctAggregateOnSameColumn(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT a), MAX(DISTINCT a) FROM MyTable"
-
- val expected = unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a")
- ),
- term("distinct", "a")
- ),
- tuples(List(null)),
- term("values", "a")
- ),
- term("union", "a")
- ),
- term("select", "COUNT(a) AS EXPR$0", "SUM(a) AS EXPR$1", "MAX(a) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testSingleDistinctAggregateAndOneOrMultiNonDistinctAggregate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- // case 0x00: DISTINCT on COUNT and Non-DISTINCT on others
- val sqlQuery0 = "SELECT COUNT(DISTINCT a), SUM(b) FROM MyTable"
-
- val expected0 = unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("groupBy", "a"),
- term("select", "a", "SUM(b) AS EXPR$1")
- ),
- tuples(List(null, null)),
- term("values", "a", "EXPR$1")
- ),
- term("union", "a", "EXPR$1")
- ),
- term("select", "COUNT(a) AS EXPR$0", "SUM(EXPR$1) AS EXPR$1")
- )
-
- util.verifySql(sqlQuery0, expected0)
-
- // case 0x01: Non-DISTINCT on COUNT and DISTINCT on others
- val sqlQuery1 = "SELECT COUNT(a), SUM(DISTINCT b) FROM MyTable"
-
- val expected1 = unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("groupBy", "b"),
- term("select", "b", "COUNT(a) AS EXPR$0")
- ),
- tuples(List(null, null)),
- term("values", "b", "EXPR$0")
- ),
- term("union", "b", "EXPR$0")
- ),
- term("select", "$SUM0(EXPR$0) AS EXPR$0", "SUM(b) AS EXPR$1")
- )
-
- util.verifySql(sqlQuery1, expected1)
- }
-
- @Test
- def testMultiDistinctAggregateOnDifferentColumn(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT b) FROM MyTable"
-
- val expected = binaryNode(
- "DataSetSingleRowJoin",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a")
- ),
- term("distinct", "a")
- ),
- tuples(List(null)),
- term("values", "a")
- ),
- term("union", "a")
- ),
- term("select", "COUNT(a) AS EXPR$0")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "b")
- ),
- term("distinct", "b")
- ),
- tuples(List(null)),
- term("values", "b")
- ),
- term("union", "b")
- ),
- term("select", "SUM(b) AS EXPR$1")
- ),
- term("where", "true"),
- term("join", "EXPR$0", "EXPR$1"),
- term("joinType", "NestedLoopInnerJoin")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testMultiDistinctAndNonDistinctAggregateOnDifferentColumn(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT b), COUNT(c) FROM MyTable"
-
- val expected = unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetSingleRowJoin",
- binaryNode(
- "DataSetSingleRowJoin",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- batchTableNode(0),
- tuples(List(null, null, null)),
- term("values", "a, b, c")
- ),
- term("union", "a, b, c")
- ),
- term("select", "COUNT(c) AS EXPR$2")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a")
- ),
- term("distinct", "a")
- ),
- tuples(List(null)),
- term("values", "a")
- ),
- term("union", "a")
- ),
- term("select", "COUNT(a) AS EXPR$0")
- ),
- term("where", "true"),
- term("join", "EXPR$2, EXPR$0"),
- term("joinType", "NestedLoopInnerJoin")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "b")
- ),
- term("distinct", "b")
- ),
- tuples(List(null)),
- term("values", "b")
- ),
- term("union", "b")
- ),
- term("select", "SUM(b) AS EXPR$1")
- ),
- term("where", "true"),
- term("join", "EXPR$2", "EXPR$0, EXPR$1"),
- term("joinType", "NestedLoopInnerJoin")
- ),
- term("select", "EXPR$0, EXPR$1, EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testSingleDistinctAggregateWithGrouping(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, COUNT(a), SUM(DISTINCT b) FROM MyTable GROUP BY a"
-
- val expected = unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("groupBy", "a", "b"),
- term("select", "a", "b", "COUNT(a) AS EXPR$1")
- ),
- term("groupBy", "a"),
- term("select", "a", "SUM(EXPR$1) AS EXPR$1", "SUM(b) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testSingleDistinctAggregateWithGroupingAndCountStar(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b) FROM MyTable GROUP BY a"
-
- val expected = unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("groupBy", "a", "b"),
- term("select", "a", "b", "COUNT(*) AS EXPR$1")
- ),
- term("groupBy", "a"),
- term("select", "a", "SUM(EXPR$1) AS EXPR$1", "SUM(b) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testTwoDistinctAggregateWithGroupingAndCountStar(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b), COUNT(DISTINCT b) FROM MyTable GROUP BY a"
-
- val expected = unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("groupBy", "a"),
- term("select", "a", "COUNT(*) AS EXPR$1")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("distinct", "a, b")
- ),
- term("groupBy", "a"),
- term("select", "a, SUM(b) AS EXPR$2, COUNT(b) AS EXPR$3")
- ),
- term("where", "IS NOT DISTINCT FROM(a, a0)"),
- term("join", "a, EXPR$1, a0, EXPR$2, EXPR$3"),
- term("joinType", "InnerJoin")
- ),
- term("select", "a, EXPR$1, EXPR$2, EXPR$3")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testTwoDifferentDistinctAggregateWithGroupingAndCountStar(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b), COUNT(DISTINCT c) FROM MyTable GROUP BY a"
-
- val expected = unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "a"),
- term("select", "a, COUNT(*) AS EXPR$1")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("distinct", "a, b")
- ),
- term("groupBy", "a"),
- term("select", "a, SUM(b) AS EXPR$2")
- ),
- term("where", "IS NOT DISTINCT FROM(a, a0)"),
- term("join", "a, EXPR$1, a0, EXPR$2"),
- term("joinType", "InnerJoin")
- ),
- term("select", "a, EXPR$1, EXPR$2")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "c")
- ),
- term("distinct", "a, c")
- ),
- term("groupBy", "a"),
- term("select", "a, COUNT(c) AS EXPR$3")
- ),
- term("where", "IS NOT DISTINCT FROM(a, a0)"),
- term("join", "a, EXPR$1, EXPR$2, a0, EXPR$3"),
- term("joinType", "InnerJoin")
- ),
- term("select", "a, EXPR$1, EXPR$2, EXPR$3")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala
deleted file mode 100644
index 5d5d7f0..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- )
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "*" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/GroupingSetsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/GroupingSetsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/GroupingSetsTest.scala
deleted file mode 100644
index c12e5a6..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/GroupingSetsTest.scala
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class GroupingSetsTest extends TableTestBase {
-
- @Test
- def testGroupingSets(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g FROM MyTable " +
- "GROUP BY GROUPING SETS (b, c)"
-
- val aggregate = unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "b"),
- term("select", "b", "AVG(a) AS c")
- ),
- unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "c"),
- term("select", "c AS b", "AVG(a) AS c")
- ),
- term("union", "b", "c", "i$b", "i$c", "a")
- ),
- term("select",
- "CASE(i$b, null, b) AS b",
- "CASE(i$c, null, c) AS c",
- "a",
- "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g") // GROUP_ID()
- )
-
- util.verifySql(sqlQuery, aggregate)
- }
-
- @Test
- def testCube(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
- "GROUPING(b) as gb, GROUPING(c) as gc, " +
- "GROUPING_ID(b) as gib, GROUPING_ID(c) as gic, " +
- "GROUPING_ID(b, c) as gid " +
- "FROM MyTable " +
- "GROUP BY CUBE (b, c)"
-
- val group1 = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "b, c"),
- term("select", "b", "c",
- "AVG(a) AS i$b")
- )
-
- val group2 = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "b"),
- term("select", "b",
- "AVG(a) AS c")
- )
-
- val group3 = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "c"),
- term("select", "c AS b",
- "AVG(a) AS c")
- )
-
- val group4 = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("select",
- "AVG(a) AS b")
- )
-
- val union1 = binaryNode(
- "DataSetUnion",
- group1, group2,
- term("union", "b", "c", "i$b", "i$c", "a")
- )
-
- val union2 = binaryNode(
- "DataSetUnion",
- union1, group3,
- term("union", "b", "c", "i$b", "i$c", "a")
- )
-
- val union3 = binaryNode(
- "DataSetUnion",
- union2, group4,
- term("union", "b", "c", "i$b", "i$c", "a")
- )
-
- val aggregate = unaryNode(
- "DataSetCalc",
- union3,
- term("select",
- "CASE(i$b, null, b) AS b",
- "CASE(i$c, null, c) AS c",
- "a",
- "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g", // GROUP_ID()
- "CASE(i$b, 1, 0) AS gb", // GROUPING(b)
- "CASE(i$c, 1, 0) AS gc", // GROUPING(c)
- "CASE(i$b, 1, 0) AS gib", // GROUPING_ID(b)
- "CASE(i$c, 1, 0) AS gic", // GROUPING_ID(c)
- "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS gid") // GROUPING_ID(b, c)
- )
-
- util.verifySql(sqlQuery, aggregate)
- }
-
- @Test
- def testRollup(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
- "GROUPING(b) as gb, GROUPING(c) as gc, " +
- "GROUPING_ID(b) as gib, GROUPING_ID(c) as gic, " +
- "GROUPING_ID(b, c) as gid " + " FROM MyTable " +
- "GROUP BY ROLLUP (b, c)"
-
- val group1 = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "b, c"),
- term("select", "b", "c",
- "AVG(a) AS i$b")
- )
-
- val group2 = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "b"),
- term("select", "b",
- "AVG(a) AS c")
- )
-
- val group3 = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("select",
- "AVG(a) AS b")
- )
-
- val union1 = binaryNode(
- "DataSetUnion",
- group1, group2,
- term("union", "b", "c", "i$b", "i$c", "a")
- )
-
- val union2 = binaryNode(
- "DataSetUnion",
- union1, group3,
- term("union", "b", "c", "i$b", "i$c", "a")
- )
-
- val aggregate = unaryNode(
- "DataSetCalc",
- union2,
- term("select",
- "CASE(i$b, null, b) AS b",
- "CASE(i$c, null, c) AS c",
- "a",
- "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g", // GROUP_ID()
- "CASE(i$b, 1, 0) AS gb", // GROUPING(b)
- "CASE(i$c, 1, 0) AS gc", // GROUPING(c)
- "CASE(i$b, 1, 0) AS gib", // GROUPING_ID(b)
- "CASE(i$c, 1, 0) AS gic", // GROUPING_ID(c)
- "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS gid") // GROUPING_ID(b, c)
- )
-
- util.verifySql(sqlQuery, aggregate)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala
deleted file mode 100644
index a56bbed..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class QueryDecorrelationTest extends TableTestBase {
-
- @Test
- def testCorrelationScalarAggAndFilter(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
- util.addTable[(Int, String)]("dept", 'deptno, 'name)
-
- val sql = "SELECT e1.empno\n" +
- "FROM emp e1, dept d1 where e1.deptno = d1.deptno\n" +
- "and e1.deptno < 10 and d1.deptno < 15\n" +
- "and e1.salary > (select avg(salary) from emp e2 where e1.empno = e2.empno)"
-
- val expectedQuery = unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "empno", "salary", "deptno"),
- term("where", "<(deptno, 10)")
- ),
- unaryNode(
- "DataSetCalc",
- batchTableNode(1),
- term("select", "deptno"),
- term("where", "<(deptno, 15)")
- ),
- term("where", "=(deptno, deptno0)"),
- term("join", "empno", "salary", "deptno", "deptno0"),
- term("joinType", "InnerJoin")
- ),
- term("select", "empno", "salary")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "empno", "salary"),
- term("where", "IS NOT NULL(empno)")
- ),
- term("groupBy", "empno"),
- term("select", "empno", "AVG(salary) AS EXPR$0")
- ),
- term("where", "AND(=(empno, empno0), >(salary, EXPR$0))"),
- term("join", "empno", "salary", "empno0", "EXPR$0"),
- term("joinType", "InnerJoin")
- ),
- term("select", "empno")
- )
-
- util.verifySql(sql, expectedQuery)
- }
-
- @Test
- def testDecorrelateWithMultiAggregate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
- util.addTable[(Int, String)]("dept", 'deptno, 'name)
-
- val sql = "select sum(e1.empno) from emp e1, dept d1 " +
- "where e1.deptno = d1.deptno " +
- "and e1.salary > (" +
- " select avg(e2.salary) from emp e2 where e2.deptno = d1.deptno" +
- ")"
-
- val expectedQuery = unaryNode(
- "DataSetAggregate",
- binaryNode(
- "DataSetUnion",
- values(
- "DataSetValues",
- tuples(List(null)),
- term("values", "empno")
- ),
- unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "empno", "salary", "deptno")
- ),
- unaryNode(
- "DataSetCalc",
- batchTableNode(1),
- term("select", "deptno")
- ),
- term("where", "=(deptno, deptno0)"),
- term("join", "empno", "salary", "deptno", "deptno0"),
- term("joinType", "InnerJoin")
- ),
- term("select", "empno", "salary", "deptno0")
- ),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "salary", "deptno"),
- term("where", "IS NOT NULL(deptno)")
- ),
- term("groupBy", "deptno"),
- term("select", "deptno", "AVG(salary) AS EXPR$0")
- ),
- term("where", "AND(=(deptno0, deptno), >(salary, EXPR$0))"),
- term("join", "empno", "salary", "deptno0", "deptno", "EXPR$0"),
- term("joinType", "InnerJoin")
- ),
- term("select", "empno")
- ),
- term("union", "empno")
- ),
- term("select", "SUM(empno) AS EXPR$0")
- )
-
- util.verifySql(sql, expectedQuery)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsTest.scala
deleted file mode 100644
index ba0326a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsTest.scala
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class SetOperatorsTest extends TableTestBase {
-
- @Test
- def testMinusWithNestedTypes(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Long, (Int, String), Array[Boolean])]("MyTable", 'a, 'b, 'c)
-
- val expected = binaryNode(
- "DataSetMinus",
- batchTableNode(0),
- batchTableNode(0),
- term("minus", "a", "b", "c")
- )
-
- val result = t.minus(t)
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testExists(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Long, Int, String)]("A", 'a_long, 'a_int, 'a_string)
- util.addTable[(Long, Int, String)]("B", 'b_long, 'b_int, 'b_string)
-
- val expected = unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetJoin",
- batchTableNode(0),
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(1),
- term("select", "b_long AS b_long3", "true AS $f0"),
- term("where", "IS NOT NULL(b_long)")
- ),
- term("groupBy", "b_long3"),
- term("select", "b_long3", "MIN($f0) AS $f1")
- ),
- term("select", "b_long3")
- ),
- term("where", "=(a_long, b_long3)"),
- term("join", "a_long", "a_int", "a_string", "b_long3"),
- term("joinType", "InnerJoin")
- ),
- term("select", "a_int", "a_string")
- )
-
- util.verifySql(
- "SELECT a_int, a_string FROM A WHERE EXISTS(SELECT * FROM B WHERE a_long = b_long)",
- expected
- )
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/UserDefinedTableFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/UserDefinedTableFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/UserDefinedTableFunctionTest.scala
deleted file mode 100644
index e091da2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/UserDefinedTableFunctionTest.scala
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.{HierarchyTableFunction, PojoTableFunc, TableFunc2}
-import org.apache.flink.table.utils._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class UserDefinedTableFunctionTest extends TableTestBase {
-
- @Test
- def testCrossJoin(): Unit = {
- val util = batchTestUtil()
- val func1 = new TableFunc1
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func1", func1)
-
- val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c)) AS T(s)"
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "func1($cor0.c)"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery, expected)
-
- // test overloading
-
- val sqlQuery2 = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c, '$')) AS T(s)"
-
- val expected2 = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "func1($cor0.c, '$')"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery2, expected2)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val util = batchTestUtil()
- val func1 = new TableFunc1
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func1", func1)
-
- val sqlQuery = "SELECT c, s FROM MyTable LEFT JOIN LATERAL TABLE(func1(c)) AS T(s) ON TRUE"
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "func1($cor0.c)"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "LEFT")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testCustomType(): Unit = {
- val util = batchTestUtil()
- val func2 = new TableFunc2
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func2", func2)
-
- val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len)"
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "func2($cor0.c)"),
- term("function", func2.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
- "VARCHAR(2147483647) f0, INTEGER f1)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS name", "f1 AS len")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testHierarchyType(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = new HierarchyTableFunction
- util.addFunction("hierarchy", function)
-
- val sqlQuery = "SELECT c, T.* FROM MyTable, LATERAL TABLE(hierarchy(c)) AS T(name, adult, len)"
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "hierarchy($cor0.c)"),
- term("function", function.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
- " VARCHAR(2147483647) f0, BOOLEAN f1, INTEGER f2)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS name", "f1 AS adult", "f2 AS len")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testPojoType(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = new PojoTableFunc
- util.addFunction("pojo", function)
-
- val sqlQuery = "SELECT c, name, age FROM MyTable, LATERAL TABLE(pojo(c))"
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "pojo($cor0.c)"),
- term("function", function.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
- " INTEGER age, VARCHAR(2147483647) name)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "name", "age")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testFilter(): Unit = {
- val util = batchTestUtil()
- val func2 = new TableFunc2
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func2", func2)
-
- val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len) " +
- "WHERE len > 2"
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "func2($cor0.c)"),
- term("function", func2.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
- "VARCHAR(2147483647) f0, INTEGER f1)"),
- term("joinType", "INNER"),
- term("condition", ">($1, 2)")
- ),
- term("select", "c", "f0 AS name", "f1 AS len")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
-
- @Test
- def testScalarFunction(): Unit = {
- val util = batchTestUtil()
- val func1 = new TableFunc1
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func1", func1)
-
- val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(SUBSTRING(c, 2))) AS T(s)"
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", "func1(SUBSTRING($cor0.c, 2))"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala
deleted file mode 100644
index 64075ef..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import java.sql.Timestamp
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMerge
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.plan.logical._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class WindowAggregateTest extends TableTestBase {
-
- @Test
- def testNonPartitionedTumbleWindow(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB FROM T GROUP BY TUMBLE(ts, INTERVAL '2' HOUR)"
-
- val expected =
- unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "ts, a, b")
- ),
- term("window", TumblingGroupWindow('w$, 'ts, 7200000.millis)),
- term("select", "SUM(a) AS sumA, COUNT(b) AS cntB")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testPartitionedTumbleWindow(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT " +
- " TUMBLE_START(ts, INTERVAL '4' MINUTE), " +
- " TUMBLE_END(ts, INTERVAL '4' MINUTE), " +
- " c, " +
- " SUM(a) AS sumA, " +
- " MIN(b) AS minB " +
- "FROM T " +
- "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE), c"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "c"),
- term("window", TumblingGroupWindow('w$, 'ts, 240000.millis)),
- term("select", "c, SUM(a) AS sumA, MIN(b) AS minB, " +
- "start('w$) AS w$start, end('w$) AS w$end")
- ),
- term("select", "CAST(w$start) AS w$start, CAST(w$end) AS w$end, c, sumA, minB")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testTumbleWindowWithUdAgg() = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val weightedAvg = new WeightedAvgWithMerge
- util.tableEnv.registerFunction("weightedAvg", weightedAvg)
-
- val sql = "SELECT weightedAvg(b, a) AS wAvg " +
- "FROM T " +
- "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE)"
-
- val expected =
- unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "ts, b, a")
- ),
- term("window", TumblingGroupWindow('w$, 'ts, 240000.millis)),
- term("select", "weightedAvg(b, a) AS wAvg")
- )
-
- util.verifySql(sql, expected)
- }
-
- @Test
- def testNonPartitionedHopWindow(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM T " +
- "GROUP BY HOP(ts, INTERVAL '15' MINUTE, INTERVAL '90' MINUTE)"
-
- val expected =
- unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "ts, a, b")
- ),
- term("window",
- SlidingGroupWindow('w$, 'ts, 5400000.millis, 900000.millis)),
- term("select", "SUM(a) AS sumA, COUNT(b) AS cntB")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testPartitionedHopWindow(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Long, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
-
- val sqlQuery =
- "SELECT " +
- " c, " +
- " HOP_END(ts, INTERVAL '1' HOUR, INTERVAL '3' HOUR), " +
- " HOP_START(ts, INTERVAL '1' HOUR, INTERVAL '3' HOUR), " +
- " SUM(a) AS sumA, " +
- " AVG(b) AS avgB " +
- "FROM T " +
- "GROUP BY HOP(ts, INTERVAL '1' HOUR, INTERVAL '3' HOUR), d, c"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "c, d"),
- term("window",
- SlidingGroupWindow('w$, 'ts, 10800000.millis, 3600000.millis)),
- term("select", "c, d, SUM(a) AS sumA, AVG(b) AS avgB, " +
- "start('w$) AS w$start, end('w$) AS w$end")
- ),
- term("select", "c, CAST(w$end) AS w$end, CAST(w$start) AS w$start, sumA, avgB")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testNonPartitionedSessionWindow(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT COUNT(*) AS cnt FROM T GROUP BY SESSION(ts, INTERVAL '30' MINUTE)"
-
- val expected =
- unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "ts")
- ),
- term("window", SessionGroupWindow('w$, 'ts, 1800000.millis)),
- term("select", "COUNT(*) AS cnt")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testPartitionedSessionWindow(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Int, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
-
- val sqlQuery =
- "SELECT " +
- " c, d, " +
- " SESSION_START(ts, INTERVAL '12' HOUR), " +
- " SESSION_END(ts, INTERVAL '12' HOUR), " +
- " SUM(a) AS sumA, " +
- " MIN(b) AS minB " +
- "FROM T " +
- "GROUP BY SESSION(ts, INTERVAL '12' HOUR), c, d"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "c, d"),
- term("window", SessionGroupWindow('w$, 'ts, 43200000.millis)),
- term("select", "c, d, SUM(a) AS sumA, MIN(b) AS minB, " +
- "start('w$) AS w$start, end('w$) AS w$end")
- ),
- term("select", "c, d, CAST(w$start) AS w$start, CAST(w$end) AS w$end, sumA, minB")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testWindowEndOnly(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT " +
- " TUMBLE_END(ts, INTERVAL '4' MINUTE)" +
- "FROM T " +
- "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE), c"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "ts, c")
- ),
- term("groupBy", "c"),
- term("window", TumblingGroupWindow('w$, 'ts, 240000.millis)),
- term("select", "c, start('w$) AS w$start, end('w$) AS w$end")
- ),
- term("select", "CAST(w$end) AS w$end")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala
deleted file mode 100644
index 20d5970..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class AggregationsValidationTest extends TableTestBase {
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
-
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("T", 'a, 'b, 'c)
-
- util.addFunction("overAgg", new OverAgg0)
-
- val sqlQuery = "SELECT overAgg(b, a) FROM T"
- util.tableEnv.sql(sqlQuery)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala
deleted file mode 100644
index 7d2de19..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class CalcValidationTest extends TableTestBase{
-
- @Test(expected = classOf[ValidationException])
- def testInvalidFields(): Unit = {
-
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, foo FROM MyTable"
-
- util.tableEnv.sql(sqlQuery)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala
deleted file mode 100644
index f4c475b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.{TableException, ValidationException}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.types.Row
-import org.junit.Test
-
-class JoinValidationTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testJoinNonExistingKey(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE foo = e"
-
- util.tableEnv.sql(sqlQuery)
- }
-
- @Test(expected = classOf[TableException])
- def testJoinNonMatchingKeyTypes(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = g"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoinWithAmbiguousFields(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testJoinNoEqualityPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE d = f"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testCrossJoin(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, String)]("Table4", 'a1, 'b1, 'c1)
-
- val sqlQuery = "SELECT a, a1 FROM Table3 CROSS JOIN Table4"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testRightOuterJoinWithNonEquiJoinPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and a > d"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testLeftOuterJoinWithNonEquiJoinPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and a > d"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testFullOuterJoinWithNonEquiJoinPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and a > d"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testRightOuterJoinWithLocalPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and e > 3"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testLeftOuterJoinWithLocalPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and b > 3"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-
- @Test(expected = classOf[TableException])
- def testFullOuterJoinWithLocalPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and b > 3"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala
deleted file mode 100644
index 61cbfd8..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.types.Row
-import org.junit.Test
-
-class SortValidationTest extends TableTestBase {
-
- @Test(expected = classOf[TableException])
- def testLimitWithoutOrder(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT * FROM MyTable LIMIT 5"
-
- util.tableEnv.sql(sqlQuery).toDataSet[Row]
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala
deleted file mode 100644
index 20fdbba..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql.validation
-
-import java.sql.Timestamp
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableException, ValidationException}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class WindowAggregateValidationTest extends TableTestBase {
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
- util.addFunction("overAgg", new OverAgg0)
-
- val sqlQuery = "SELECT overAgg(b, a) FROM T GROUP BY TUMBLE(ts, INTERVAL '2' HOUR)"
-
- util.tableEnv.sql(sqlQuery)
- }
-
- @Test(expected = classOf[TableException])
- def testHopWindowNoOffset(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM T " +
- "GROUP BY HOP(ts, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- util.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testSessionWindowNoOffset(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM T " +
- "GROUP BY SESSION(ts, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- util.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testVariableWindowSize() = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sql = "SELECT COUNT(*) " +
- "FROM T " +
- "GROUP BY TUMBLE(ts, b * INTERVAL '1' MINUTE)"
- util.verifySql(sql, "n/a")
- }
-
- @Test(expected = classOf[ValidationException])
- def testTumbleWindowWithInvalidUdAggArgs() = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val weightedAvg = new WeightedAvgWithMerge
- util.tableEnv.registerFunction("weightedAvg", weightedAvg)
-
- val sql = "SELECT weightedAvg(c, a) AS wAvg " +
- "FROM T " +
- "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE)"
- util.verifySql(sql, "n/a")
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala
deleted file mode 100644
index 6ca607b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for testing aggregate plans.
- */
-class AggregationsTest extends TableTestBase {
-
- @Test
- def testGroupAggregateWithFilter(): Unit = {
-
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val resultTable = sourceTable.groupBy('a)
- .select('a, 'a.avg, 'b.sum, 'c.count)
- .where('a === 1)
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", "=(a, 1)")
- )
-
- val expected = unaryNode(
- "DataSetAggregate",
- calcNode,
- term("groupBy", "a"),
- term("select",
- "a",
- "AVG(a) AS TMP_0",
- "SUM(b) AS TMP_1",
- "COUNT(c) AS TMP_2")
- )
-
- util.verifyTable(resultTable,expected)
- }
-
- @Test
- def testAggregate(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
- val resultTable = sourceTable.select('a.avg,'b.sum,'c.count)
-
- val setValues = unaryNode(
- "DataSetValues",
- batchTableNode(0),
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val expected = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS TMP_0",
- "SUM(b) AS TMP_1",
- "COUNT(c) AS TMP_2")
- )
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testAggregateWithFilter(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val resultTable = sourceTable.select('a,'b,'c).where('a === 1)
- .select('a.avg,'b.sum,'c.count)
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- // ReduceExpressionsRule will add cast for Project node by force
- // if the input of the Project node has constant expression.
- term("select", "CAST(1) AS a", "b", "c"),
- term("where", "=(a, 1)")
- )
-
- val setValues = unaryNode(
- "DataSetValues",
- calcNode,
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
-
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val expected = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS TMP_0",
- "SUM(b) AS TMP_1",
- "COUNT(c) AS TMP_2")
- )
-
- util.verifyTable(resultTable, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala
deleted file mode 100644
index ece9acc..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.scala.createTypeInformation
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.table.CompositeFlatteningTest.{TestCaseClass, giveMeCaseClass}
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-
-class CompositeFlatteningTest extends TableTestBase {
-
- @Test
- def testMultipleFlatteningsTable(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
-
- val result = table.select('a.flatten(), 'c, 'b.flatten())
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "a._1 AS a$_1",
- "a._2 AS a$_2",
- "c",
- "b._1 AS b$_1",
- "b._2 AS b$_2"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testNestedFlattening(): Unit = {
- val util = batchTestUtil()
- val table = util
- .addTable[((((String, TestCaseClass), Boolean), String), String)]("MyTable", 'a, 'b)
-
- val result = table.select('a.flatten(), 'b.flatten())
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "a._1 AS a$_1",
- "a._2 AS a$_2",
- "b"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testScalarFunctionAccess(): Unit = {
- val util = batchTestUtil()
- val table = util
- .addTable[(String, Int)]("MyTable", 'a, 'b)
-
- val result = table.select(
- giveMeCaseClass().get("my"),
- giveMeCaseClass().get("clazz"),
- giveMeCaseClass().flatten())
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- s"${giveMeCaseClass.functionIdentifier}().my AS _c0",
- s"${giveMeCaseClass.functionIdentifier}().clazz AS _c1",
- s"${giveMeCaseClass.functionIdentifier}().my AS _c2",
- s"${giveMeCaseClass.functionIdentifier}().clazz AS _c3"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
-}
-
-object CompositeFlatteningTest {
-
- case class TestCaseClass(my: String, clazz: Int)
-
- object giveMeCaseClass extends ScalarFunction {
- def eval(): TestCaseClass = {
- TestCaseClass("hello", 42)
- }
-
- override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
- createTypeInformation[TestCaseClass]
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala
deleted file mode 100644
index 4a38741..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.test.util.MultipleProgramsTestBase
-import org.junit.Assert.assertEquals
-import org.junit._
-
-class ExplainTest
- extends MultipleProgramsTestBase(MultipleProgramsTestBase.TestExecutionMode.CLUSTER) {
-
- val testFilePath = ExplainTest.this.getClass.getResource("/").getFile
-
- @Test
- def testFilterWithoutExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements((1, "hello"))
- .toTable(tEnv, 'a, 'b)
- .filter("a % 2 = 0")
-
- val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testFilter0.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testFilterWithExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements((1, "hello"))
- .toTable(tEnv, 'a, 'b)
- .filter("a % 2 = 0")
-
- val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testFilter1.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testJoinWithoutExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
- val table = table1.join(table2).where("b = d").select("a, c")
-
- val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testJoin0.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testJoinWithExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
- val table = table1.join(table2).where("b = d").select("a, c")
-
- val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testJoin1.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testUnionWithoutExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table = table1.unionAll(table2)
-
- val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testUnion0.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testUnionWithExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table = table1.unionAll(table2)
-
- val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testUnion1.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala
deleted file mode 100644
index c35a454..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
[03/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala
new file mode 100644
index 0000000..15828eb
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala
@@ -0,0 +1,838 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.sql
+
+import org.apache.flink.api.common.time.Time
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.sql.TimeTestUtil.EventTimeSourceFunction
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit._
+
+import scala.collection.mutable
+
+class OverWindowITCase extends StreamingWithStateTestBase {
+
+ val data = List(
+ (1L, 1, "Hello"),
+ (2L, 2, "Hello"),
+ (3L, 3, "Hello"),
+ (4L, 4, "Hello"),
+ (5L, 5, "Hello"),
+ (6L, 6, "Hello"),
+ (7L, 7, "Hello World"),
+ (8L, 8, "Hello World"),
+ (20L, 20, "Hello World"))
+
+ @Test
+ def testProcTimeBoundedPartitionedRowsOver(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
+ tEnv.registerTable("MyTable", t)
+
+ val sqlQuery = "SELECT a, " +
+ " SUM(c) OVER (" +
+ " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW), " +
+ " MIN(c) OVER (" +
+ " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) " +
+ "FROM MyTable"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,0,0",
+ "2,1,1",
+ "2,3,1",
+ "3,3,3",
+ "3,7,3",
+ "3,12,3",
+ "4,6,6",
+ "4,13,6",
+ "4,21,6",
+ "4,30,6",
+ "5,10,10",
+ "5,21,10",
+ "5,33,10",
+ "5,46,10",
+ "5,60,10")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeBoundedNonPartitionedRowsOver(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
+ tEnv.registerTable("MyTable", t)
+
+ val sqlQuery = "SELECT a, " +
+ " SUM(c) OVER (" +
+ " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW), " +
+ " MIN(c) OVER (" +
+ " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) " +
+ "FROM MyTable"
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,0,0",
+ "2,1,0",
+ "2,3,0",
+ "3,6,0",
+ "3,10,0",
+ "3,15,0",
+ "4,21,0",
+ "4,28,0",
+ "4,36,0",
+ "4,45,0",
+ "5,55,0",
+ "5,66,1",
+ "5,77,2",
+ "5,88,3",
+ "5,99,4")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeUnboundedPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ // for sum aggregation ensure that every time the order of each element is consistent
+ env.setParallelism(1)
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
+ "sum(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) " +
+ "from T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello World,1,7", "Hello World,2,15", "Hello World,3,35",
+ "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeUnboundedPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT c, cnt1 from " +
+ "(SELECT " +
+ "c, " +
+ "count(a) " +
+ " OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
+ "as cnt1 from T1)"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello World,1", "Hello World,2", "Hello World,3",
+ "Hello,1", "Hello,2", "Hello,3", "Hello,4", "Hello,5", "Hello,6")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRangeOver(): Unit = {
+ val queryConfig =
+ new StreamQueryConfig().withIdleStateRetentionTime(Time.hours(2), Time.hours(3))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ // for sum aggregation ensure that every time the order of each element is consistent
+ env.setParallelism(1)
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding), " +
+ "sum(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) " +
+ "from T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row](queryConfig)
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello World,7,28", "Hello World,8,36", "Hello World,9,56",
+ "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "count(a) OVER (ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
+ "from T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("1", "2", "3", "4", "5", "6", "7", "8", "9")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRangeOver(): Unit = {
+ val data = Seq(
+ Left((1500L, (1L, 15, "Hello"))),
+ Left((1600L, (1L, 16, "Hello"))),
+ Left((1000L, (1L, 1, "Hello"))),
+ Left((2000L, (2L, 2, "Hello"))),
+ Right(1000L),
+ Left((2000L, (2L, 2, "Hello"))),
+ Left((2000L, (2L, 3, "Hello"))),
+ Left((3000L, (3L, 3, "Hello"))),
+ Right(2000L),
+ Left((4000L, (4L, 4, "Hello"))),
+ Right(3000L),
+ Left((5000L, (5L, 5, "Hello"))),
+ Right(5000L),
+ Left((6000L, (6L, 6, "Hello"))),
+ Left((6500L, (6L, 65, "Hello"))),
+ Right(7000L),
+ Left((9000L, (6L, 9, "Hello"))),
+ Left((9500L, (6L, 18, "Hello"))),
+ Left((9000L, (6L, 9, "Hello"))),
+ Right(10000L),
+ Left((10000L, (7L, 7, "Hello World"))),
+ Left((11000L, (7L, 17, "Hello World"))),
+ Left((11000L, (7L, 77, "Hello World"))),
+ Right(12000L),
+ Left((14000L, (7L, 18, "Hello World"))),
+ Right(14000L),
+ Left((15000L, (8L, 8, "Hello World"))),
+ Right(17000L),
+ Left((20000L, (20L, 20, "Hello World"))),
+ Right(19000L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ " c, b, " +
+ " COUNT(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
+ " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
+ " SUM(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
+ " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW)" +
+ " FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
+ "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
+ "Hello,3,4,9",
+ "Hello,4,2,7",
+ "Hello,5,2,9",
+ "Hello,6,2,11", "Hello,65,2,12",
+ "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
+ "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
+ "Hello World,8,2,15",
+ "Hello World,20,1,20")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRowsOver(): Unit = {
+ val data = Seq(
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((3L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Right(2L),
+ Left((3L, (3L, 3, "Hello"))),
+ Left((4L, (4L, 4, "Hello"))),
+ Left((5L, (5L, 5, "Hello"))),
+ Left((6L, (6L, 6, "Hello"))),
+ Left((20L, (20L, 20, "Hello World"))),
+ Right(6L),
+ Left((8L, (8L, 8, "Hello World"))),
+ Left((7L, (7L, 7, "Hello World"))),
+ Right(20L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ " c, a, " +
+ " COUNT(a) " +
+ " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), " +
+ " SUM(a) " +
+ " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
+ "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
+ "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
+ "Hello,6,3,15",
+ "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
+ "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRangeOver(): Unit = {
+ val data = Seq(
+ Left((1500L, (1L, 15, "Hello"))),
+ Left((1600L, (1L, 16, "Hello"))),
+ Left((1000L, (1L, 1, "Hello"))),
+ Left((2000L, (2L, 2, "Hello"))),
+ Right(1000L),
+ Left((2000L, (2L, 2, "Hello"))),
+ Left((2000L, (2L, 3, "Hello"))),
+ Left((3000L, (3L, 3, "Hello"))),
+ Right(2000L),
+ Left((4000L, (4L, 4, "Hello"))),
+ Right(3000L),
+ Left((5000L, (5L, 5, "Hello"))),
+ Right(5000L),
+ Left((6000L, (6L, 6, "Hello"))),
+ Left((6500L, (6L, 65, "Hello"))),
+ Right(7000L),
+ Left((9000L, (6L, 9, "Hello"))),
+ Left((9500L, (6L, 18, "Hello"))),
+ Left((9000L, (6L, 9, "Hello"))),
+ Right(10000L),
+ Left((10000L, (7L, 7, "Hello World"))),
+ Left((11000L, (7L, 17, "Hello World"))),
+ Left((11000L, (7L, 77, "Hello World"))),
+ Right(12000L),
+ Left((14000L, (7L, 18, "Hello World"))),
+ Right(14000L),
+ Left((15000L, (8L, 8, "Hello World"))),
+ Right(17000L),
+ Left((20000L, (20L, 20, "Hello World"))),
+ Right(19000L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ " c, b, " +
+ " COUNT(a) " +
+ " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
+ " SUM(a) " +
+ " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW) " +
+ " FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
+ "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
+ "Hello,3,4,9",
+ "Hello,4,2,7",
+ "Hello,5,2,9",
+ "Hello,6,2,11", "Hello,65,2,12",
+ "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
+ "Hello World,7,4,25", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
+ "Hello World,8,2,15",
+ "Hello World,20,1,20")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRowsOver(): Unit = {
+
+ val data = Seq(
+ Left((2L, (2L, 2, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((20L, (20L, 20, "Hello World"))), // early row
+ Right(3L),
+ Left((2L, (2L, 2, "Hello"))), // late row
+ Left((3L, (3L, 3, "Hello"))),
+ Left((4L, (4L, 4, "Hello"))),
+ Left((5L, (5L, 5, "Hello"))),
+ Left((6L, (6L, 6, "Hello"))),
+ Left((7L, (7L, 7, "Hello World"))),
+ Right(7L),
+ Left((9L, (9L, 9, "Hello World"))),
+ Left((8L, (8L, 8, "Hello World"))),
+ Left((8L, (8L, 8, "Hello World"))),
+ Right(20L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "c, a, " +
+ " COUNT(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW), " +
+ " SUM(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW) " +
+ "FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
+ "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
+ "Hello,3,3,7",
+ "Hello,4,3,9", "Hello,5,3,12",
+ "Hello,6,3,15", "Hello World,7,3,18",
+ "Hello World,8,3,21", "Hello World,8,3,23",
+ "Hello World,9,3,25",
+ "Hello World,20,3,37")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT a, b, c, " +
+ " SUM(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " COUNT(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " AVG(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MAX(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MIN(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (1, 1L, "Hello")),
+ Left(14000002L, (1, 2L, "Hello")),
+ Left(14000002L, (1, 3L, "Hello world")),
+ Left(14000003L, (2, 2L, "Hello world")),
+ Left(14000003L, (2, 3L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 4L, "Hello world")),
+ Left(14000022L, (1, 5L, "Hello world")),
+ Left(14000022L, (1, 6L, "Hello world")),
+ Left(14000022L, (1, 7L, "Hello world")),
+ Left(14000023L, (2, 4L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000030L))
+
+ val t1 = env
+ .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,1,Hello,6,3,2,3,1",
+ "1,2,Hello,6,3,2,3,1",
+ "1,3,Hello world,6,3,2,3,1",
+ "1,1,Hi,7,4,1,3,1",
+ "2,1,Hello,1,1,1,1,1",
+ "2,2,Hello world,6,3,2,3,1",
+ "2,3,Hello world,6,3,2,3,1",
+ "1,4,Hello world,11,5,2,4,1",
+ "1,5,Hello world,29,8,3,7,1",
+ "1,6,Hello world,29,8,3,7,1",
+ "1,7,Hello world,29,8,3,7,1",
+ "2,4,Hello world,15,5,3,5,1",
+ "2,5,Hello world,15,5,3,5,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val sqlQuery = "SELECT a, b, c, " +
+ "SUM(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "count(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "avg(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "max(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "min(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row) " +
+ "from T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (3, 1L, "Hello")),
+ Left(14000003L, (1, 2L, "Hello")),
+ Left(14000004L, (1, 3L, "Hello world")),
+ Left(14000007L, (3, 2L, "Hello world")),
+ Left(14000008L, (2, 2L, "Hello world")),
+ Right(14000010L),
+ Left(14000012L, (1, 5L, "Hello world")),
+ Left(14000021L, (1, 6L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000020L),
+ Left(14000024L, (3, 5L, "Hello world")),
+ Left(14000026L, (1, 7L, "Hello world")),
+ Left(14000025L, (1, 8L, "Hello world")),
+ Left(14000022L, (1, 9L, "Hello world")),
+ Right(14000030L))
+
+ val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,2,Hello,2,1,2,2,2",
+ "1,3,Hello world,5,2,2,3,2",
+ "1,1,Hi,6,3,2,3,1",
+ "2,1,Hello,1,1,1,1,1",
+ "2,2,Hello world,3,2,1,2,1",
+ "3,1,Hello,1,1,1,1,1",
+ "3,2,Hello world,3,2,1,2,1",
+ "1,5,Hello world,11,4,2,5,1",
+ "1,6,Hello world,17,5,3,6,1",
+ "1,9,Hello world,26,6,4,9,1",
+ "1,8,Hello world,34,7,4,9,1",
+ "1,7,Hello world,41,8,5,9,1",
+ "2,5,Hello world,8,3,2,5,1",
+ "3,5,Hello world,8,3,2,5,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedNonPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT a, b, c, " +
+ " SUM(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " COUNT(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " AVG(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MAX(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MIN(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (1, 1L, "Hello")),
+ Left(14000002L, (1, 2L, "Hello")),
+ Left(14000002L, (1, 3L, "Hello world")),
+ Left(14000003L, (2, 2L, "Hello world")),
+ Left(14000003L, (2, 3L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 4L, "Hello world")),
+ Left(14000022L, (1, 5L, "Hello world")),
+ Left(14000022L, (1, 6L, "Hello world")),
+ Left(14000022L, (1, 7L, "Hello world")),
+ Left(14000023L, (2, 4L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000030L))
+
+ val t1 = env
+ .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "2,1,Hello,1,1,1,1,1",
+ "1,1,Hello,7,4,1,3,1",
+ "1,2,Hello,7,4,1,3,1",
+ "1,3,Hello world,7,4,1,3,1",
+ "2,2,Hello world,12,6,2,3,1",
+ "2,3,Hello world,12,6,2,3,1",
+ "1,1,Hi,13,7,1,3,1",
+ "1,4,Hello world,17,8,2,4,1",
+ "1,5,Hello world,35,11,3,7,1",
+ "1,6,Hello world,35,11,3,7,1",
+ "1,7,Hello world,35,11,3,7,1",
+ "2,4,Hello world,44,13,3,7,1",
+ "2,5,Hello world,44,13,3,7,1")
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedNonPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.clear
+ env.setParallelism(1)
+
+ val sqlQuery = "SELECT a, b, c, " +
+ " SUM(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " COUNT(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " AVG(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MAX(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MIN(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 2L, "Hello")),
+ Left(14000002L, (3, 5L, "Hello")),
+ Left(14000003L, (1, 3L, "Hello")),
+ Left(14000004L, (3, 7L, "Hello world")),
+ Left(14000007L, (4, 9L, "Hello world")),
+ Left(14000008L, (5, 8L, "Hello world")),
+ Right(14000010L),
+ // this element will be discard because it is late
+ Left(14000008L, (6, 8L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (6, 8L, "Hello world")),
+ Right(14000030L)
+ )
+
+ val t1 = env
+ .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "2,2,Hello,2,1,2,2,2",
+ "3,5,Hello,7,2,3,5,2",
+ "1,3,Hello,10,3,3,5,2",
+ "3,7,Hello world,17,4,4,7,2",
+ "1,1,Hi,18,5,3,7,1",
+ "4,9,Hello world,27,6,4,9,1",
+ "5,8,Hello world,35,7,5,9,1",
+ "6,8,Hello world,43,8,5,9,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test sliding event-time unbounded window with partition by **/
+ @Test
+ def testRowTimeUnBoundedPartitionedRowsOver2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.clear
+ env.setParallelism(1)
+
+ val sqlQuery = "SELECT a, b, c, " +
+ "SUM(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "count(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "avg(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "max(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "min(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row) " +
+ "from T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (3, 1L, "Hello")),
+ Left(14000003L, (1, 2L, "Hello")),
+ Left(14000004L, (1, 3L, "Hello world")),
+ Left(14000007L, (3, 2L, "Hello world")),
+ Left(14000008L, (2, 2L, "Hello world")),
+ Right(14000010L),
+ // the next 3 elements are late
+ Left(14000008L, (1, 4L, "Hello world")),
+ Left(14000008L, (2, 3L, "Hello world")),
+ Left(14000008L, (3, 3L, "Hello world")),
+ Left(14000012L, (1, 5L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 6L, "Hello world")),
+ // the next 3 elements are late
+ Left(14000019L, (1, 6L, "Hello world")),
+ Left(14000018L, (2, 4L, "Hello world")),
+ Left(14000018L, (3, 4L, "Hello world")),
+ Left(14000022L, (2, 5L, "Hello world")),
+ Left(14000022L, (3, 5L, "Hello world")),
+ Left(14000024L, (1, 7L, "Hello world")),
+ Left(14000023L, (1, 8L, "Hello world")),
+ Left(14000021L, (1, 9L, "Hello world")),
+ Right(14000030L)
+ )
+
+ val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,2,Hello,2,1,2,2,2",
+ "1,3,Hello world,5,2,2,3,2",
+ "1,1,Hi,6,3,2,3,1",
+ "2,1,Hello,1,1,1,1,1",
+ "2,2,Hello world,3,2,1,2,1",
+ "3,1,Hello,1,1,1,1,1",
+ "3,2,Hello world,3,2,1,2,1",
+ "1,5,Hello world,11,4,2,5,1",
+ "1,6,Hello world,17,5,3,6,1",
+ "1,9,Hello world,26,6,4,9,1",
+ "1,8,Hello world,34,7,4,9,1",
+ "1,7,Hello world,41,8,5,9,1",
+ "2,5,Hello world,8,3,2,5,1",
+ "3,5,Hello world,8,3,2,5,1"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala
new file mode 100644
index 0000000..ec719d2
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala
@@ -0,0 +1,319 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.sql
+
+import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit._
+
+class SqlITCase extends StreamingWithStateTestBase {
+
+ /** test row stream registered table **/
+ @Test
+ def testRowRegister(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM MyTableRow WHERE c < 3"
+
+ val data = List(
+ Row.of("Hello", "Worlds", Int.box(1)),
+ Row.of("Hello", "Hiden", Int.box(5)),
+ Row.of("Hello again", "Worlds", Int.box(2)))
+
+ implicit val tpe: TypeInformation[Row] = new RowTypeInfo(
+ BasicTypeInfo.STRING_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO,
+ BasicTypeInfo.INT_TYPE_INFO) // tpe is automatically
+
+ val ds = env.fromCollection(data)
+
+ val t = ds.toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTableRow", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("Hello,Worlds,1","Hello again,Worlds,2")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test unbounded groupBy (without window) **/
+ @Test
+ def testUnboundedGroupBy(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT b, COUNT(a) FROM MyTable GROUP BY b"
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toRetractStream[Row]
+ result.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = List("1,1", "2,2", "3,3", "4,4", "5,5", "6,6")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ /** test selection **/
+ @Test
+ def testSelectExpressionFromTable(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT a * 2, b - 1 FROM MyTable"
+
+ val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("2,0", "4,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test filtering with registered table **/
+ @Test
+ def testSimpleFilter(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE a = 3"
+
+ val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test filtering with registered datastream **/
+ @Test
+ def testDatastreamFilter(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE _1 = 3"
+
+ val t = StreamTestData.getSmall3TupleDataStream(env)
+ tEnv.registerDataStream("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test union with registered tables **/
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM T1 " +
+ "UNION ALL " +
+ "SELECT * FROM T2"
+
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T1", t1)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T2", t2)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,1,Hi", "1,1,Hi",
+ "2,2,Hello", "2,2,Hello",
+ "3,2,Hello world", "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test union with filter **/
+ @Test
+ def testUnionWithFilter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM T1 WHERE a = 3 " +
+ "UNION ALL " +
+ "SELECT * FROM T2 WHERE a = 2"
+
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T1", t1)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T2", t2)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test union of a table and a datastream **/
+ @Test
+ def testUnionTableWithDataSet(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT c FROM T1 WHERE a = 3 " +
+ "UNION ALL " +
+ "SELECT c FROM T2 WHERE a = 2"
+
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T1", t1)
+ val t2 = StreamTestData.get3TupleDataStream(env)
+ tEnv.registerDataStream("T2", t2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("Hello", "Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnnestPrimitiveArrayFromTable(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val data = List(
+ (1, Array(12, 45), Array(Array(12, 45))),
+ (2, Array(41, 5), Array(Array(18), Array(87))),
+ (3, Array(18, 42), Array(Array(1), Array(45)))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, b, s FROM T, UNNEST(T.b) AS A (s)"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,[12, 45],12",
+ "1,[12, 45],45",
+ "2,[41, 5],41",
+ "2,[41, 5],5",
+ "3,[18, 42],18",
+ "3,[18, 42],42"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnnestArrayOfArrayFromTable(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val data = List(
+ (1, Array(12, 45), Array(Array(12, 45))),
+ (2, Array(41, 5), Array(Array(18), Array(87))),
+ (3, Array(18, 42), Array(Array(1), Array(45)))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) AS A (s)"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,[12, 45]",
+ "2,[18]",
+ "2,[87]",
+ "3,[1]",
+ "3,[45]")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnnestObjectArrayFromTableWithFilter(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val data = List(
+ (1, Array((12, "45.6"), (12, "45.612"))),
+ (2, Array((13, "41.6"), (14, "45.2136"))),
+ (3, Array((18, "42.6")))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataStream("T", stream, 'a, 'b)
+
+ val sqlQuery = "SELECT a, b, s, t FROM T, UNNEST(T.b) AS A (s, t) WHERE s > 13"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "2,[(13,41.6), (14,45.2136)],14,45.2136",
+ "3,[(18,42.6)],18,42.6")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala
new file mode 100644
index 0000000..31e7c5a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.utils.CommonTestData
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class TableSourceITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testCsvTableSource(): Unit = {
+
+ val csvTable = CommonTestData.getCsvTableSource
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ tEnv.registerTableSource("persons", csvTable)
+
+ tEnv.sql(
+ "SELECT id, `first`, `last`, score FROM persons WHERE id < 4 ")
+ .toAppendStream[Row]
+ .addSink(new StreamITCase.StringSink[Row])
+
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,Mike,Smith,12.3",
+ "2,Bob,Taylor,45.6",
+ "3,Sam,Miller,7.89")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala
new file mode 100644
index 0000000..2e8f206
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.expressions.utils.{RichFunc1, RichFunc2}
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.utils.UserDefinedFunctionTestUtils
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class CalcITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testSimpleSelectAll(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1, '_2, '_3)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hi",
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSelectFirst(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("1", "2", "3")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSimpleSelectWithNaming(): Unit = {
+
+ // verify ProjectMergeRule.
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv)
+ .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
+ .select('a, 'b)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1", "2,2", "3,2", "4,3", "5,3", "6,3", "7,4",
+ "8,4", "9,4", "10,4", "11,5", "12,5", "13,5", "14,5", "15,5",
+ "16,6", "17,6", "18,6", "19,6", "20,6", "21,6")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSimpleSelectAllWithAs(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a, 'b, 'c)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hi",
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSimpleFilter(): Unit = {
+ /*
+ * Test simple filter
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter('a === 3)
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+ /*
+ * Test all-rejecting filter
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(false) )
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ assertEquals(true, StreamITCase.testResults.isEmpty)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+ /*
+ * Test all-passing filter
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(true) )
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hi",
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testFilterOnIntegerTupleField(): Unit = {
+ /*
+ * Test filter on Integer tuple field.
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 === 0 )
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "2,2,Hello", "4,3,Hello world, how are you?",
+ "6,3,Luke Skywalker", "8,4,Comment#2", "10,4,Comment#4",
+ "12,5,Comment#6", "14,5,Comment#8", "16,6,Comment#10",
+ "18,6,Comment#12", "20,6,Comment#14")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testNotEquals(): Unit = {
+ /*
+ * Test filter on Integer tuple field.
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 !== 0)
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+ val expected = mutable.MutableList(
+ "1,1,Hi", "3,2,Hello world",
+ "5,3,I am fine.", "7,4,Comment#1", "9,4,Comment#3",
+ "11,5,Comment#5", "13,5,Comment#7", "15,5,Comment#9",
+ "17,6,Comment#11", "19,6,Comment#13", "21,6,Comment#15")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedFunctionWithParameter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
+
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.get3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .where("RichFunc2(c)='ABC#Hello'")
+ .select('c)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Hello")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testMultipleUserDefinedFunctions(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc1", new RichFunc1)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
+
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.get3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .where("RichFunc2(c)='Abc#Hello' || RichFunc1(a)=3 && b=2")
+ .select('c)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Hello", "Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala
new file mode 100644
index 0000000..8df14e8
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import org.apache.flink.api.common.time.Time
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.datastream.StreamITCase.RetractingSink
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
+import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+import scala.collection.mutable
+
+/**
+ * Tests of groupby (without window) aggregations
+ */
+class GroupAggregationsITCase extends StreamingWithStateTestBase {
+ private val queryConfig = new StreamQueryConfig()
+ queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
+
+
+ @Test
+ def testDistinct(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('b).distinct()
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = mutable.MutableList("1", "2", "3", "4", "5", "6")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testDistinctAfterAggregate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .groupBy('e).select('e, 'a.count).distinct()
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = mutable.MutableList("1,5", "2,7", "3,3")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testNonKeyedGroupAggregate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a.sum, 'b.sum)
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = List("231,91")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testGroupAggregate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('b, 'a.sum)
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = List("1,1", "2,5", "3,15", "4,34", "5,65", "6,111")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testDoubleGroupAggregation(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('a.count as 'cnt, 'b)
+ .groupBy('cnt)
+ .select('cnt, 'b.count as 'freq)
+
+ val results = t.toRetractStream[Row](queryConfig)
+
+ results.addSink(new RetractingSink)
+ env.execute()
+ val expected = List("1,1", "2,1", "3,1", "4,1", "5,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testGroupAggregateWithExpression(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .groupBy('e, 'b % 3)
+ .select('c.min, 'e, 'a.avg, 'd.count)
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new RetractingSink)
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "0,1,1,1", "7,1,4,2", "2,1,3,2",
+ "3,2,3,3", "1,2,3,3", "14,2,5,1",
+ "12,3,5,1", "5,3,4,2")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala
new file mode 100644
index 0000000..1af85d9
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala
@@ -0,0 +1,446 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.common.time.Time
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.runtime.datastream.table.GroupWindowAggregationsITCase._
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+/**
+ * We only test some aggregations until better testing of constructed DataStream
+ * programs is possible.
+ */
+class GroupWindowAggregationsITCase extends StreamingMultipleProgramsTestBase {
+ private val queryConfig = new StreamQueryConfig()
+ queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
+
+ val data = List(
+ (1L, 1, "Hi"),
+ (2L, 2, "Hello"),
+ (4L, 2, "Hello"),
+ (8L, 3, "Hello world"),
+ (16L, 3, "Hello world"))
+
+ val data2 = List(
+ (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
+ (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
+ (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
+ (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
+ (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
+ (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
+ (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
+
+ @Test
+ def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
+
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, countFun('int), 'int.avg,
+ weightAvgFun('long, 'int), weightAvgFun('int, 'int))
+
+ val results = windowedTable.toAppendStream[Row](queryConfig)
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("Hello world,1,3,8,3", "Hello world,2,3,12,3", "Hello,1,2,2,2",
+ "Hello,2,2,3,2", "Hi,1,1,1,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindowOverTime(): Unit = {
+ //To verify the "merge" functionality, we create this test with the following characteristics:
+ // 1. set the Parallelism to 1, and have the test data out of order
+ // 2. create a waterMark with 10ms offset to delay the window emission by 10ms
+ val sessionWindowTestdata = List(
+ (1L, 1, "Hello"),
+ (2L, 2, "Hello"),
+ (8L, 8, "Hello"),
+ (9L, 9, "Hello World"),
+ (4L, 4, "Hello"),
+ (16L, 16, "Hello"))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvgWithMerge
+
+ val stream = env
+ .fromCollection(sessionWindowTestdata)
+ .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset[(Long, Int, String)](10L))
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Session withGap 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, countFun('int), 'int.avg,
+ weightAvgFun('long, 'int), weightAvgFun('int, 'int))
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("Hello World,1,9,9,9", "Hello,1,16,16,16", "Hello,4,3,5,5")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w)
+ .select(countFun('string), 'int.avg,
+ weightAvgFun('long, 'int), weightAvgFun('int, 'int))
+
+ val results = windowedTable.toAppendStream[Row](queryConfig)
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("2,1,1,1", "2,2,6,2")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeTumblingWindow(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset[(Long, Int, String)](0L))
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, countFun('string), 'int.avg, weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int), 'int.min, 'int.max, 'int.sum, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hello world,1,3,8,3,3,3,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01",
+ "Hello world,1,3,16,3,3,3,3,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02",
+ "Hello,2,2,3,2,2,2,4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hi,1,1,1,1,1,1,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testGroupWindowWithoutKeyInProjection(): Unit = {
+ val data = List(
+ (1L, 1, "Hi", 1, 1),
+ (2L, 2, "Hello", 2, 2),
+ (4L, 2, "Hello", 2, 2),
+ (8L, 3, "Hello world", 3, 3),
+ (16L, 3, "Hello world", 3, 3))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'long, 'int, 'string, 'int2, 'int3, 'proctime.proctime)
+
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'int2, 'int3, 'string)
+ .select(weightAvgFun('long, 'int))
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq("12", "8", "2", "3", "1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+
+
+ // ----------------------------------------------------------------------------------------------
+ // Sliding windows
+ // ----------------------------------------------------------------------------------------------
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 2.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
+ "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
+ "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019",
+ "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
+ "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003",
+ "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011",
+ "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007",
+ "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
+ "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 10.milli every 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
+ "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
+ "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
+ "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02",
+ "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025",
+ "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
+ "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
+ "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
+ "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 4.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
+ "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
+ "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
+ "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataSet variant
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 3.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testEventTimeGroupWindowWithoutExplicitTimeField(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data2)
+ .assignTimestampsAndWatermarks(
+ new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
+ .map(t => (t._2, t._6))
+ val table = stream.toTable(tEnv, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 3.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+ val expected = Seq(
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
+
+object GroupWindowAggregationsITCase {
+
+ class TimestampAndWatermarkWithOffset[T <: Product](
+ offset: Long) extends AssignerWithPunctuatedWatermarks[T] {
+
+ override def checkAndGetNextWatermark(
+ lastElement: T,
+ extractedTimestamp: Long): Watermark = {
+ new Watermark(extractedTimestamp - offset)
+ }
+
+ override def extractTimestamp(
+ element: T,
+ previousElementTimestamp: Long): Long = {
+ element.productElement(0).asInstanceOf[Long]
+ }
+ }
+
+}
[08/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala
new file mode 100644
index 0000000..d2fddca
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.junit.Test
+
+class UnsupportedOpsValidationTest extends StreamingMultipleProgramsTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testSort(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).orderBy('_1.desc)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoin(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.join(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.union(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testIntersect(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.intersect(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testIntersectAll(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.intersectAll(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMinus(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.minus(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMinusAll(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.minusAll(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testLimit(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.limit(0,5)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala
new file mode 100644
index 0000000..218cc89
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils._
+import org.apache.flink.table.utils._
+import org.junit.Assert.{assertTrue, fail}
+import org.junit.Test
+
+class UserDefinedTableFunctionValidationTest extends TableTestBase {
+
+ @Test
+ def testRegisterFunctionException(): Unit ={
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('a, 'b, 'c)
+
+ // check scala object is forbidden
+ expectExceptionThrown(
+ util.tableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
+ expectExceptionThrown(
+ util.javaTableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
+
+ expectExceptionThrown(t.join(ObjectTableFunction('a, 1)), "Scala object")
+ }
+
+ @Test
+ def testInvalidTableFunctions(): Unit = {
+ val util = streamTestUtil()
+
+ val func1 = new TableFunc1
+ util.javaTableEnv.registerFunction("func1", func1)
+
+ // table function call select
+ expectExceptionThrown(
+ func1('c).select("f0"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call select
+ expectExceptionThrown(
+ func1('c).select('f0),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call writeToSink
+ expectExceptionThrown(
+ func1('c).writeToSink(null),
+ "Cannot translate a query with an unbounded table function call."
+ )
+
+ // table function call distinct
+ expectExceptionThrown(
+ func1('c).distinct(),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call filter
+ expectExceptionThrown(
+ func1('c).filter('f0 === "?"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call filter
+ expectExceptionThrown(
+ func1('c).filter("f0 = '?'"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call limit
+ expectExceptionThrown(
+ func1('c).orderBy('f0).limit(3),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call limit
+ expectExceptionThrown(
+ func1('c).orderBy('f0).limit(0, 3),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call orderBy
+ expectExceptionThrown(
+ func1('c).orderBy("f0"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call orderBy
+ expectExceptionThrown(
+ func1('c).orderBy('f0),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call where
+ expectExceptionThrown(
+ func1('c).where("f0 = '?'"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call where
+ expectExceptionThrown(
+ func1('c).where('f0 === "?"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ }
+
+ @Test
+ def testInvalidTableFunction(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ //=================== check scala object is forbidden =====================
+ // Scala table environment register
+ expectExceptionThrown(util.addFunction("udtf", ObjectTableFunction), "Scala object")
+ // Java table environment register
+ expectExceptionThrown(
+ util.tableEnv.registerFunction("udtf", ObjectTableFunction), "Scala object")
+ // Scala Table API directly call
+ expectExceptionThrown(t.join(ObjectTableFunction('a, 1)), "Scala object")
+
+
+ //============ throw exception when table function is not registered =========
+ // Java Table API call
+ expectExceptionThrown(
+ t.join(new Table(util.tableEnv, "nonexist(a)")
+ ), "Undefined function: NONEXIST")
+ // SQL API call
+ expectExceptionThrown(
+ util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(nonexist(a))"),
+ "No match found for function signature nonexist(<NUMERIC>)")
+
+
+ //========= throw exception when the called function is a scalar function ====
+ util.tableEnv.registerFunction("func0", Func0)
+
+ // Java Table API call
+ expectExceptionThrown(
+ t.join(new Table(util.tableEnv, "func0(a)")),
+ "only accept String that define table function",
+ classOf[TableException])
+ // SQL API call
+ // NOTE: it doesn't throw an exception but an AssertionError, maybe a Calcite bug
+ expectExceptionThrown(
+ util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func0(a))"),
+ null,
+ classOf[AssertionError])
+
+ //========== throw exception when the parameters is not correct ===============
+ // Java Table API call
+ util.addFunction("func2", new TableFunc2)
+ expectExceptionThrown(
+ t.join(new Table(util.tableEnv, "func2(c, c)")),
+ "Given parameters of function 'FUNC2' do not match any signature")
+ // SQL API call
+ expectExceptionThrown(
+ util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func2(c, c))"),
+ "No match found for function signature func2(<CHARACTER>, <CHARACTER>)")
+ }
+
+ // ----------------------------------------------------------------------------------------------
+
+ private def expectExceptionThrown(
+ function: => Unit,
+ keywords: String,
+ clazz: Class[_ <: Throwable] = classOf[ValidationException])
+ : Unit = {
+ try {
+ function
+ fail(s"Expected a $clazz, but no exception is thrown.")
+ } catch {
+ case e if e.getClass == clazz =>
+ if (keywords != null) {
+ assertTrue(
+ s"The exception message '${e.getMessage}' doesn't contain keyword '$keywords'",
+ e.getMessage.contains(keywords))
+ }
+ case e: Throwable => fail(s"Expected throw ${clazz.getSimpleName}, but is $e.")
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamITCase.scala
deleted file mode 100644
index 4c6e6f0..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamITCase.scala
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.utils
-
-import java.util.Collections
-
-import org.apache.flink.types.Row
-import org.junit.Assert._
-
-import scala.collection.mutable
-import org.apache.flink.streaming.api.functions.sink.RichSinkFunction
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable.ArrayBuffer
-
-object StreamITCase {
-
- var testResults: mutable.MutableList[String] = mutable.MutableList.empty[String]
- var retractedResults: ArrayBuffer[String] = mutable.ArrayBuffer.empty[String]
-
- def clear = {
- StreamITCase.testResults.clear()
- StreamITCase.retractedResults.clear()
- }
-
- def compareWithList(expected: java.util.List[String]): Unit = {
- Collections.sort(expected)
- assertEquals(expected.asScala, StreamITCase.testResults.sorted)
- }
-
- final class StringSink[T] extends RichSinkFunction[T]() {
- def invoke(value: T) {
- testResults.synchronized {
- testResults += value.toString
- }
- }
- }
-
- final class RetractMessagesSink extends RichSinkFunction[(Boolean, Row)]() {
- def invoke(v: (Boolean, Row)) {
- testResults.synchronized {
- testResults += (if (v._1) "+" else "-") + v._2
- }
- }
- }
-
- final class RetractingSink() extends RichSinkFunction[(Boolean, Row)] {
- def invoke(v: (Boolean, Row)) {
- retractedResults.synchronized {
- val value = v._2.toString
- if (v._1) {
- retractedResults += value
- } else {
- val idx = retractedResults.indexOf(value)
- if (idx >= 0) {
- retractedResults.remove(idx)
- } else {
- throw new RuntimeException("Tried to retract a value that wasn't added first. " +
- "This is probably an incorrectly implemented test. " +
- "Try to set the parallelism of the sink to 1.")
- }
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamingWithStateTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamingWithStateTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamingWithStateTestBase.scala
deleted file mode 100644
index 5f3f6ca..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamingWithStateTestBase.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.utils
-
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.contrib.streaming.state.RocksDBStateBackend
-
-import org.junit.rules.TemporaryFolder
-import org.junit.Rule
-
-class StreamingWithStateTestBase extends StreamingMultipleProgramsTestBase {
-
- val _tempFolder = new TemporaryFolder
-
- @Rule
- def tempFolder: TemporaryFolder = _tempFolder
-
- def getStateBackend: RocksDBStateBackend = {
- val dbPath = tempFolder.newFolder().getAbsolutePath
- val checkpointPath = tempFolder.newFolder().toURI.toString
- val backend = new RocksDBStateBackend(checkpointPath)
- backend.setDbStoragePath(dbPath)
- backend
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala
new file mode 100644
index 0000000..af8aff0
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableEnvironmentValidationTest extends TableTestBase {
+ def testInvalidTimeAttributes(): Unit = {
+ val util = streamTestUtil()
+ // table definition makes no sense
+ util.addTable[(Long, Int, String, Int, Long)]('a.rowtime.rowtime, 'b, 'c, 'd, 'e)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testInvalidProctimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ // cannot replace an attribute with proctime
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b.proctime, 'c, 'd, 'e)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeAttributeReplaceFieldOfInvalidType(): Unit = {
+ val util = streamTestUtil()
+ // cannot replace a non-time attribute with rowtime
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c.rowtime, 'd, 'e)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeAndInvalidProctimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'pt.proctime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testOnlyOneRowtimeAttribute1(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a.rowtime, 'b, 'c, 'd, 'e, 'rt.rowtime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testOnlyOneProctimeAttribute1(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt1.proctime, 'pt2.proctime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeAttributeUsedName(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'a.rowtime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testProctimeAttributeUsedName(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'b.proctime)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala
new file mode 100644
index 0000000..e275d75
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.validation
+
+import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
+import org.apache.flink.table.api.{TableException, TableSchema}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableSchemaValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testInvalidSchema() {
+ val fieldNames = Array("a", "b", "c")
+ val typeInfos: Array[TypeInformation[_]] = Array(
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO)
+ new TableSchema(fieldNames, typeInfos)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala
new file mode 100644
index 0000000..0780b25
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala
@@ -0,0 +1,402 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.calcite
+
+import org.apache.calcite.rel.rules._
+import org.apache.calcite.sql.fun.{OracleSqlOperatorTable, SqlStdOperatorTable}
+import org.apache.calcite.tools.RuleSets
+import org.apache.flink.table.plan.rules.datastream.DataStreamRetractionRules
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.JavaConverters._
+
+class CalciteConfigBuilderTest {
+
+ @Test
+ def testDefaultRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder().build()
+
+ assertFalse(cc.replacesNormRuleSet)
+ assertFalse(cc.getNormRuleSet.isDefined)
+
+ assertFalse(cc.replacesLogicalOptRuleSet)
+ assertFalse(cc.getLogicalOptRuleSet.isDefined)
+
+ assertFalse(cc.replacesPhysicalOptRuleSet)
+ assertFalse(cc.getPhysicalOptRuleSet.isDefined)
+
+ assertFalse(cc.replacesDecoRuleSet)
+ assertFalse(cc.getDecoRuleSet.isDefined)
+ }
+
+ @Test
+ def testRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
+ .replaceLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .replacePhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .replaceDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ .build()
+
+ assertFalse(cc.replacesNormRuleSet)
+ assertTrue(cc.getNormRuleSet.isDefined)
+
+ assertTrue(cc.replacesLogicalOptRuleSet)
+ assertTrue(cc.getLogicalOptRuleSet.isDefined)
+
+ assertTrue(cc.replacesPhysicalOptRuleSet)
+ assertTrue(cc.getPhysicalOptRuleSet.isDefined)
+
+ assertTrue(cc.replacesDecoRuleSet)
+ assertTrue(cc.getDecoRuleSet.isDefined)
+ }
+
+ @Test
+ def testReplaceNormalizationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesNormRuleSet)
+ assertTrue(cc.getNormRuleSet.isDefined)
+ val cSet = cc.getNormRuleSet.get.iterator().asScala.toSet
+ assertEquals(1, cSet.size)
+ assertTrue(cSet.contains(ReduceExpressionsRule.FILTER_INSTANCE))
+ }
+
+ @Test
+ def testReplaceNormalizationAddRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
+ .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.PROJECT_INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesNormRuleSet)
+ assertTrue(cc.getNormRuleSet.isDefined)
+ val cSet = cc.getNormRuleSet.get.iterator().asScala.toSet
+ assertEquals(2, cSet.size)
+ assertTrue(cSet.contains(ReduceExpressionsRule.FILTER_INSTANCE))
+ assertTrue(cSet.contains(ReduceExpressionsRule.PROJECT_INSTANCE))
+ }
+
+ @Test
+ def testAddNormalizationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
+ .build()
+
+ assertEquals(false, cc.replacesNormRuleSet)
+ assertTrue(cc.getNormRuleSet.isDefined)
+ val cSet = cc.getNormRuleSet.get.iterator().asScala.toSet
+ assertEquals(1, cSet.size)
+ assertTrue(cSet.contains(ReduceExpressionsRule.FILTER_INSTANCE))
+ }
+
+ @Test
+ def testAddAddNormalizationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
+ .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.PROJECT_INSTANCE,
+ ReduceExpressionsRule.CALC_INSTANCE))
+ .build()
+
+ assertEquals(false, cc.replacesNormRuleSet)
+ assertTrue(cc.getNormRuleSet.isDefined)
+ val cList = cc.getNormRuleSet.get.iterator().asScala.toList
+ assertEquals(3, cList.size)
+ assertEquals(cList.head, ReduceExpressionsRule.FILTER_INSTANCE)
+ assertEquals(cList(1), ReduceExpressionsRule.PROJECT_INSTANCE)
+ assertEquals(cList(2), ReduceExpressionsRule.CALC_INSTANCE)
+ }
+
+ @Test
+ def testReplaceLogicalOptimizationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesLogicalOptRuleSet)
+ assertTrue(cc.getLogicalOptRuleSet.isDefined)
+ val cSet = cc.getLogicalOptRuleSet.get.iterator().asScala.toSet
+ assertEquals(1, cSet.size)
+ assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
+ }
+
+ @Test
+ def testReplaceLogicalOptimizationAddRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .addLogicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesLogicalOptRuleSet)
+ assertTrue(cc.getLogicalOptRuleSet.isDefined)
+ val cSet = cc.getLogicalOptRuleSet.get.iterator().asScala.toSet
+ assertEquals(3, cSet.size)
+ assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
+ }
+
+ @Test
+ def testAddLogicalOptimizationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .addLogicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
+ .build()
+
+ assertEquals(false, cc.replacesLogicalOptRuleSet)
+ assertTrue(cc.getLogicalOptRuleSet.isDefined)
+ val cSet = cc.getLogicalOptRuleSet.get.iterator().asScala.toSet
+ assertEquals(3, cSet.size)
+ assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
+ }
+
+ @Test
+ def testReplacePhysicalOptimizationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replacePhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesPhysicalOptRuleSet)
+ assertTrue(cc.getPhysicalOptRuleSet.isDefined)
+ val cSet = cc.getPhysicalOptRuleSet.get.iterator().asScala.toSet
+ assertEquals(1, cSet.size)
+ assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
+ }
+
+ @Test
+ def testReplacePhysicalOptimizationAddRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replacePhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .addPhysicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesPhysicalOptRuleSet)
+ assertTrue(cc.getPhysicalOptRuleSet.isDefined)
+ val cSet = cc.getPhysicalOptRuleSet.get.iterator().asScala.toSet
+ assertEquals(3, cSet.size)
+ assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
+ }
+
+ @Test
+ def testAddPhysicalOptimizationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addPhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
+ .addPhysicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
+ .build()
+
+ assertEquals(false, cc.replacesPhysicalOptRuleSet)
+ assertTrue(cc.getPhysicalOptRuleSet.isDefined)
+ val cSet = cc.getPhysicalOptRuleSet.get.iterator().asScala.toSet
+ assertEquals(3, cSet.size)
+ assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
+ assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
+ }
+
+ @Test
+ def testReplaceDecorationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesDecoRuleSet)
+ assertTrue(cc.getDecoRuleSet.isDefined)
+ val cSet = cc.getDecoRuleSet.get.iterator().asScala.toSet
+ assertEquals(1, cSet.size)
+ assertTrue(cSet.contains(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ }
+
+ @Test
+ def testReplaceDecorationAddRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE))
+ .build()
+
+ assertEquals(true, cc.replacesDecoRuleSet)
+ assertTrue(cc.getDecoRuleSet.isDefined)
+ val cSet = cc.getDecoRuleSet.get.iterator().asScala.toSet
+ assertEquals(2, cSet.size)
+ assertTrue(cSet.contains(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ assertTrue(cSet.contains(DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE))
+ }
+
+ @Test
+ def testAddDecorationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ .build()
+
+ assertEquals(false, cc.replacesDecoRuleSet)
+ assertTrue(cc.getDecoRuleSet.isDefined)
+ val cSet = cc.getDecoRuleSet.get.iterator().asScala.toSet
+ assertEquals(1, cSet.size)
+ assertTrue(cSet.contains(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ }
+
+ @Test
+ def testAddAddDecorationRules(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
+ .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE,
+ DataStreamRetractionRules.ACCMODE_INSTANCE))
+ .build()
+
+ assertEquals(false, cc.replacesDecoRuleSet)
+ assertTrue(cc.getDecoRuleSet.isDefined)
+ val cList = cc.getDecoRuleSet.get.iterator().asScala.toList
+ assertEquals(3, cList.size)
+ assertEquals(cList.head, DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE)
+ assertEquals(cList(1), DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE)
+ assertEquals(cList(2), DataStreamRetractionRules.ACCMODE_INSTANCE)
+ }
+
+ @Test
+ def testDefaultOperatorTable(): Unit = {
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .build()
+
+ assertEquals(false, cc.replacesSqlOperatorTable)
+ assertFalse(cc.getSqlOperatorTable.isDefined)
+ }
+
+ @Test
+ def testReplaceOperatorTable(): Unit = {
+
+ val oracleTable = new OracleSqlOperatorTable
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceSqlOperatorTable(oracleTable)
+ .build()
+
+ val oracleOps = oracleTable.getOperatorList.asScala
+
+ assertEquals(true, cc.replacesSqlOperatorTable)
+ assertTrue(cc.getSqlOperatorTable.isDefined)
+ val ops = cc.getSqlOperatorTable.get.getOperatorList
+ .asScala.toSet
+ assertEquals(oracleOps.size, ops.size)
+ for (o <- oracleOps) {
+ assertTrue(ops.contains(o))
+ }
+ }
+
+ @Test
+ def testReplaceAddOperatorTable(): Unit = {
+
+ val oracleTable = new OracleSqlOperatorTable
+ val stdTable = new SqlStdOperatorTable
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceSqlOperatorTable(oracleTable)
+ .addSqlOperatorTable(stdTable)
+ .build()
+
+ val oracleOps = oracleTable.getOperatorList.asScala
+ val stdOps = stdTable.getOperatorList.asScala
+
+ assertEquals(true, cc.replacesSqlOperatorTable)
+ assertTrue(cc.getSqlOperatorTable.isDefined)
+ val ops = cc.getSqlOperatorTable.get.getOperatorList
+ .asScala.toSet
+ assertEquals(oracleOps.size + stdOps.size, ops.size)
+ for (o <- oracleOps) {
+ assertTrue(ops.contains(o))
+ }
+ for (o <- stdOps) {
+ assertTrue(ops.contains(o))
+ }
+
+ }
+
+ @Test
+ def testAddOperatorTable(): Unit = {
+
+ val oracleTable = new OracleSqlOperatorTable
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addSqlOperatorTable(oracleTable)
+ .build()
+
+ val oracleOps = oracleTable.getOperatorList.asScala
+
+ assertEquals(false, cc.replacesSqlOperatorTable)
+ assertTrue(cc.getSqlOperatorTable.isDefined)
+ val ops = cc.getSqlOperatorTable.get.getOperatorList
+ .asScala.toSet
+ assertEquals(oracleOps.size, ops.size)
+ for (o <- oracleOps) {
+ assertTrue(ops.contains(o))
+ }
+ }
+
+ @Test
+ def testAddAddOperatorTable(): Unit = {
+
+ val oracleTable = new OracleSqlOperatorTable
+ val stdTable = new SqlStdOperatorTable
+
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .addSqlOperatorTable(oracleTable)
+ .addSqlOperatorTable(stdTable)
+ .build()
+
+ val oracleOps = oracleTable.getOperatorList.asScala
+ val stdOps = stdTable.getOperatorList.asScala
+
+ assertEquals(false, cc.replacesSqlOperatorTable)
+ assertTrue(cc.getSqlOperatorTable.isDefined)
+ val ops = cc.getSqlOperatorTable.get.getOperatorList
+ .asScala.toSet
+ assertEquals(oracleOps.size + stdOps.size, ops.size)
+ for (o <- oracleOps) {
+ assertTrue(ops.contains(o))
+ }
+ for (o <- stdOps) {
+ assertTrue(ops.contains(o))
+ }
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverterTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverterTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverterTest.scala
deleted file mode 100644
index c315d94..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverterTest.scala
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.calcite
-
-import java.sql.Timestamp
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.calcite.RelTimeIndicatorConverterTest.TableFunc
-import org.apache.flink.table.expressions.{TimeIntervalUnit, WindowReference}
-import org.apache.flink.table.functions.TableFunction
-import org.apache.flink.table.plan.logical.TumblingGroupWindow
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Tests for [[RelTimeIndicatorConverter]].
- */
-class RelTimeIndicatorConverterTest extends TableTestBase {
-
- @Test
- def testSimpleMaterialization(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
-
- val result = t
- .select('rowtime.floor(TimeIntervalUnit.DAY) as 'rowtime, 'long)
- .filter('long > 0)
- .select('rowtime)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "FLOOR(TIME_MATERIALIZATION(rowtime)", "FLAG(DAY)) AS rowtime"),
- term("where", ">(long, 0)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testSelectAll(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
-
- val result = t.select('*)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long", "int",
- "TIME_MATERIALIZATION(proctime) AS proctime")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testFilteringOnRowtime(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .filter('rowtime > "1990-12-02 12:11:11".toTimestamp)
- .select('rowtime)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime"),
- term("where", ">(TIME_MATERIALIZATION(rowtime), 1990-12-02 12:11:11)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testGroupingOnRowtime(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
-
- val result = t
- .groupBy('rowtime)
- .select('long.count)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "long", "TIME_MATERIALIZATION(rowtime) AS rowtime")
- ),
- term("groupBy", "rowtime"),
- term("select", "rowtime", "COUNT(long) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testGroupingOnProctimeSql(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
-
- val result = util.tEnv.sql("SELECT COUNT(long) FROM MyTable GROUP BY proctime")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(proctime) AS proctime", "long")
- ),
- term("groupBy", "proctime"),
- term("select", "proctime", "COUNT(long) AS EXPR$0")
- ),
- term("select", "EXPR$0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testAggregationOnRowtime(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .groupBy('long)
- .select('rowtime.min)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long")
- ),
- term("groupBy", "long"),
- term("select", "long", "MIN(rowtime) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testAggregationOnProctimeSql(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
-
- val result = util.tEnv.sql("SELECT MIN(proctime) FROM MyTable GROUP BY long")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "long", "TIME_MATERIALIZATION(proctime) AS proctime")
- ),
- term("groupBy", "long"),
- term("select", "long", "MIN(proctime) AS EXPR$0")
- ),
- term("select", "EXPR$0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testTableFunction(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
- val func = new TableFunc
-
- val result = t.join(func('rowtime, 'proctime, "") as 's).select('rowtime, 'proctime, 's)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation",
- s"${func.functionIdentifier}(TIME_MATERIALIZATION($$0), TIME_MATERIALIZATION($$3), '')"),
- term("function", func),
- term("rowType", "RecordType(TIMESTAMP(3) rowtime, BIGINT long, INTEGER int, " +
- "TIMESTAMP(3) proctime, VARCHAR(2147483647) s)"),
- term("joinType", "INNER")
- ),
- term("select",
- "TIME_MATERIALIZATION(rowtime) AS rowtime",
- "TIME_MATERIALIZATION(proctime) AS proctime",
- "s")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testWindow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .window(Tumble over 100.millis on 'rowtime as 'w)
- .groupBy('w, 'long)
- .select('w.end as 'rowtime, 'long, 'int.sum)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w,
- 'rowtime,
- 100.millis)),
- term("select", "long", "SUM(int) AS TMP_1", "end('w) AS TMP_0")
- ),
- term("select", "TMP_0 AS rowtime", "long", "TMP_1")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testWindowSql(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
-
- val result = util.tEnv.sql(
- "SELECT TUMBLE_END(rowtime, INTERVAL '0.1' SECOND) AS `rowtime`, `long`, " +
- "SUM(`int`) FROM MyTable " +
- "GROUP BY `long`, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w$"),
- 'rowtime,
- 100.millis)),
- term("select", "long", "SUM(int) AS EXPR$2", "start('w$) AS w$start", "end('w$) AS w$end")
- ),
- term("select", "w$end", "long", "EXPR$2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testWindowWithAggregationOnRowtimeSql(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
-
- val result = util.tEnv.sql("SELECT MIN(rowtime), long FROM MyTable " +
- "GROUP BY long, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "long", "rowtime", "TIME_MATERIALIZATION(rowtime) AS $f2")
- ),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w$,
- 'rowtime,
- 100.millis)),
- term("select", "long", "MIN($f2) AS EXPR$0")
- ),
- term("select", "EXPR$0", "long")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testUnion(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
-
- val result = t.unionAll(t).select('rowtime)
-
- val expected = unaryNode(
- "DataStreamCalc",
- binaryNode(
- "DataStreamUnion",
- streamTableNode(0),
- streamTableNode(0),
- term("union all", "rowtime", "long", "int")
- ),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testMultiWindow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .window(Tumble over 100.millis on 'rowtime as 'w)
- .groupBy('w, 'long)
- .select('w.rowtime as 'newrowtime, 'long, 'int.sum as 'int)
- .window(Tumble over 1.second on 'newrowtime as 'w2)
- .groupBy('w2, 'long)
- .select('w2.end, 'long, 'int.sum)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w,
- 'rowtime,
- 100.millis)),
- term("select", "long", "SUM(int) AS TMP_1", "rowtime('w) AS TMP_0")
- ),
- term("select", "TMP_0 AS newrowtime", "long", "TMP_1 AS int")
- ),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w2,
- 'newrowtime,
- 1000.millis)),
- term("select", "long", "SUM(int) AS TMP_3", "end('w2) AS TMP_2")
- ),
- term("select", "TMP_2", "long", "TMP_3")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
-
-object RelTimeIndicatorConverterTest {
-
- class TableFunc extends TableFunction[String] {
- val t = new Timestamp(0L)
- def eval(time1: Long, time2: Timestamp, string: String): Unit = {
- collect(time1.toString + time2.after(t) + string)
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala
new file mode 100644
index 0000000..a25f2c2
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.calcite.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.WindowReference
+import org.apache.flink.table.plan.logical.TumblingGroupWindow
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Tests for [[org.apache.flink.table.calcite.RelTimeIndicatorConverter]].
+ */
+class RelTimeIndicatorConverterTest extends TableTestBase {
+
+ @Test
+ def testGroupingOnProctime(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
+
+ val result = util.tableEnv.sql("SELECT COUNT(long) FROM MyTable GROUP BY proctime")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(proctime) AS proctime", "long")
+ ),
+ term("groupBy", "proctime"),
+ term("select", "proctime", "COUNT(long) AS EXPR$0")
+ ),
+ term("select", "EXPR$0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testAggregationOnProctime(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
+
+ val result = util.tableEnv.sql("SELECT MIN(proctime) FROM MyTable GROUP BY long")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "long", "TIME_MATERIALIZATION(proctime) AS proctime")
+ ),
+ term("groupBy", "long"),
+ term("select", "long", "MIN(proctime) AS EXPR$0")
+ ),
+ term("select", "EXPR$0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testWindow(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+
+ val result = util.tableEnv.sql(
+ "SELECT TUMBLE_END(rowtime, INTERVAL '0.1' SECOND) AS `rowtime`, `long`, " +
+ "SUM(`int`) FROM MyTable " +
+ "GROUP BY `long`, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w$"),
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "SUM(int) AS EXPR$2", "start('w$) AS w$start", "end('w$) AS w$end")
+ ),
+ term("select", "w$end", "long", "EXPR$2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testWindowWithAggregationOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+
+ val result = util.tableEnv.sql("SELECT MIN(rowtime), long FROM MyTable " +
+ "GROUP BY long, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "long", "rowtime", "TIME_MATERIALIZATION(rowtime) AS $f2")
+ ),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w$,
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "MIN($f2) AS EXPR$0")
+ ),
+ term("select", "EXPR$0", "long")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala
new file mode 100644
index 0000000..0416392
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.calcite.table
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.calcite.table.RelTimeIndicatorConverterTest.TableFunc
+import org.apache.flink.table.expressions.TimeIntervalUnit
+import org.apache.flink.table.functions.TableFunction
+import org.apache.flink.table.plan.logical.TumblingGroupWindow
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Tests for [[org.apache.flink.table.calcite.RelTimeIndicatorConverter]].
+ */
+class RelTimeIndicatorConverterTest extends TableTestBase {
+
+ @Test
+ def testSimpleMaterialization(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+
+ val result = t
+ .select('rowtime.floor(TimeIntervalUnit.DAY) as 'rowtime, 'long)
+ .filter('long > 0)
+ .select('rowtime)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "FLOOR(TIME_MATERIALIZATION(rowtime)", "FLAG(DAY)) AS rowtime"),
+ term("where", ">(long, 0)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testSelectAll(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+
+ val result = t.select('*)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long", "int",
+ "TIME_MATERIALIZATION(proctime) AS proctime")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testFilteringOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .filter('rowtime > "1990-12-02 12:11:11".toTimestamp)
+ .select('rowtime)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime"),
+ term("where", ">(TIME_MATERIALIZATION(rowtime), 1990-12-02 12:11:11)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testGroupingOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+
+ val result = t
+ .groupBy('rowtime)
+ .select('long.count)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "long", "TIME_MATERIALIZATION(rowtime) AS rowtime")
+ ),
+ term("groupBy", "rowtime"),
+ term("select", "rowtime", "COUNT(long) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testAggregationOnRowtime(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .groupBy('long)
+ .select('rowtime.min)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long")
+ ),
+ term("groupBy", "long"),
+ term("select", "long", "MIN(rowtime) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testTableFunction(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
+ val func = new TableFunc
+
+ val result = t.join(func('rowtime, 'proctime, "") as 's).select('rowtime, 'proctime, 's)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation",
+ s"${func.functionIdentifier}(TIME_MATERIALIZATION($$0), TIME_MATERIALIZATION($$3), '')"),
+ term("function", func),
+ term("rowType", "RecordType(TIMESTAMP(3) rowtime, BIGINT long, INTEGER int, " +
+ "TIMESTAMP(3) proctime, VARCHAR(2147483647) s)"),
+ term("joinType", "INNER")
+ ),
+ term("select",
+ "TIME_MATERIALIZATION(rowtime) AS rowtime",
+ "TIME_MATERIALIZATION(proctime) AS proctime",
+ "s")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testWindow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .window(Tumble over 100.millis on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ .select('w.end as 'rowtime, 'long, 'int.sum)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w,
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "SUM(int) AS TMP_1", "end('w) AS TMP_0")
+ ),
+ term("select", "TMP_0 AS rowtime", "long", "TMP_1")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+
+ val result = t.unionAll(t).select('rowtime)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ binaryNode(
+ "DataStreamUnion",
+ streamTableNode(0),
+ streamTableNode(0),
+ term("union all", "rowtime", "long", "int")
+ ),
+ term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testMultiWindow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
+
+ val result = t
+ .window(Tumble over 100.millis on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ .select('w.rowtime as 'newrowtime, 'long, 'int.sum as 'int)
+ .window(Tumble over 1.second on 'newrowtime as 'w2)
+ .groupBy('w2, 'long)
+ .select('w2.end, 'long, 'int.sum)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w,
+ 'rowtime,
+ 100.millis)),
+ term("select", "long", "SUM(int) AS TMP_1", "rowtime('w) AS TMP_0")
+ ),
+ term("select", "TMP_0 AS newrowtime", "long", "TMP_1 AS int")
+ ),
+ term("groupBy", "long"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ 'w2,
+ 'newrowtime,
+ 1000.millis)),
+ term("select", "long", "SUM(int) AS TMP_3", "end('w2) AS TMP_2")
+ ),
+ term("select", "TMP_2", "long", "TMP_3")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
+
+object RelTimeIndicatorConverterTest {
+
+ class TableFunc extends TableFunction[String] {
+ val t = new Timestamp(0L)
+ def eval(time1: Long, time2: Timestamp, string: String): Unit = {
+ collect(time1.toString + time2.after(t) + string)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala
new file mode 100644
index 0000000..d981c82
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.catalog.batch.sql
+
+import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
+import org.apache.flink.table.utils.CommonTestData
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Test for external catalog query plan.
+ */
+class ExternalCatalogTest extends ExternalCatalogTestBase {
+
+ @Test
+ def test(): Unit = {
+ val util = batchTestUtil()
+
+ util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
+ "(SELECT a * 2, b, c FROM test.db1.tb1)"
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS EXPR$0", "e", "g"),
+ term("where", "<(d, 3)")),
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS EXPR$0", "b", "c")
+ ),
+ term("union", "EXPR$0", "e", "g"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala
new file mode 100644
index 0000000..fab6c08
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.catalog.batch.table
+
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
+import org.apache.flink.table.utils.CommonTestData
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Test for external catalog query plan.
+ */
+class ExternalCatalogTest extends ExternalCatalogTestBase {
+
+ @Test
+ def test(): Unit = {
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val table1 = tEnv.scan("test", "db1", "tb1")
+ val table2 = tEnv.scan("test", "db2", "tb2")
+ val result = table2
+ .select('d * 2, 'e, 'g.upperCase())
+ .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
+ ),
+ term("union", "_c0", "e", "_c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testTopLevelTable(): Unit = {
+ val util = batchTestUtil()
+ val tEnv = util.tableEnv
+
+ tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val table1 = tEnv.scan("test", "tb1")
+ val table2 = tEnv.scan("test", "db2", "tb2")
+ val result = table2
+ .select('d * 2, 'e, 'g.upperCase())
+ .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table1TopLevelPath, table1ProjectedFields),
+ term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
+ ),
+ term("union", "_c0", "e", "_c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala
new file mode 100644
index 0000000..786c4a1
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.catalog.stream.sql
+
+import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
+import org.apache.flink.table.utils.CommonTestData
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Test for external catalog query plan.
+ */
+class ExternalCatalogTest extends ExternalCatalogTestBase {
+
+ @Test
+ def test(): Unit = {
+ val util = streamTestUtil()
+
+ util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
+ "(SELECT a * 2, b, c FROM test.db1.tb1)"
+
+ val expected = binaryNode(
+ "DataStreamUnion",
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS EXPR$0", "e", "g"),
+ term("where", "<(d, 3)")),
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS EXPR$0", "b", "c")
+ ),
+ term("union all", "EXPR$0", "e", "g"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala
new file mode 100644
index 0000000..79d3f99
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.catalog.stream.table
+
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
+import org.apache.flink.table.utils.CommonTestData
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Test for external catalog query plan.
+ */
+class ExternalCatalogTest extends ExternalCatalogTestBase {
+
+ @Test
+ def testStreamTableApi(): Unit = {
+ val util = streamTestUtil()
+ val tEnv = util.tableEnv
+
+ util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val table1 = tEnv.scan("test", "db1", "tb1")
+ val table2 = tEnv.scan("test", "db2", "tb2")
+
+ val result = table2.where("d < 3")
+ .select('d * 2, 'e, 'g.upperCase())
+ .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
+
+ val expected = binaryNode(
+ "DataStreamUnion",
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2"),
+ term("where", "<(d, 3)")
+ ),
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
+ ),
+ term("union all", "_c0", "e", "_c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala
new file mode 100644
index 0000000..19fbd36
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.catalog.utils
+
+import org.apache.flink.table.utils.TableTestBase
+
+class ExternalCatalogTestBase extends TableTestBase {
+ protected val table1Path: Array[String] = Array("test", "db1", "tb1")
+ protected val table1TopLevelPath: Array[String] = Array("test", "tb1")
+ protected val table1ProjectedFields: Array[String] = Array("a", "b", "c")
+ protected val table2Path: Array[String] = Array("test", "db2", "tb2")
+ protected val table2ProjectedFields: Array[String] = Array("d", "e", "g")
+
+ def sourceBatchTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
+ s"BatchTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
+ s"fields=[${fields.mkString(", ")}])"
+ }
+
+ def sourceStreamTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
+ s"StreamTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
+ s"fields=[${fields.mkString(", ")}])"
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ArrayTypeTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ArrayTypeTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ArrayTypeTest.scala
index 297c21a..536f6ba 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ArrayTypeTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ArrayTypeTest.scala
@@ -20,80 +20,12 @@ package org.apache.flink.table.expressions
import java.sql.Date
-import org.apache.flink.api.common.typeinfo.{BasicArrayTypeInfo, PrimitiveArrayTypeInfo, TypeInformation}
-import org.apache.flink.api.java.typeutils.ObjectArrayTypeInfo
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.types.Row
+import org.apache.flink.table.api.Types
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.ExpressionTestBase
-import org.apache.flink.table.api.{Types, ValidationException}
+import org.apache.flink.table.expressions.utils.ArrayTypeTestBase
import org.junit.Test
-class ArrayTypeTest extends ExpressionTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testObviousInvalidIndexTableApi(): Unit = {
- testTableApi('f2.at(0), "FAIL", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testEmptyArraySql(): Unit = {
- testSqlApi("ARRAY[]", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testEmptyArrayTableApi(): Unit = {
- testTableApi("FAIL", "array()", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testNullArraySql(): Unit = {
- testSqlApi("ARRAY[NULL]", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testDifferentTypesArraySql(): Unit = {
- testSqlApi("ARRAY[1, TRUE]", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testDifferentTypesArrayTableApi(): Unit = {
- testTableApi("FAIL", "array(1, true)", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnsupportedComparison(): Unit = {
- testAllApis(
- 'f2 <= 'f5.at(1),
- "f2 <= f5.at(1)",
- "f2 <= f5[1]",
- "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testElementNonArray(): Unit = {
- testTableApi(
- 'f0.element(),
- "FAIL",
- "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testElementNonArraySql(): Unit = {
- testSqlApi(
- "ELEMENT(f0)",
- "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testCardinalityOnNonArray(): Unit = {
- testTableApi('f0.cardinality(), "FAIL", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testCardinalityOnNonArraySql(): Unit = {
- testSqlApi("CARDINALITY(f0)", "FAIL")
- }
+class ArrayTypeTest extends ArrayTypeTestBase {
@Test
def testArrayLiterals(): Unit = {
@@ -363,42 +295,4 @@ class ArrayTypeTest extends ExpressionTestBase {
"f11 <> f9",
"false")
}
-
- // ----------------------------------------------------------------------------------------------
-
- case class MyCaseClass(string: String, int: Int)
-
- override def testData: Any = {
- val testData = new Row(12)
- testData.setField(0, null)
- testData.setField(1, 42)
- testData.setField(2, Array(1, 2, 3))
- testData.setField(3, Array(Date.valueOf("1984-03-12"), Date.valueOf("1984-02-10")))
- testData.setField(4, null)
- testData.setField(5, Array(Array(1, 2, 3), null))
- testData.setField(6, Array[Integer](1, null, null, 4))
- testData.setField(7, Array(1, 2, 3, 4))
- testData.setField(8, Array(4.0))
- testData.setField(9, Array[Integer](1))
- testData.setField(10, Array[Integer]())
- testData.setField(11, Array[Integer](1))
- testData
- }
-
- override def typeInfo: TypeInformation[Any] = {
- new RowTypeInfo(
- Types.INT,
- Types.INT,
- PrimitiveArrayTypeInfo.INT_PRIMITIVE_ARRAY_TYPE_INFO,
- ObjectArrayTypeInfo.getInfoFor(Types.SQL_DATE),
- ObjectArrayTypeInfo.getInfoFor(ObjectArrayTypeInfo.getInfoFor(Types.INT)),
- ObjectArrayTypeInfo.getInfoFor(PrimitiveArrayTypeInfo.INT_PRIMITIVE_ARRAY_TYPE_INFO),
- ObjectArrayTypeInfo.getInfoFor(Types.INT),
- PrimitiveArrayTypeInfo.INT_PRIMITIVE_ARRAY_TYPE_INFO,
- PrimitiveArrayTypeInfo.DOUBLE_PRIMITIVE_ARRAY_TYPE_INFO,
- ObjectArrayTypeInfo.getInfoFor(Types.INT),
- ObjectArrayTypeInfo.getInfoFor(Types.INT),
- BasicArrayTypeInfo.INT_ARRAY_TYPE_INFO
- ).asInstanceOf[TypeInformation[Any]]
- }
}
[33/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala
new file mode 100644
index 0000000..02f84c0
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.{Upper, WindowReference}
+import org.apache.flink.table.plan.logical.TumblingGroupWindow
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcTest extends TableTestBase {
+
+ // ----------------------------------------------------------------------------------------------
+ // Tests for all the situations when we can do fields projection. Like selecting few fields
+ // from a large field count source.
+ // ----------------------------------------------------------------------------------------------
+
+ @Test
+ def testSelectFromWindow(): Unit = {
+ val util = streamTestUtil()
+ val sourceTable =
+ util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
+ val resultTable = sourceTable
+ .window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select(Upper('c).count, 'a.sum)
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "c", "a", "rowtime", "UPPER(c) AS $f3")
+ ),
+ term("window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'rowtime,
+ 5.millis)),
+ term("select", "COUNT($f3) AS TMP_0", "SUM(a) AS TMP_1")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectFromGroupedWindow(): Unit = {
+ val util = streamTestUtil()
+ val sourceTable =
+ util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
+ val resultTable = sourceTable
+ .window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'b)
+ .select(Upper('c).count, 'a.sum, 'b)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "c", "a", "b", "rowtime", "UPPER(c) AS $f4")
+ ),
+ term("groupBy", "b"),
+ term("window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'rowtime,
+ 5.millis)),
+ term("select", "b", "COUNT($f4) AS TMP_0", "SUM(a) AS TMP_1")
+ ),
+ term("select", "TMP_0", "TMP_1", "b")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala
new file mode 100644
index 0000000..8f53f4a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.runtime.utils._
+import org.apache.flink.table.utils._
+import org.junit.Test
+
+class CorrelateTest extends TableTestBase {
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("func1", new TableFunc1)
+
+ val result1 = table.join(function('c) as 's).select('c, 's)
+
+ val expected1 = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "s")
+ )
+
+ util.verifyTable(result1, expected1)
+
+ // test overloading
+
+ val result2 = table.join(function('c, "$") as 's).select('c, 's)
+
+ val expected2 = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2, '$$')"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "s")
+ )
+
+ util.verifyTable(result2, expected2)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("func1", new TableFunc1)
+
+ val result = table.leftOuterJoin(function('c) as 's).select('c, 's)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
+ term("joinType", "LEFT")
+ ),
+ term("select", "c", "s")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testCustomType(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("func2", new TableFunc2)
+
+ val result = table.join(function('c) as ('name, 'len)).select('c, 'name, 'len)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
+ "VARCHAR(2147483647) name, INTEGER len)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "name", "len")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testHierarchyType(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("hierarchy", new HierarchyTableFunction)
+
+ val result = table.join(function('c) as ('name, 'adult, 'len))
+
+ val expected = unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
+ " VARCHAR(2147483647) name, BOOLEAN adult, INTEGER len)"),
+ term("joinType", "INNER")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testPojoType(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("pojo", new PojoTableFunc)
+
+ val result = table.join(function('c))
+
+ val expected = unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
+ "INTEGER age, VARCHAR(2147483647) name)"),
+ term("joinType", "INNER")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testFilter(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("func2", new TableFunc2)
+
+ val result = table
+ .join(function('c) as ('name, 'len))
+ .select('c, 'name, 'len)
+ .filter('len > 2)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}($$2)"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
+ "VARCHAR(2147483647) name, INTEGER len)"),
+ term("joinType", "INNER"),
+ term("condition", ">($1, 2)")
+ ),
+ term("select", "c", "name", "len")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testScalarFunction(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = util.addFunction("func1", new TableFunc1)
+
+ val result = table.join(function('c.substring(2)) as 's)
+
+ val expected = unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", s"${function.functionIdentifier}(SUBSTRING($$2, 2, CHAR_LENGTH($$2)))"),
+ term("function", function),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
+ term("joinType", "INNER")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala
new file mode 100644
index 0000000..a024460
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala
@@ -0,0 +1,785 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.WindowReference
+import org.apache.flink.table.plan.logical._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.{Ignore, Test}
+
+class GroupWindowTest extends TableTestBase {
+
+ @Test
+ def testMultiWindow(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 50.milli on 'proctime as 'w1)
+ .groupBy('w1, 'string)
+ .select('w1.proctime as 'proctime, 'string, 'int.count)
+ .window(Slide over 20.milli every 10.milli on 'proctime as 'w2)
+ .groupBy('w2)
+ .select('string.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w1"),
+ 'proctime,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_1", "proctime('w1) AS TMP_0")
+ ),
+ term("select", "string", "TMP_0 AS proctime")
+ ),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w2"),
+ 'proctime,
+ 20.milli,
+ 10.milli)),
+ term("select", "COUNT(string) AS TMP_2")
+ )
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 50.milli on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(WindowReference("w"), 'proctime, 2.rows)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 5.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowWithUdAgg(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val weightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'rowtime,
+ 5.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 2.rows,
+ 1.rows)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "rowtime")
+ ),
+ term("groupBy", "string"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ @Ignore // see comments in DataStreamGroupWindowAggregate
+ def testEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 8.milli,
+ 10.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowWithUdAgg(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val weightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindowWithUdAgg(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val weightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'rowtime, 7.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 50.milli on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "proctime")
+ ),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 2.rows)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "rowtime")
+ ),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ @Ignore // see comments in DataStreamGroupWindowAggregate
+ def testAllEventTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "long")
+ ),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 5.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "proctime")
+ ),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli,
+ 50.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "proctime")
+ ),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 2.rows,
+ 1.rows)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "rowtime")
+ ),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+// @Ignore // see comments in DataStreamGroupWindowAggregate
+ def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "long")
+ ),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeSessionGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "long")
+ ),
+ term(
+ "window",
+ SessionGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 7.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testTumbleWindowStartEnd(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "rowtime")
+ ),
+ term("groupBy", "string"),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
+ term("select",
+ "string",
+ "COUNT(int) AS TMP_0",
+ "start('w) AS TMP_1",
+ "end('w) AS TMP_2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testSlidingWindowWithUDAF(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String, Int, Int)](
+ 'long,
+ 'int,
+ 'string,
+ 'int2,
+ 'int3,
+ 'proctime.proctime)
+
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'int2, 'int3, 'string)
+ .select(weightAvgFun('long, 'int))
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string, int2, int3"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'proctime, 2.rows, 1.rows)),
+ term(
+ "select",
+ "string",
+ "int2",
+ "int3",
+ "WeightedAvg(long, int) AS TMP_0")
+ ),
+ term("select","TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testSlideWindowStartEnd(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 10.milli every 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "rowtime")
+ ),
+ term("groupBy", "string"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 10.milli, 5.milli)),
+ term("select",
+ "string",
+ "COUNT(int) AS TMP_0",
+ "start('w) AS TMP_1",
+ "end('w) AS TMP_2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testSessionWindowStartWithTwoEnd(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Session withGap 3.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('w.end as 'we1, 'string, 'int.count as 'cnt, 'w.start as 'ws, 'w.end as 'we2)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'long, 3.milli)),
+ term("select",
+ "string",
+ "COUNT(int) AS TMP_1",
+ "end('w) AS TMP_0",
+ "start('w) AS TMP_2")
+ ),
+ term("select", "TMP_0 AS we1", "string", "TMP_1 AS cnt", "TMP_2 AS ws", "TMP_0 AS we2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testTumbleWindowWithDuplicateAggsAndProps(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.millis on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.sum + 1 as 's1, 'int.sum + 3 as 's2, 'w.start as 'x, 'w.start as 'x2,
+ 'w.end as 'x3, 'w.end)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.millis)),
+ term("select",
+ "string",
+ "SUM(int) AS TMP_0",
+ "start('w) AS TMP_1",
+ "end('w) AS TMP_2")
+ ),
+ term("select",
+ "string",
+ "+(CAST(TMP_0), 1) AS s1",
+ "+(CAST(TMP_0), 3) AS s2",
+ "TMP_1 AS x",
+ "TMP_1 AS x2",
+ "TMP_2 AS x3",
+ "TMP_2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala
new file mode 100644
index 0000000..8b563a3
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala
@@ -0,0 +1,596 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithRetract
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils.Func1
+import org.apache.flink.table.api.Table
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.StreamTableTestUtil
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class OverWindowTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ val table: Table = streamUtil.addTable[(Int, String, Long)]("MyTable",
+ 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
+
+ @Test
+ def testScalarFunctionsOnOverWindow() = {
+ val weightedAvg = new WeightedAvgWithRetract
+ val plusOne = Func1
+
+ val result = table
+ .window(Over partitionBy 'b orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
+ .select(
+ plusOne('a.sum over 'w as 'wsum) as 'd,
+ ('a.count over 'w).exp(),
+ (weightedAvg('c, 'a) over 'w) + 1,
+ "AVG:".toExpr + (weightedAvg('c, 'a) over 'w),
+ array(weightedAvg('c, 'a) over 'w, 'a.count over 'w))
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c", "proctime")
+ ),
+ term("partitionBy", "b"),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "b", "c", "proctime",
+ "SUM(a) AS w0$o0",
+ "COUNT(a) AS w0$o1",
+ "WeightedAvgWithRetract(c, a) AS w0$o2")
+ ),
+ term("select",
+ s"${plusOne.functionIdentifier}(w0$$o0) AS d",
+ "EXP(CAST(w0$o1)) AS _c1",
+ "+(w0$o2, 1) AS _c2",
+ "||('AVG:', CAST(w0$o2)) AS _c3",
+ "ARRAY(w0$o2, w0$o1) AS _c4")
+ )
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeBoundedPartitionedRowsOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(Over partitionBy 'b orderBy 'proctime preceding 2.rows following CURRENT_ROW as 'w)
+ .select('c, weightedAvg('c, 'a) over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c", "proctime")
+ ),
+ term("partitionBy", "b"),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "b", "c", "proctime", "WeightedAvgWithRetract(c, a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS _c1")
+ )
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeBoundedPartitionedRangeOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(
+ Over partitionBy 'a orderBy 'proctime preceding 2.hours following CURRENT_RANGE as 'w)
+ .select('a, weightedAvg('c, 'a) over 'w as 'myAvg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("partitionBy", "a"),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "proctime",
+ "WeightedAvgWithRetract(c, a) AS w0$o0"
+ )
+ ),
+ term("select", "a", "w0$o0 AS myAvg")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeBoundedNonPartitionedRangeOver() = {
+ val result = table
+ .window(Over orderBy 'proctime preceding 10.second as 'w)
+ .select('a, 'c.count over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN 10000 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(c) AS w0$o0")
+ ),
+ term("select", "a", "w0$o0 AS _c1")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeBoundedNonPartitionedRowsOver() = {
+ val result = table
+ .window(Over orderBy 'proctime preceding 2.rows as 'w)
+ .select('c, 'a.count over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS _c1")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeUnboundedPartitionedRangeOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_RANGE following
+ CURRENT_RANGE as 'w)
+ .select('a, 'c, 'a.count over 'w, weightedAvg('c, 'a) over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "proctime",
+ "COUNT(a) AS w0$o0",
+ "WeightedAvgWithRetract(c, a) AS w0$o1"
+ )
+ ),
+ term(
+ "select",
+ "a",
+ "c",
+ "w0$o0 AS _c2",
+ "w0$o1 AS _c3"
+ )
+ )
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeUnboundedPartitionedRowsOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(
+ Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_ROW following CURRENT_ROW as 'w)
+ .select('c, 'a.count over 'w, weightedAvg('c, 'a) over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime",
+ "COUNT(a) AS w0$o0",
+ "WeightedAvgWithRetract(c, a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS _c1", "w0$o1 AS _c2")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRangeOver() = {
+ val result = table
+ .window(
+ Over orderBy 'proctime preceding UNBOUNDED_RANGE as 'w)
+ .select('a, 'c, 'a.count over 'w, 'a.sum over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "proctime",
+ "COUNT(a) AS w0$o0",
+ "SUM(a) AS w0$o1"
+ )
+ ),
+ term(
+ "select",
+ "a",
+ "c",
+ "w0$o0 AS _c2",
+ "w0$o1 AS _c3"
+ )
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRowsOver() = {
+ val result = table
+ .window(Over orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
+ .select('c, 'a.count over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS _c1")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRowsOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(
+ Over partitionBy 'b orderBy 'rowtime preceding 2.rows following CURRENT_ROW as 'w)
+ .select('c, 'b.count over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c", "rowtime")
+ ),
+ term("partitionBy", "b"),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "b", "c", "rowtime",
+ "COUNT(b) AS w0$o0",
+ "WeightedAvgWithRetract(c, a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS _c1", "w0$o1 AS wAvg")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRangeOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(
+ Over partitionBy 'a orderBy 'rowtime preceding 2.hours following CURRENT_RANGE as 'w)
+ .select('a, 'c.avg over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("partitionBy", "a"),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "rowtime",
+ "AVG(c) AS w0$o0",
+ "WeightedAvgWithRetract(c, a) AS w0$o1"
+ )
+ ),
+ term("select", "a", "w0$o0 AS _c1", "w0$o1 AS wAvg")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRangeOver() = {
+ val result = table
+ .window(Over orderBy 'rowtime preceding 10.second as 'w)
+ .select('a, 'c.count over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN 10000 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(c) AS w0$o0")
+ ),
+ term("select", "a", "w0$o0 AS _c1")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRowsOver() = {
+ val result = table
+ .window(Over orderBy 'rowtime preceding 2.rows as 'w)
+ .select('c, 'a.count over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS _c1")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedPartitionedRangeOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding UNBOUNDED_RANGE following
+ CURRENT_RANGE as 'w)
+ .select('a, 'c, 'a.count over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "rowtime",
+ "COUNT(a) AS w0$o0",
+ "WeightedAvgWithRetract(c, a) AS w0$o1"
+ )
+ ),
+ term(
+ "select",
+ "a",
+ "c",
+ "w0$o0 AS _c2",
+ "w0$o1 AS wAvg"
+ )
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedPartitionedRowsOver() = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding UNBOUNDED_ROW following
+ CURRENT_ROW as 'w)
+ .select('c, 'a.count over 'w, weightedAvg('c, 'a) over 'w as 'wAvg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime",
+ "COUNT(a) AS w0$o0",
+ "WeightedAvgWithRetract(c, a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS _c1", "w0$o1 AS wAvg")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedNonPartitionedRangeOver() = {
+ val result = table
+ .window(
+ Over orderBy 'rowtime preceding UNBOUNDED_RANGE as 'w)
+ .select('a, 'c, 'a.count over 'w, 'a.sum over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "rowtime",
+ "COUNT(a) AS w0$o0",
+ "SUM(a) AS w0$o1"
+ )
+ ),
+ term(
+ "select",
+ "a",
+ "c",
+ "w0$o0 AS _c2",
+ "w0$o1 AS _c3"
+ )
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedNonPartitionedRowsOver() = {
+ val result = table
+ .window(Over orderBy 'rowtime preceding UNBOUNDED_ROW as 'w)
+ .select('c, 'a.count over 'w)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS _c1")
+ )
+
+ streamUtil.verifyTable(result, expected)
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala
new file mode 100644
index 0000000..5d4386c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.streaming.api.datastream.DataStream
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.sources.{DefinedProctimeAttribute, DefinedRowtimeAttribute, StreamTableSource}
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class TableSourceTest extends TableTestBase {
+
+ @Test
+ def testRowTimeTableSourceSimple(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
+
+ val t = util.tableEnv.scan("rowTimeT").select("addTime, id, name, val")
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
+ term("select", "TIME_MATERIALIZATION(addTime) AS addTime", "id", "name", "val")
+ )
+ util.verifyTable(t, expected)
+ }
+
+ @Test
+ def testRowTimeTableSourceGroupWindow(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
+
+ val t = util.tableEnv.scan("rowTimeT")
+ .filter("val > 100")
+ .window(Tumble over 10.minutes on 'addTime as 'w)
+ .groupBy('name, 'w)
+ .select('name, 'w.end, 'val.avg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
+ term("select", "name", "val", "addTime"),
+ term("where", ">(val, 100)")
+ ),
+ term("groupBy", "name"),
+ term("window", "TumblingGroupWindow('w, 'addTime, 600000.millis)"),
+ term("select", "name", "AVG(val) AS TMP_1", "end('w) AS TMP_0")
+ ),
+ term("select", "name", "TMP_0", "TMP_1")
+ )
+ util.verifyTable(t, expected)
+ }
+
+ @Test
+ def testProcTimeTableSourceSimple(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
+
+ val t = util.tableEnv.scan("procTimeT").select("pTime, id, name, val")
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
+ term("select", "TIME_MATERIALIZATION(pTime) AS pTime", "id", "name", "val")
+ )
+ util.verifyTable(t, expected)
+ }
+
+ @Test
+ def testProcTimeTableSourceOverWindow(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
+
+ val t = util.tableEnv.scan("procTimeT")
+ .window(Over partitionBy 'id orderBy 'pTime preceding 2.hours as 'w)
+ .select('id, 'name, 'val.sum over 'w as 'valSum)
+ .filter('valSum > 100)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
+ term("partitionBy", "id"),
+ term("orderBy", "pTime"),
+ term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
+ term("select", "id", "val", "name", "pTime", "SUM(val) AS w0$o0")
+ ),
+ term("select", "id", "name", "w0$o0 AS valSum"),
+ term("where", ">(w0$o0, 100)")
+ )
+ util.verifyTable(t, expected)
+ }
+}
+
+class TestRowtimeSource(timeField: String)
+ extends StreamTableSource[Row] with DefinedRowtimeAttribute {
+
+ override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
+
+ override def getRowtimeAttribute: String = timeField
+
+ override def getReturnType: TypeInformation[Row] = {
+ new RowTypeInfo(
+ Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
+ Array("id", "val", "name"))
+ }
+}
+
+class TestProctimeSource(timeField: String)
+ extends StreamTableSource[Row] with DefinedProctimeAttribute {
+
+ override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
+
+ override def getProctimeAttribute: String = timeField
+
+ override def getReturnType: TypeInformation[Row] = {
+ new RowTypeInfo(
+ Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
+ Array("id", "val", "name"))
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/AggregateStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/AggregateStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/AggregateStringExpressionTest.scala
new file mode 100644
index 0000000..2bef95e
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/AggregateStringExpressionTest.scala
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvg
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class AggregateStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testGroupedAggregate(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .groupBy('string)
+ .select('int.count as 'cnt, weightAvgFun('long, 'int))
+
+ // String / Java API
+ val resJava = t
+ .groupBy("string")
+ .select("int.count as cnt, weightAvgFun(long, int)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testNonGroupedAggregate(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ // Expression / Scala API
+ val resScala = t.select('int.count as 'cnt, 'long.sum)
+
+ // String / Java API
+ val resJava = t.select("int.count as cnt, long.sum")
+
+ verifyTableEquals(resJava, resScala)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CalcStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CalcStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CalcStringExpressionTest.scala
new file mode 100644
index 0000000..6fd0158
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CalcStringExpressionTest.scala
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testSimpleSelect(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]()
+
+ val resScala = t.select('_1, '_2)
+ val resJava = t.select("_1, _2")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSelectStar(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.select('*)
+ val resJava = t.select("*")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSelectWithWhere(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val resScala = t.where('string === "true").select('int)
+ val resJava = t.where("string === 'true'").select("int")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSimpleSelectWithNaming(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.select('int, 'string)
+ val resJava = t.select("int, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSimpleSelectWithAlias(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val resScala = t.select('int as 'myInt, 'string as 'myString)
+ val resJava = t.select("int as myInt, string as myString")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSimpleFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter('int === 3).select('int as 'myInt, 'string)
+ val resJava = t.filter("int === 3").select("int as myInt, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter(Literal(false)).select('int as 'myInt, 'string)
+ val resJava = t.filter("false").select("int as myInt, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter(Literal(true)).select('int as 'myInt, 'string)
+ val resJava = t.filter("true").select("int as myInt, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testNotEqualsFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter('int !== 2).filter('string.like("%world%")).select('int, 'string)
+ val resJava = t.filter("int !== 2").filter("string.like('%world%')").select("int, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testFilterWithExpression(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter('int % 2 === 0).select('int, 'string)
+ val resJava = t.filter("int % 2 === 0").select("int, string")
+ verifyTableEquals(resJava, resScala)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala
new file mode 100644
index 0000000..0d12400
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.stringexpr
+
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api._
+import org.apache.flink.table.runtime.utils._
+import org.apache.flink.table.utils._
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class CorrelateStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testCorrelateJoins(): Unit = {
+
+ val util = streamTestUtil()
+ val sTab = util.addTable[(Int, Long, String)]('a, 'b, 'c)
+ val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
+ val jTab = util.addJavaTable[Row](typeInfo,"MyTab","a, b, c")
+
+ // test cross join
+ val func1 = new TableFunc1
+ util.javaTableEnv.registerFunction("func1", func1)
+ var scalaTable = sTab.join(func1('c) as 's).select('c, 's)
+ var javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c).as(s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test left outer join
+ scalaTable = sTab.leftOuterJoin(func1('c) as 's).select('c, 's)
+ javaTable = jTab.leftOuterJoin(new Table(util.javaTableEnv, "func1(c)").as("s")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test overloading
+ scalaTable = sTab.join(func1('c, "$") as 's).select('c, 's)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test custom result type
+ val func2 = new TableFunc2
+ util.javaTableEnv.registerFunction("func2", func2)
+ scalaTable = sTab.join(func2('c) as ('name, 'len)).select('c, 'name, 'len)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test hierarchy generic type
+ val hierarchy = new HierarchyTableFunction
+ util.javaTableEnv.registerFunction("hierarchy", hierarchy)
+ scalaTable = sTab.join(hierarchy('c) as ('name, 'adult, 'len)).select('c, 'name, 'len, 'adult)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
+ .select("c, name, len, adult")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test pojo type
+ val pojo = new PojoTableFunc
+ util.javaTableEnv.registerFunction("pojo", pojo)
+ scalaTable = sTab.join(pojo('c)).select('c, 'name, 'age)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "pojo(c)")).select("c, name, age")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with filter
+ scalaTable = sTab.join(func2('c) as ('name, 'len)).select('c, 'name, 'len).filter('len > 2)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func2(c) as (name, len)"))
+ .select("c, name, len").filter("len > 2")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with scalar function
+ scalaTable = sTab.join(func1('c.substring(2)) as 's).select('a, 'c, 's)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func1(substring(c, 2)) as (s)")).select("a, c, s")
+ verifyTableEquals(scalaTable, javaTable)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/GroupWindowStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
new file mode 100644
index 0000000..2cb5a8a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvg
+import org.apache.flink.table.api.java.{Session => JSession, Slide => JSlide, Tumble => JTumble}
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testRowTimeSlide(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'rowtime.rowtime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Slide over 4.hours every 2.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select(
+ 'string,
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JSlide.over("4.hours").every("2.hours").on("rowtime").as("w"))
+ .groupBy("w, string")
+ .select(
+ "string, " +
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)," +
+ "end(w)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testRowTimeTumble(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, Long, String)]('int, 'long, 'rowtime.rowtime, 'string)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Tumble over 4.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select(
+ 'string,
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JTumble.over("4.hours").on("rowtime").as("w"))
+ .groupBy("w, string")
+ .select(
+ "string, " +
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)," +
+ "end(w)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testRowTimeSession(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'rowtime.rowtime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Session withGap 4.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select(
+ 'string,
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start)
+
+ // String / Java API
+ val resJava = t
+ .window(JSession.withGap("4.hours").on("rowtime").as("w"))
+ .groupBy("w, string")
+ .select(
+ "string, " +
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)"
+ )
+
+ verifyTableEquals(resJava, resScala)
+ }
+ @Test
+ def testProcTimeSlide(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'proctime.proctime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Slide over 4.hours every 2.hours on 'proctime as 'w)
+ .groupBy('w)
+ .select(
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JSlide.over("4.hours").every("2.hours").on("proctime").as("w"))
+ .groupBy("w")
+ .select(
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)," +
+ "end(w)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testProcTimeTumble(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long,'string, 'proctime.proctime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Tumble over 4.hours on 'proctime as 'w)
+ .groupBy('w)
+ .select(
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JTumble.over("4.hours").on("proctime").as("w"))
+ .groupBy("w")
+ .select(
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)," +
+ "end(w)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testProcTimeSession(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'proctime.proctime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Session withGap 4.hours on 'proctime as 'w)
+ .groupBy('w)
+ .select(
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JSession.withGap("4.hours").on("proctime").as("w"))
+ .groupBy("w")
+ .select(
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w), " +
+ "end(w)"
+ )
+
+ verifyTableEquals(resJava, resScala)
+ }
+}
[32/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/OverWindowStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/OverWindowStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/OverWindowStringExpressionTest.scala
new file mode 100644
index 0000000..3e757da
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/OverWindowStringExpressionTest.scala
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithRetract
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvg
+import org.apache.flink.table.api.java.{Over => JOver}
+import org.apache.flink.table.api.scala.{Over => SOver, _}
+import org.apache.flink.table.expressions.utils.Func1
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class OverWindowStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testPartitionedUnboundedOverRow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_ROW as 'w)
+ .select('a, 'b.sum over 'w as 'cnt, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_row").as("w"))
+ .select("a, SUM(b) OVER w as cnt, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testUnboundedOverRow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver orderBy 'rowtime preceding UNBOUNDED_ROW following CURRENT_ROW as 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(JOver.orderBy("rowtime").preceding("unbounded_row").following("current_row").as("w"))
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testPartitionedBoundedOverRow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver partitionBy('a, 'd) orderBy 'rowtime preceding 10.rows as 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(JOver.partitionBy("a, d").orderBy("rowtime").preceding("10.rows").as("w"))
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testBoundedOverRow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver orderBy 'rowtime preceding 10.rows following CURRENT_ROW as 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(JOver.orderBy("rowtime").preceding("10.rows").following("current_row").as("w"))
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testPartitionedUnboundedOverRange(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_RANGE as 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_range").as("w"))
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testUnboundedOverRange(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver orderBy 'rowtime preceding UNBOUNDED_RANGE following CURRENT_RANGE as 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(
+ JOver.orderBy("rowtime").preceding("unbounded_range").following("current_range").as("w"))
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testPartitionedBoundedOverRange(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver partitionBy('a, 'c) orderBy 'rowtime preceding 10.minutes as 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(JOver.partitionBy("a, c").orderBy("rowtime").preceding("10.minutes").as("w"))
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testBoundedOverRange(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ val resScala = t
+ .window(SOver orderBy 'rowtime preceding 4.hours following CURRENT_RANGE as 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
+ val resJava = t
+ .window(JOver.orderBy("rowtime").preceding("4.hours").following("current_range").as("w"))
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
+
+ verifyTableEquals(resScala, resJava)
+ }
+
+ @Test
+ def testScalarFunctionsOnOverWindow(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+
+ val weightedAvg = new WeightedAvgWithRetract
+ val plusOne = Func1
+ util.addFunction("plusOne", plusOne)
+ util.addFunction("weightedAvg", weightedAvg)
+
+ val resScala = t
+ .window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_ROW as 'w)
+ .select(
+ array('a.sum over 'w, 'a.count over 'w),
+ plusOne('b.sum over 'w as 'wsum) as 'd,
+ ('a.count over 'w).exp(),
+ (weightedAvg('a, 'b) over 'w) + 1,
+ "AVG:".toExpr + (weightedAvg('a, 'b) over 'w))
+
+ val resJava = t
+ .window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_row").as("w"))
+ .select(
+ s"""
+ |ARRAY(SUM(a) OVER w, COUNT(a) OVER w),
+ |plusOne(SUM(b) OVER w AS wsum) AS d,
+ |EXP(COUNT(a) OVER w),
+ |(weightedAvg(a, b) OVER w) + 1,
+ |'AVG:' + (weightedAvg(a, b) OVER w)
+ """.stripMargin)
+
+ verifyTableEquals(resScala, resJava)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/SetOperatorsStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/SetOperatorsStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/SetOperatorsStringExpressionTest.scala
new file mode 100644
index 0000000..bfb3ef6
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/SetOperatorsStringExpressionTest.scala
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class SetOperatorsStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testUnionAll(): Unit = {
+ val util = streamTestUtil()
+ val t1 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val t2 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t1.unionAll(t2).select('int)
+ val resJava = t1.unionAll(t2).select("int")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testUnionAllWithFilter(): Unit = {
+ val util = streamTestUtil()
+ val t1 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val t2 = util.addTable[(Int, Long, Double, String)]('int, 'long, 'double, 'string)
+
+ val resScala = t1.unionAll(t2.select('int, 'long, 'string)).filter('int < 2).select('int)
+ val resJava = t1.unionAll(t2.select("int, long, string")).filter("int < 2").select("int")
+ verifyTableEquals(resJava, resScala)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/AggregateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/AggregateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/AggregateValidationTest.scala
new file mode 100644
index 0000000..5953ca4
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/AggregateValidationTest.scala
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class AggregateValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupingOnNonExistentField(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val ds = table
+ // must fail. '_foo is not a valid field
+ .groupBy('_foo)
+ .select('a.avg)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupingInvalidSelection(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ table
+ .groupBy('a, 'b)
+ // must fail. 'c is not a grouping key or aggregation
+ .select('c)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CalcValidationTest.scala
new file mode 100644
index 0000000..6e0e15e
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CalcValidationTest.scala
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.stream.table.validation
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala.{Tumble, _}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidUseOfRowtime(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, Double, Float, BigDecimal, String)](
+ "MyTable",
+ 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ .select('rowtime.rowtime)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidUseOfRowtime2(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, Double, Float, BigDecimal, String)](
+ "MyTable",
+ 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ .window(Tumble over 2.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.end.rowtime, 'int.count as 'int) // no rowtime on non-window reference
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CorrelateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CorrelateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CorrelateValidationTest.scala
new file mode 100644
index 0000000..dbc7d46
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/CorrelateValidationTest.scala
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils._
+import org.apache.flink.table.runtime.utils._
+import org.apache.flink.table.utils.{ObjectTableFunction, TableFunc1, TableFunc2, TableTestBase}
+import org.junit.Assert.{assertTrue, fail}
+import org.junit.Test
+
+class CorrelateValidationTest extends TableTestBase {
+
+ @Test
+ def testRegisterFunctionException(): Unit ={
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('a, 'b, 'c)
+
+ // check scala object is forbidden
+ expectExceptionThrown(
+ util.tableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
+ expectExceptionThrown(
+ util.javaTableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
+
+ expectExceptionThrown(t.join(ObjectTableFunction('a, 1)), "Scala object")
+ }
+
+ @Test
+ def testInvalidTableFunctions(): Unit = {
+ val util = streamTestUtil()
+
+ val func1 = new TableFunc1
+ util.javaTableEnv.registerFunction("func1", func1)
+
+ // table function call select
+ expectExceptionThrown(
+ func1('c).select("f0"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call select
+ expectExceptionThrown(
+ func1('c).select('f0),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call writeToSink
+ expectExceptionThrown(
+ func1('c).writeToSink(null),
+ "Cannot translate a query with an unbounded table function call."
+ )
+
+ // table function call distinct
+ expectExceptionThrown(
+ func1('c).distinct(),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call filter
+ expectExceptionThrown(
+ func1('c).filter('f0 === "?"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call filter
+ expectExceptionThrown(
+ func1('c).filter("f0 = '?'"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call limit
+ expectExceptionThrown(
+ func1('c).orderBy('f0).limit(3),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call limit
+ expectExceptionThrown(
+ func1('c).orderBy('f0).limit(0, 3),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call orderBy
+ expectExceptionThrown(
+ func1('c).orderBy("f0"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call orderBy
+ expectExceptionThrown(
+ func1('c).orderBy('f0),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call where
+ expectExceptionThrown(
+ func1('c).where("f0 = '?'"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ // table function call where
+ expectExceptionThrown(
+ func1('c).where('f0 === "?"),
+ "TableFunction can only be used in join and leftOuterJoin."
+ )
+
+ }
+
+ @Test
+ def testInvalidTableFunction(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ //=================== check scala object is forbidden =====================
+ // Scala table environment register
+ expectExceptionThrown(util.addFunction("udtf", ObjectTableFunction), "Scala object")
+ // Java table environment register
+ expectExceptionThrown(
+ util.tableEnv.registerFunction("udtf", ObjectTableFunction), "Scala object")
+ // Scala Table API directly call
+ expectExceptionThrown(t.join(ObjectTableFunction('a, 1)), "Scala object")
+
+
+ //============ throw exception when table function is not registered =========
+ // Java Table API call
+ expectExceptionThrown(
+ t.join(new Table(util.tableEnv, "nonexist(a)")
+ ), "Undefined function: NONEXIST")
+ // SQL API call
+ expectExceptionThrown(
+ util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(nonexist(a))"),
+ "No match found for function signature nonexist(<NUMERIC>)")
+
+
+ //========= throw exception when the called function is a scalar function ====
+ util.tableEnv.registerFunction("func0", Func0)
+
+ // Java Table API call
+ expectExceptionThrown(
+ t.join(new Table(util.tableEnv, "func0(a)")),
+ "only accept String that define table function",
+ classOf[TableException])
+ // SQL API call
+ // NOTE: it doesn't throw an exception but an AssertionError, maybe a Calcite bug
+ expectExceptionThrown(
+ util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func0(a))"),
+ null,
+ classOf[AssertionError])
+
+ //========== throw exception when the parameters is not correct ===============
+ // Java Table API call
+ util.addFunction("func2", new TableFunc2)
+ expectExceptionThrown(
+ t.join(new Table(util.tableEnv, "func2(c, c)")),
+ "Given parameters of function 'FUNC2' do not match any signature")
+ // SQL API call
+ expectExceptionThrown(
+ util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func2(c, c))"),
+ "No match found for function signature func2(<CHARACTER>, <CHARACTER>)")
+ }
+
+ // ----------------------------------------------------------------------------------------------
+
+ private def expectExceptionThrown(
+ function: => Unit,
+ keywords: String,
+ clazz: Class[_ <: Throwable] = classOf[ValidationException])
+ : Unit = {
+ try {
+ function
+ fail(s"Expected a $clazz, but no exception is thrown.")
+ } catch {
+ case e if e.getClass == clazz =>
+ if (keywords != null) {
+ assertTrue(
+ s"The exception message '${e.getMessage}' doesn't contain keyword '$keywords'",
+ e.getMessage.contains(keywords))
+ }
+ case e: Throwable => fail(s"Expected throw ${clazz.getSimpleName}, but is $e.")
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/GroupWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/GroupWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/GroupWindowValidationTest.scala
new file mode 100644
index 0000000..8d5943d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/GroupWindowValidationTest.scala
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMerge
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowProperty(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .groupBy('string)
+ .select('string, 'string.start) // property in non windowed table
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupByWithoutWindowAlias(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidRowTimeRef(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
+ .groupBy('w2)
+ .select('string)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidTumblingSize(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Tumble over "WRONG" on 'long as 'w) // string is not a valid interval
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testTumbleUdAggWithInvalidArgs(): Unit = {
+ val util = streamTestUtil()
+ val weightedAvg = new WeightedAvgWithMerge
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Tumble over 2.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSlidingSize(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Slide over "WRONG" every "WRONG" on 'long as 'w) // string is not a valid interval
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSlidingSlide(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ // row and time intervals may not be mixed
+ .window(Slide over 12.rows every 1.minute on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSlideUdAggWithInvalidArgs(): Unit = {
+ val util = streamTestUtil()
+ val weightedAvg = new WeightedAvgWithMerge
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Slide over 2.hours every 30.minutes on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSessionGap(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ // row interval is not valid for session windows
+ .window(Session withGap 10.rows on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowAlias1(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Session withGap 100.milli on 'long as 1 + 1) // expression instead of a symbol
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowAlias2(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ // field name "string" is already present
+ .window(Session withGap 100.milli on 'long as 'string)
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSessionUdAggWithInvalidArgs(): Unit = {
+ val util = streamTestUtil()
+ val weightedAvg = new WeightedAvgWithMerge
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ table
+ .window(Session withGap 2.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowPropertyOnRowCountsTumblingWindow(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowPropertyOnRowCountsSlidingWindow(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ table
+ .window(Slide over 10.rows every 5.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/OverWindowValidationTest.scala
new file mode 100644
index 0000000..37e1526
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/OverWindowValidationTest.scala
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{Table, ValidationException}
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.{OverAgg0, WeightedAvgWithRetract}
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class OverWindowValidationTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ val table: Table = streamUtil.addTable[(Int, String, Long)]("MyTable",
+ 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+ val overAgg = new OverAgg0
+ table.select(overAgg('a, 'b))
+ }
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation2(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val overAgg = new OverAgg0
+ table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select(overAgg('long, 'int))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowAlias(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
+ .select('c, 'b.count over 'x)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testOrderBy(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'abc preceding 2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPrecedingAndFollowingUsingIsLiteral(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2 following "xx" as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPrecedingAndFollowingUsingSameType(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_RANGE as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPartitionByWithUnresolved(): Unit = {
+ val result = table
+ .window(Over partitionBy 'a + 'b orderBy 'rowtime preceding 2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPartitionByWithNotKeyType(): Unit = {
+ val table2 = streamUtil.addTable[(Int, String, Either[Long, String])]("MyTable2", 'a, 'b, 'c)
+
+ val result = table2
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPrecedingValue(): Unit = {
+ val result = table
+ .window(Over orderBy 'rowtime preceding -1.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFollowingValue(): Unit = {
+ val result = table
+ .window(Over orderBy 'rowtime preceding 1.rows following -2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUdAggWithInvalidArgs(): Unit = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
+ .select('c, weightedAvg('b, 'a) over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test
+ def testAccessesWindowProperties(): Unit = {
+ thrown.expect(classOf[ValidationException])
+ thrown.expectMessage("Window start and end properties are not available for Over windows.")
+
+ table
+ .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
+ .select('c, 'a.count over 'w, 'w.start, 'w.end)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/SetOperatorsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/SetOperatorsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/SetOperatorsValidationTest.scala
new file mode 100644
index 0000000..1b20d99
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/SetOperatorsValidationTest.scala
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamTestData}
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+import scala.collection.mutable
+
+class SetOperatorsValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionFieldsNameNotOverlap1(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
+
+ val unionDs = ds1.unionAll(ds2)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ assertEquals(true, StreamITCase.testResults.isEmpty)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionFieldsNameNotOverlap2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .select('a, 'b, 'c)
+
+ val unionDs = ds1.unionAll(ds2)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ assertEquals(true, StreamITCase.testResults.isEmpty)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionTablesFromDifferentEnv(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv1, 'a, 'b, 'c)
+ val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv2, 'a, 'b, 'c)
+
+ // Must fail. Tables are bound to different TableEnvironments.
+ ds1.unionAll(ds2)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSinkValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSinkValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSinkValidationTest.scala
new file mode 100644
index 0000000..1c36169
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSinkValidationTest.scala
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.{TableEnvironment, TableException}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.stream.table.{TestAppendSink, TestUpsertSink}
+import org.apache.flink.table.runtime.utils.StreamTestData
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableSinkValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testAppendSinkOnUpdatingTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'id, 'num, 'text)
+
+ t.groupBy('text)
+ .select('text, 'id.count, 'num.sum)
+ .writeToSink(new TestAppendSink)
+
+ // must fail because table is not append-only
+ env.execute()
+ }
+
+ @Test(expected = classOf[TableException])
+ def testUpsertSinkOnUpdatingTableWithoutFullKey(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text)
+
+ t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
+ .groupBy('len, 'cTrue)
+ .select('len, 'id.count, 'num.sum)
+ .writeToSink(new TestUpsertSink(Array("len", "cTrue"), false))
+
+ // must fail because table is updating table without full key
+ env.execute()
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSourceValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSourceValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSourceValidationTest.scala
new file mode 100644
index 0000000..dea55c2
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/TableSourceValidationTest.scala
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.stream.table.{TestProctimeSource, TestRowtimeSource}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableSourceValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeTableSourceWithEmptyName(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource(" "))
+
+ val t = util.tableEnv.scan("rowTimeT")
+ .select('id)
+
+ util.tableEnv.optimize(t.getRelNode, updatesAsRetraction = false)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testProctimeTableSourceWithEmptyName(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource(" "))
+
+ val t = util.tableEnv.scan("procTimeT")
+ .select('id)
+
+ util.tableEnv.optimize(t.getRelNode, updatesAsRetraction = false)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/UnsupportedOpsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/UnsupportedOpsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/UnsupportedOpsValidationTest.scala
new file mode 100644
index 0000000..635aba5
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/validation/UnsupportedOpsValidationTest.scala
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table.validation
+
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.runtime.utils.StreamTestData
+import org.junit.Test
+
+class UnsupportedOpsValidationTest extends StreamingMultipleProgramsTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testSort(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).orderBy('_1.desc)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoin(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.join(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.union(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testIntersect(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.intersect(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testIntersectAll(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.intersectAll(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMinus(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.minus(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMinusAll(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.minusAll(t2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testLimit(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
+ t1.limit(0,5)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableEnvironmentValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableEnvironmentValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableEnvironmentValidationTest.scala
new file mode 100644
index 0000000..1e7ad61
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableEnvironmentValidationTest.scala
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.validation
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo.{DOUBLE_TYPE_INFO, INT_TYPE_INFO, STRING_TYPE_INFO}
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.{GenericTypeInfo, RowTypeInfo, TupleTypeInfo, TypeExtractor}
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{CClass, PojoClass, TableEnvironment, TableException}
+import org.apache.flink.table.expressions.{Alias, UnresolvedFieldReference}
+import org.apache.flink.table.runtime.types.CRowTypeInfo
+import org.apache.flink.types.Row
+import org.junit.Assert.assertTrue
+import org.junit._
+
+class TableEnvironmentValidationTest {
+
+ private val env = ExecutionEnvironment.getExecutionEnvironment
+ private val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val tupleType = new TupleTypeInfo(
+ INT_TYPE_INFO,
+ STRING_TYPE_INFO,
+ DOUBLE_TYPE_INFO)
+
+ val rowType = new RowTypeInfo(INT_TYPE_INFO, STRING_TYPE_INFO,DOUBLE_TYPE_INFO)
+
+ val cRowType = new CRowTypeInfo(rowType)
+
+ val caseClassType: TypeInformation[CClass] = implicitly[TypeInformation[CClass]]
+
+ val pojoType: TypeInformation[PojoClass] = TypeExtractor.createTypeInfo(classOf[PojoClass])
+
+ val atomicType = INT_TYPE_INFO
+
+ val genericRowType = new GenericTypeInfo[Row](classOf[Row])
+
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoPojoNames1(): Unit = {
+ tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoAtomicName2(): Unit = {
+ tEnv.getFieldInfo(
+ atomicType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoTupleAlias3(): Unit = {
+ tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ Alias(UnresolvedFieldReference("xxx"), "name1"),
+ Alias(UnresolvedFieldReference("yyy"), "name2"),
+ Alias(UnresolvedFieldReference("zzz"), "name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoCClassAlias3(): Unit = {
+ tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ Alias(UnresolvedFieldReference("xxx"), "name1"),
+ Alias(UnresolvedFieldReference("yyy"), "name2"),
+ Alias(UnresolvedFieldReference("zzz"), "name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoPojoAlias3(): Unit = {
+ tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ Alias(UnresolvedFieldReference("xxx"), "name1"),
+ Alias(UnresolvedFieldReference("yyy"), "name2"),
+ Alias(UnresolvedFieldReference("zzz"), "name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoAtomicAlias(): Unit = {
+ tEnv.getFieldInfo(
+ atomicType,
+ Array(
+ Alias(UnresolvedFieldReference("name1"), "name2")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoGenericRowAlias(): Unit = {
+ tEnv.getFieldInfo(
+ genericRowType,
+ Array(UnresolvedFieldReference("first")))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRegisterExistingDataSet(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds1)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ // Must fail. Name is already in use.
+ tEnv.registerDataSet("MyTable", ds2)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testScanUnregisteredTable(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ // Must fail. No table registered under that name.
+ tEnv.scan("someTable")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRegisterExistingTable(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", t1)
+ val t2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
+ // Must fail. Name is already in use.
+ tEnv.registerDataSet("MyTable", t2)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRegisterTableFromOtherEnv(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+
+ val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv1)
+ // Must fail. Table is bound to different TableEnvironment.
+ tEnv2.registerTable("MyTable", t1)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithToManyFields(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ CollectionDataSets.get3TupleDataSet(env)
+ // Must fail. Number of fields does not match.
+ .toTable(tEnv, 'a, 'b, 'c, 'd)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithAmbiguousFields(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ CollectionDataSets.get3TupleDataSet(env)
+ // Must fail. Field names not unique.
+ .toTable(tEnv, 'a, 'b, 'b)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithNonFieldReference1(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ // Must fail. as() can only have field references
+ CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a + 1, 'b, 'c)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithNonFieldReference2(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ // Must fail. as() can only have field references
+ CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a as 'foo, 'b, 'c)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGenericRow() {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+
+ // use null value the enforce GenericType
+ val dataSet = env.fromElements(Row.of(null))
+ assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
+ assertTrue(dataSet.getType().getTypeClass == classOf[Row])
+
+ // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
+ tableEnv.fromDataSet(dataSet)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGenericRowWithAlias() {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+
+ // use null value the enforce GenericType
+ val dataSet = env.fromElements(Row.of(null))
+ assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
+ assertTrue(dataSet.getType().getTypeClass == classOf[Row])
+
+ // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
+ tableEnv.fromDataSet(dataSet, "nullField")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSchemaValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSchemaValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSchemaValidationTest.scala
new file mode 100644
index 0000000..1a7815a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSchemaValidationTest.scala
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.validation
+
+import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
+import org.apache.flink.table.api.{TableException, TableSchema}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableSchemaValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testInvalidSchema() {
+ val fieldNames = Array("a", "b", "c")
+ val typeInfos: Array[TypeInformation[_]] = Array(
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO)
+ new TableSchema(fieldNames, typeInfos)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSinksValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSinksValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSinksValidationTest.scala
new file mode 100644
index 0000000..ab87cd3
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSinksValidationTest.scala
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.stream.table.TestAppendSink
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableSinksValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testAppendSinkOnUpdatingTable(): Unit = {
+ val util = streamTestUtil()
+
+ val t = util.addTable[(Int, Long, String)]("MyTable", 'id, 'num, 'text)
+
+ t.groupBy('text)
+ .select('text, 'id.count, 'num.sum)
+ // must fail because table is not append-only
+ .writeToSink(new TestAppendSink)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSourceValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSourceValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSourceValidationTest.scala
new file mode 100644
index 0000000..49784be
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/validation/TableSourceValidationTest.scala
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.validation
+
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.sources.CsvTableSource
+import org.junit.Test
+
+class TableSourceValidationTest {
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithNullPath(): Unit = {
+ CsvTableSource.builder()
+ .field("myfield", Types.STRING)
+ // should fail, path is not defined
+ .build()
+ }
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithDuplicateFieldName(): Unit = {
+ CsvTableSource.builder()
+ .path("/path/to/csv")
+ .field("myfield", Types.STRING)
+ // should fail, field name must no be duplicate
+ .field("myfield", Types.INT)
+ }
+
+ @Test(expected = classOf[IllegalArgumentException])
+ def testCsvTableSourceBuilderWithEmptyField(): Unit = {
+ CsvTableSource.builder()
+ .path("/path/to/csv")
+ // should fail, field can be empty
+ .build()
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala
index 0780b25..c73c20c 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/CalciteConfigBuilderTest.scala
@@ -397,6 +397,4 @@ class CalciteConfigBuilderTest {
}
}
-
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala
deleted file mode 100644
index a25f2c2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/sql/RelTimeIndicatorConverterTest.scala
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.calcite.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.WindowReference
-import org.apache.flink.table.plan.logical.TumblingGroupWindow
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Tests for [[org.apache.flink.table.calcite.RelTimeIndicatorConverter]].
- */
-class RelTimeIndicatorConverterTest extends TableTestBase {
-
- @Test
- def testGroupingOnProctime(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
-
- val result = util.tableEnv.sql("SELECT COUNT(long) FROM MyTable GROUP BY proctime")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(proctime) AS proctime", "long")
- ),
- term("groupBy", "proctime"),
- term("select", "proctime", "COUNT(long) AS EXPR$0")
- ),
- term("select", "EXPR$0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testAggregationOnProctime(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
-
- val result = util.tableEnv.sql("SELECT MIN(proctime) FROM MyTable GROUP BY long")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "long", "TIME_MATERIALIZATION(proctime) AS proctime")
- ),
- term("groupBy", "long"),
- term("select", "long", "MIN(proctime) AS EXPR$0")
- ),
- term("select", "EXPR$0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testWindow(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
-
- val result = util.tableEnv.sql(
- "SELECT TUMBLE_END(rowtime, INTERVAL '0.1' SECOND) AS `rowtime`, `long`, " +
- "SUM(`int`) FROM MyTable " +
- "GROUP BY `long`, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w$"),
- 'rowtime,
- 100.millis)),
- term("select", "long", "SUM(int) AS EXPR$2", "start('w$) AS w$start", "end('w$) AS w$end")
- ),
- term("select", "w$end", "long", "EXPR$2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testWindowWithAggregationOnRowtime(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
-
- val result = util.tableEnv.sql("SELECT MIN(rowtime), long FROM MyTable " +
- "GROUP BY long, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "long", "rowtime", "TIME_MATERIALIZATION(rowtime) AS $f2")
- ),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w$,
- 'rowtime,
- 100.millis)),
- term("select", "long", "MIN($f2) AS EXPR$0")
- ),
- term("select", "EXPR$0", "long")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala
deleted file mode 100644
index 0416392..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/calcite/table/RelTimeIndicatorConverterTest.scala
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.calcite.table
-
-import java.sql.Timestamp
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.calcite.table.RelTimeIndicatorConverterTest.TableFunc
-import org.apache.flink.table.expressions.TimeIntervalUnit
-import org.apache.flink.table.functions.TableFunction
-import org.apache.flink.table.plan.logical.TumblingGroupWindow
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Tests for [[org.apache.flink.table.calcite.RelTimeIndicatorConverter]].
- */
-class RelTimeIndicatorConverterTest extends TableTestBase {
-
- @Test
- def testSimpleMaterialization(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
-
- val result = t
- .select('rowtime.floor(TimeIntervalUnit.DAY) as 'rowtime, 'long)
- .filter('long > 0)
- .select('rowtime)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "FLOOR(TIME_MATERIALIZATION(rowtime)", "FLAG(DAY)) AS rowtime"),
- term("where", ">(long, 0)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testSelectAll(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
-
- val result = t.select('*)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long", "int",
- "TIME_MATERIALIZATION(proctime) AS proctime")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testFilteringOnRowtime(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .filter('rowtime > "1990-12-02 12:11:11".toTimestamp)
- .select('rowtime)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime"),
- term("where", ">(TIME_MATERIALIZATION(rowtime), 1990-12-02 12:11:11)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testGroupingOnRowtime(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
-
- val result = t
- .groupBy('rowtime)
- .select('long.count)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "long", "TIME_MATERIALIZATION(rowtime) AS rowtime")
- ),
- term("groupBy", "rowtime"),
- term("select", "rowtime", "COUNT(long) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testAggregationOnRowtime(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .groupBy('long)
- .select('rowtime.min)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime", "long")
- ),
- term("groupBy", "long"),
- term("select", "long", "MIN(rowtime) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testTableFunction(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int, 'proctime.proctime)
- val func = new TableFunc
-
- val result = t.join(func('rowtime, 'proctime, "") as 's).select('rowtime, 'proctime, 's)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation",
- s"${func.functionIdentifier}(TIME_MATERIALIZATION($$0), TIME_MATERIALIZATION($$3), '')"),
- term("function", func),
- term("rowType", "RecordType(TIMESTAMP(3) rowtime, BIGINT long, INTEGER int, " +
- "TIMESTAMP(3) proctime, VARCHAR(2147483647) s)"),
- term("joinType", "INNER")
- ),
- term("select",
- "TIME_MATERIALIZATION(rowtime) AS rowtime",
- "TIME_MATERIALIZATION(proctime) AS proctime",
- "s")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testWindow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .window(Tumble over 100.millis on 'rowtime as 'w)
- .groupBy('w, 'long)
- .select('w.end as 'rowtime, 'long, 'int.sum)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w,
- 'rowtime,
- 100.millis)),
- term("select", "long", "SUM(int) AS TMP_1", "end('w) AS TMP_0")
- ),
- term("select", "TMP_0 AS rowtime", "long", "TMP_1")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testUnion(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
-
- val result = t.unionAll(t).select('rowtime)
-
- val expected = unaryNode(
- "DataStreamCalc",
- binaryNode(
- "DataStreamUnion",
- streamTableNode(0),
- streamTableNode(0),
- term("union all", "rowtime", "long", "int")
- ),
- term("select", "TIME_MATERIALIZATION(rowtime) AS rowtime")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testMultiWindow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Long, Int)]('rowtime.rowtime, 'long, 'int)
-
- val result = t
- .window(Tumble over 100.millis on 'rowtime as 'w)
- .groupBy('w, 'long)
- .select('w.rowtime as 'newrowtime, 'long, 'int.sum as 'int)
- .window(Tumble over 1.second on 'newrowtime as 'w2)
- .groupBy('w2, 'long)
- .select('w2.end, 'long, 'int.sum)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w,
- 'rowtime,
- 100.millis)),
- term("select", "long", "SUM(int) AS TMP_1", "rowtime('w) AS TMP_0")
- ),
- term("select", "TMP_0 AS newrowtime", "long", "TMP_1 AS int")
- ),
- term("groupBy", "long"),
- term(
- "window",
- TumblingGroupWindow(
- 'w2,
- 'newrowtime,
- 1000.millis)),
- term("select", "long", "SUM(int) AS TMP_3", "end('w2) AS TMP_2")
- ),
- term("select", "TMP_2", "long", "TMP_3")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
-
-object RelTimeIndicatorConverterTest {
-
- class TableFunc extends TableFunction[String] {
- val t = new Timestamp(0L)
- def eval(time1: Long, time2: Timestamp, string: String): Unit = {
- collect(time1.toString + time2.after(t) + string)
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/ExternalCatalogSchemaTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/ExternalCatalogSchemaTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/ExternalCatalogSchemaTest.scala
index 127c860..339ea52 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/ExternalCatalogSchemaTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/ExternalCatalogSchemaTest.scala
@@ -27,8 +27,8 @@ import org.apache.calcite.schema.SchemaPlus
import org.apache.calcite.sql.validate.SqlMonikerType
import org.apache.flink.table.calcite.{FlinkTypeFactory, FlinkTypeSystem}
import org.apache.flink.table.plan.schema.TableSourceTable
+import org.apache.flink.table.runtime.utils.CommonTestData
import org.apache.flink.table.sources.CsvTableSource
-import org.apache.flink.table.utils.CommonTestData
import org.junit.Assert._
import org.junit.{Before, Test}
@@ -86,5 +86,4 @@ class ExternalCatalogSchemaTest {
Lists.newArrayList(schemaName, db, "nonexist-tb"))
assertNull(relOptTable)
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala
deleted file mode 100644
index d981c82..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/sql/ExternalCatalogTest.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.catalog.batch.sql
-
-import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
-import org.apache.flink.table.utils.CommonTestData
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for external catalog query plan.
- */
-class ExternalCatalogTest extends ExternalCatalogTestBase {
-
- @Test
- def test(): Unit = {
- val util = batchTestUtil()
-
- util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
- "(SELECT a * 2, b, c FROM test.db1.tb1)"
-
- val expected = binaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS EXPR$0", "e", "g"),
- term("where", "<(d, 3)")),
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS EXPR$0", "b", "c")
- ),
- term("union", "EXPR$0", "e", "g"))
-
- util.verifySql(sqlQuery, expected)
- }
-}
[15/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/JoinITCase.scala
deleted file mode 100644
index 3ed44a3..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/JoinITCase.scala
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.{TableEnvironment, TableException, ValidationException}
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Assert.assertEquals
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class JoinITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND b < 2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi,Hallo\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND a < 6 AND h < b"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithMultipleKeys(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d AND b = h"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
- "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoinNonExistingKey(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE foo = e"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery)
- }
-
- @Test(expected = classOf[TableException])
- def testJoinNonMatchingKeyTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = g"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoinWithAmbiguousFields(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'c)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery)
- }
-
- @Test
- def testJoinWithAlias(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT Table5.c, Table3.c FROM Table3, Table5 WHERE a = d AND a < 4"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'c)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = "1,Hi\n" + "2,Hello\n" + "1,Hello\n" +
- "2,Hello world\n" + "2,Hello world\n" + "3,Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[TableException])
- def testJoinNoEqualityPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE d = f"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
- @Test
- def testDataSetJoinWithAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT COUNT(g), COUNT(b) FROM Table3, Table5 WHERE a = d"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("Table3", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("Table5", ds2, 'd, 'e, 'f, 'g, 'h)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "6,6"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableJoinWithAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT COUNT(b), COUNT(g) FROM Table3, Table5 WHERE a = d"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "6,6"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFullOuterJoin(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
- "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
- "null,IJK\n" + "null,JKL\n" + "null,KLM"
-
- val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table5 LEFT OUTER JOIN Table3 ON b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
- "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
- "null,IJK\n" + "null,JKL\n" + "null,KLM"
- val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightOuterJoin(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
- "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
- "null,IJK\n" + "null,JKL\n" + "null,KLM"
- val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[TableException])
- def testCrossJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
- val table2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('b1, 'b2, 'b3)
- tEnv.registerTable("A", table1)
- tEnv.registerTable("B", table2)
-
- val sqlQuery = "SELECT a1, b1 FROM A CROSS JOIN B"
- tEnv.sql(sqlQuery).count
- }
-
- @Test
- def testCrossJoinWithLeftSingleRowInput(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
- tEnv.registerTable("A", table)
-
- val sqlQuery2 = "SELECT * FROM (SELECT count(*) FROM A) CROSS JOIN A"
- val expected =
- "3,1,1,Hi\n" +
- "3,2,2,Hello\n" +
- "3,3,2,Hello world"
- val result = tEnv.sql(sqlQuery2).collect()
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testCrossJoinWithRightSingleRowInput(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
- tEnv.registerTable("A", table)
-
- val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A)"
- val expected =
- "1,1,Hi,3\n" +
- "2,2,Hello,3\n" +
- "3,2,Hello world,3"
- val result = tEnv.sql(sqlQuery1).collect()
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testCrossJoinWithEmptySingleRowInput(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
- tEnv.registerTable("A", table)
-
- val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A HAVING count(*) < 0)"
- val result = tEnv.sql(sqlQuery1).count()
- Assert.assertEquals(0, result)
- }
-
- @Test
- def testLeftNullRightJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt " +
- "FROM (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) RIGHT JOIN A ON a < cnt"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,null",
- "2,null", "2,null",
- "3,null", "3,null", "3,null",
- "4,null", "4,null", "4,null", "4,null",
- "5,null", "5,null", "5,null", "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-
- @Test
- def testLeftSingleRightJoinEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt = a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,null", "2,null", "2,null", "3,3", "3,3",
- "3,3", "4,null", "4,null", "4,null",
- "4,null", "5,null", "5,null", "5,null",
- "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLeftSingleRightJoinNotEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt > a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,3", "2,3", "2,3", "3,null", "3,null",
- "3,null", "4,null", "4,null", "4,null",
- "4,null", "5,null", "5,null", "5,null",
- "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightNullLeftJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt " +
- "FROM A LEFT JOIN (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) ON cnt > a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("A", ds2)
- tEnv.registerTable("B", ds1)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = Seq(
- "2,null", "3,null", "1,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightSingleLeftJoinEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt = a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = Seq(
- "1,null", "2,null", "2,null", "3,3", "3,3",
- "3,3", "4,null", "4,null", "4,null",
- "4,null", "5,null", "5,null", "5,null",
- "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightSingleLeftJoinNotEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt < a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = Seq(
- "1,null", "2,null", "2,null", "3,null", "3,null",
- "3,null", "4,3", "4,3", "4,3",
- "4,3", "5,3", "5,3", "5,3",
- "5,3", "5,3").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightSingleLeftJoinTwoFields(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt, cnt2 " +
- "FROM t1 LEFT JOIN (SELECT COUNT(*) AS cnt,COUNT(*) AS cnt2 FROM t2 ) AS x ON a = cnt"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("t1", ds1)
- tEnv.registerTable("t2", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,null,null",
- "2,null,null", "2,null,null",
- "3,3,3", "3,3,3", "3,3,3",
- "4,null,null", "4,null,null", "4,null,null", "4,null,null",
- "5,null,null", "5,null,null", "5,null,null", "5,null,null", "5,null,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCrossWithUnnest(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- (1, 1L, Array("Hi", "w")),
- (2, 2L, Array("Hello", "k")),
- (3, 2L, Array("Hello world", "x"))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataSet("T", stream, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) as A (s)"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = List("1,Hi", "1,w", "2,Hello", "2,k", "3,Hello world", "3,x")
- val results = result.toDataSet[Row].collect().toList
- assertEquals(expected.toString(), results.sortWith(_.toString < _.toString).toString())
- }
-
- @Test
- def testJoinWithUnnestOfTuple(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- (1, Array((12, "45.6"), (2, "45.612"))),
- (2, Array((13, "41.6"), (1, "45.2136"))),
- (3, Array((18, "42.6")))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataSet("T", stream, 'a, 'b)
-
- val sqlQuery = "" +
- "SELECT a, b, x, y " +
- "FROM " +
- " (SELECT a, b FROM T WHERE a < 3) as tf, " +
- " UNNEST(tf.b) as A (x, y) " +
- "WHERE x > a"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = List(
- "1,[(12,45.6), (2,45.612)],12,45.6",
- "1,[(12,45.6), (2,45.612)],2,45.612",
- "2,[(13,41.6), (1,45.2136)],13,41.6").mkString(", ")
- val results = result.toDataSet[Row].collect().map(_.toString)
- assertEquals(expected, results.sorted.mkString(", "))
- }
-
- @Test(expected = classOf[TableException])
- def testRightOuterJoinWithNonEquiJoinPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and a > d"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[TableException])
- def testLeftOuterJoinWithNonEquiJoinPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and a > d"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[TableException])
- def testFullOuterJoinWithNonEquiJoinPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and a > d"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[TableException])
- def testRightOuterJoinWithLocalPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and e > 3"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[TableException])
- def testLeftOuterJoinWithLocalPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and b > 3"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[TableException])
- def testFullOuterJoinWithLocalPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and b > 3"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala
index de313ff..a56bbed 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/QueryDecorrelationTest.scala
@@ -19,22 +19,18 @@ package org.apache.flink.table.api.scala.batch.sql
import org.apache.flink.api.scala._
import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{BatchTableTestUtil, TableTestBase}
-import org.junit.{Before, Test}
+import org.junit.Test
class QueryDecorrelationTest extends TableTestBase {
- val util: BatchTableTestUtil = batchTestUtil()
-
- @Before
- def setup(): Unit = {
+ @Test
+ def testCorrelationScalarAggAndFilter(): Unit = {
+ val util = batchTestUtil()
util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
util.addTable[(Int, String)]("dept", 'deptno, 'name)
- }
- @Test
- def testCorrelationScalarAggAndFilter(): Unit = {
val sql = "SELECT e1.empno\n" +
"FROM emp e1, dept d1 where e1.deptno = d1.deptno\n" +
"and e1.deptno < 10 and d1.deptno < 15\n" +
@@ -89,6 +85,10 @@ class QueryDecorrelationTest extends TableTestBase {
@Test
def testDecorrelateWithMultiAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
+ util.addTable[(Int, String)]("dept", 'deptno, 'name)
+
val sql = "select sum(e1.empno) from emp e1, dept d1 " +
"where e1.deptno = d1.deptno " +
"and e1.salary > (" +
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsITCase.scala
deleted file mode 100644
index dd99114..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SetOperatorsITCase.scala
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-import scala.util.Random
-
-@RunWith(classOf[Parameterized])
-class SetOperatorsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testUnionAll(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 UNION ALL (SELECT f FROM t2)"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnion(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 UNION (SELECT f FROM t2)"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnionWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM (" +
- "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))" +
- "WHERE b < 2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hallo\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnionWithAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT count(c) FROM (" +
- "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "18"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testExcept(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 EXCEPT (SELECT c FROM t2)"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = env.fromElements((1, 1L, "Hi"))
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @Ignore
- // calcite sql parser doesn't support EXCEPT ALL
- def testExceptAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 EXCEPT ALL SELECT c FROM t2"
-
- val data1 = new mutable.MutableList[Int]
- data1 += (1, 1, 1, 2, 2)
- val data2 = new mutable.MutableList[Int]
- data2 += (1, 2, 2, 3)
- val ds1 = env.fromCollection(data1)
- val ds2 = env.fromCollection(data2)
-
- tEnv.registerDataSet("t1", ds1, 'c)
- tEnv.registerDataSet("t2", ds2, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1\n1"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testExceptWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM (" +
- "SELECT * FROM t1 EXCEPT (SELECT a, b, c FROM t2))" +
- "WHERE b < 2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersect(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 INTERSECT SELECT c FROM t2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Hi"))
- data.+=((2, 2L, "Hello"))
- data.+=((2, 2L, "Hello"))
- data.+=((3, 2L, "Hello world!"))
- val ds2 = env.fromCollection(Random.shuffle(data))
-
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hello\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @Ignore
- // calcite sql parser doesn't support INTERSECT ALL
- def testIntersectAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 INTERSECT ALL SELECT c FROM t2"
-
- val data1 = new mutable.MutableList[Int]
- data1 += (1, 1, 1, 2, 2)
- val data2 = new mutable.MutableList[Int]
- data2 += (1, 2, 2, 3)
- val ds1 = env.fromCollection(data1)
- val ds2 = env.fromCollection(data2)
-
- tEnv.registerDataSet("t1", ds1, 'c)
- tEnv.registerDataSet("t2", ds2, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1\n2\n2"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectWithFilter(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM ((SELECT * FROM t1) INTERSECT (SELECT * FROM t2)) WHERE a > 1"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get3TupleDataSet(env)
-
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SortITCase.scala
deleted file mode 100644
index bc04cc7..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/SortITCase.scala
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala.{ExecutionEnvironment, _}
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.SortTestUtils._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-@RunWith(classOf[Parameterized])
-class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- private def getExecutionEnvironment = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- // set the parallelism explicitly to make sure the query is executed in
- // a distributed manner
- env.setParallelism(3)
- env
- }
-
- @Test
- def testOrderByMultipleFieldsWithSql(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC, _2 DESC"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- (- x.productElement(0).asInstanceOf[Int], - x.productElement(1).asInstanceOf[Long]))
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- def rowOrdering = Ordering.by((r : Row) => {
- // ordering for this tuple will fall into the previous defined tupleOrdering,
- // so we just need to return the field by their defining sequence
- (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
- })
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(rowOrdering)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByWithOffset(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC OFFSET 2 ROWS"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- - x.productElement(0).asInstanceOf[Int] )
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings, 2, 21)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results.
- filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByWithOffsetAndFetch(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings, 2, 7)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByLimit(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _2, _1 LIMIT 5"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- (x.productElement(1).asInstanceOf[Long], x.productElement(0).asInstanceOf[Int]) )
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- def rowOrdering = Ordering.by((r : Row) => {
- // ordering for this tuple will fall into the previous defined tupleOrdering,
- // so we just need to return the field by their defining sequence
- (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
- })
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(rowOrdering)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test(expected = classOf[TableException])
- def testLimitWithoutOrder(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable LIMIT 5"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- tEnv.sql(sqlQuery).toDataSet[Row].collect()
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/TableWithSQLITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/TableWithSQLITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/TableWithSQLITCase.scala
deleted file mode 100644
index 89bf783..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/TableWithSQLITCase.scala
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class TableWithSQLITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSQLTable(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE a > 9"
-
- val result = tEnv.sql(sqlQuery).select('a.avg, 'b.sum, 'c.count)
-
- val expected = "15,65,12"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableSQLTable(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val t1 = ds.filter('a > 9)
-
- tEnv.registerTable("MyTable", t1)
-
- val sqlQuery = "SELECT avg(a) as a1, sum(b) as b1, count(c) as c1 FROM MyTable"
-
- val result = tEnv.sql(sqlQuery).select('a1 + 1, 'b1 - 5, 'c1)
-
- val expected = "16,60,12"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMultipleSQLQueries(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val sqlQuery = "SELECT a as aa FROM MyTable WHERE b = 6"
- val result1 = tEnv.sql(sqlQuery)
- tEnv.registerTable("ResTable", result1)
-
- val sqlQuery2 = "SELECT count(aa) FROM ResTable"
- val result2 = tEnv.sql(sqlQuery2)
-
- val expected = "6"
- val results = result2.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectWithCompositeType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT MyTable.a2, MyTable.a1._2 FROM MyTable"
-
- val ds = env.fromElements(((12, true), "Hello")).toTable(tEnv).as('a1, 'a2)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello,true\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala
index 328c03c..64075ef 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/WindowAggregateTest.scala
@@ -21,8 +21,7 @@ package org.apache.flink.table.api.scala.batch.sql
import java.sql.Timestamp
import org.apache.flink.api.scala._
-import org.apache.flink.table.api.{TableException, ValidationException}
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMerge
import org.apache.flink.table.api.scala._
import org.apache.flink.table.plan.logical._
import org.apache.flink.table.utils.TableTestBase
@@ -31,20 +30,6 @@ import org.junit.Test
class WindowAggregateTest extends TableTestBase {
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
- util.addFunction("overAgg", new OverAgg0)
-
- val sqlQuery = "SELECT overAgg(b, a) FROM T GROUP BY TUMBLE(ts, INTERVAL '2' HOUR)"
-
- util.tEnv.sql(sqlQuery)
- }
-
@Test
def testNonPartitionedTumbleWindow(): Unit = {
val util = batchTestUtil()
@@ -106,7 +91,7 @@ class WindowAggregateTest extends TableTestBase {
util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
val weightedAvg = new WeightedAvgWithMerge
- util.tEnv.registerFunction("weightedAvg", weightedAvg)
+ util.tableEnv.registerFunction("weightedAvg", weightedAvg)
val sql = "SELECT weightedAvg(b, a) AS wAvg " +
"FROM T " +
@@ -272,67 +257,4 @@ class WindowAggregateTest extends TableTestBase {
util.verifySql(sqlQuery, expected)
}
- @Test(expected = classOf[TableException])
- def testTumbleWindowNoOffset(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM T " +
- "GROUP BY TUMBLE(ts, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- util.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testHopWindowNoOffset(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM T " +
- "GROUP BY HOP(ts, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- util.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testSessionWindowNoOffset(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM T " +
- "GROUP BY SESSION(ts, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- util.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testVariableWindowSize() = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val sql = "SELECT COUNT(*) " +
- "FROM T " +
- "GROUP BY TUMBLE(ts, b * INTERVAL '1' MINUTE)"
- util.verifySql(sql, "n/a")
- }
-
- @Test(expected = classOf[ValidationException])
- def testTumbleWindowWithInvalidUdAggArgs() = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
-
- val weightedAvg = new WeightedAvgWithMerge
- util.tEnv.registerFunction("weightedAvg", weightedAvg)
-
- val sql = "SELECT weightedAvg(c, a) AS wAvg " +
- "FROM T " +
- "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE)"
- util.verifySql(sql, "n/a")
- }
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala
new file mode 100644
index 0000000..20d5970
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/AggregationsValidationTest.scala
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class AggregationsValidationTest extends TableTestBase {
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testOverAggregation(): Unit = {
+
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("T", 'a, 'b, 'c)
+
+ util.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(b, a) FROM T"
+ util.tableEnv.sql(sqlQuery)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala
new file mode 100644
index 0000000..7d2de19
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/CalcValidationTest.scala
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcValidationTest extends TableTestBase{
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidFields(): Unit = {
+
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, foo FROM MyTable"
+
+ util.tableEnv.sql(sqlQuery)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala
new file mode 100644
index 0000000..f4c475b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/JoinValidationTest.scala
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class JoinValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinNonExistingKey(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE foo = e"
+
+ util.tableEnv.sql(sqlQuery)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testJoinNonMatchingKeyTypes(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = g"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinWithAmbiguousFields(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testJoinNoEqualityPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE d = f"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testCrossJoin(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, String)]("Table4", 'a1, 'b1, 'c1)
+
+ val sqlQuery = "SELECT a, a1 FROM Table3 CROSS JOIN Table4"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRightOuterJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and a > d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testLeftOuterJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and a > d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testFullOuterJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and a > d"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRightOuterJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e and e > 3"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testLeftOuterJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 LEFT OUTER JOIN Table5 ON b = e and b > 3"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testFullOuterJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e and b > 3"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala
new file mode 100644
index 0000000..61cbfd8
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/SortValidationTest.scala
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class SortValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testLimitWithoutOrder(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT * FROM MyTable LIMIT 5"
+
+ util.tableEnv.sql(sqlQuery).toDataSet[Row]
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala
new file mode 100644
index 0000000..20fdbba
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/validation/WindowAggregateValidationTest.scala
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.batch.sql.validation
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class WindowAggregateValidationTest extends TableTestBase {
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testOverAggregation(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+ util.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(b, a) FROM T GROUP BY TUMBLE(ts, INTERVAL '2' HOUR)"
+
+ util.tableEnv.sql(sqlQuery)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testHopWindowNoOffset(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM T " +
+ "GROUP BY HOP(ts, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ util.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testSessionWindowNoOffset(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM T " +
+ "GROUP BY SESSION(ts, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ util.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testVariableWindowSize() = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sql = "SELECT COUNT(*) " +
+ "FROM T " +
+ "GROUP BY TUMBLE(ts, b * INTERVAL '1' MINUTE)"
+ util.verifySql(sql, "n/a")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testTumbleWindowWithInvalidUdAggArgs() = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val weightedAvg = new WeightedAvgWithMerge
+ util.tableEnv.registerFunction("weightedAvg", weightedAvg)
+
+ val sql = "SELECT weightedAvg(c, a) AS wAvg " +
+ "FROM T " +
+ "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE)"
+ util.verifySql(sql, "n/a")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsITCase.scala
deleted file mode 100644
index 45abf09..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsITCase.scala
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class AggregationsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testAggregationTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1.sum, '_1.sum0, '_1.min, '_1.max, '_1.count, '_1.avg)
-
- val results = t.toDataSet[Row].collect()
- val expected = "231,231,1,21,21,11"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testWorkingAggregationDataTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
- .select('_1.avg, '_2.avg, '_3.avg, '_4.avg, '_5.avg, '_6.avg, '_7.count)
-
- val expected = "1,1,1,1,1.5,1.5,2"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements(
- (1: Byte, 1: Short),
- (2: Byte, 2: Short)).toTable(tEnv)
- .select('_1.avg, '_1.sum, '_1.count, '_2.avg, '_2.sum)
-
- val expected = "1,3,2,1,3"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationWithArithmetic(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
- .select(('_1 + 2).avg + 2, '_2.count + 5)
-
- val expected = "5.5,7"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationWithTwoCount(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
- .select('_1.count, '_2.count)
-
- val expected = "2,2"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationAfterProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
- .select('_1, '_2, '_3)
- .select('_1.avg, '_2.sum, '_3.count)
-
- val expected = "1,3,2"
- val result = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testSQLStyleAggregations(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select(
- """Sum( a) as a1, a.sum as a2,
- |Min (a) as b1, a.min as b2,
- |Max (a ) as c1, a.max as c2,
- |Avg ( a ) as d1, a.avg as d2,
- |Count(a) as e1, a.count as e2
- """.stripMargin)
-
- val expected = "231,231,1,1,21,21,11,11,21,21"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testPojoAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val input = env.fromElements(
- WC("hello", 1),
- WC("hello", 1),
- WC("ciao", 1),
- WC("hola", 1),
- WC("hola", 1))
- val expr = input.toTable(tEnv)
- val result = expr
- .groupBy('word)
- .select('word, 'frequency.sum as 'frequency)
- .filter('frequency === 2)
- .toDataSet[WC]
-
- val mappedResult = result.map(w => (w.word, w.frequency * 10)).collect()
- val expected = "(hello,20)\n" + "(hola,20)"
- TestBaseUtils.compareResultAsText(mappedResult.asJava, expected)
- }
-
- @Test
- def testDistinct(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val distinct = ds.select('b).distinct()
-
- val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
- val results = distinct.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDistinctAfterAggregate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- val distinct = ds.groupBy('a, 'e).select('e).distinct()
-
- val expected = "1\n" + "2\n" + "3\n"
- val results = distinct.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val countFun = new CountAggFunction
- val wAvgFun = new WeightedAvgWithMergeAndReset
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('b, 'a.sum, countFun('c), wAvgFun('b, 'a), wAvgFun('a, 'a))
-
- val expected = "1,1,1,1,1\n" + "2,5,2,2,2\n" + "3,15,3,3,5\n" + "4,34,4,4,8\n" +
- "5,65,5,5,13\n" + "6,111,6,6,18\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupingKeyForwardIfNotUsed(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('a.sum)
-
- val expected = "1\n" + "5\n" + "15\n" + "34\n" + "65\n" + "111\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupNoAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('a.sum as 'd, 'b)
- .groupBy('b, 'd)
- .select('b)
-
- val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithLongKeys(): Unit = {
- // This uses very long keys to force serialized comparison.
- // With short keys, the normalized key is sufficient.
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = env.fromElements(
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2))
- .rebalance().setParallelism(2).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('a, 'b)
- .select('c.sum)
-
- val expected = "10\n" + "8\n"
- val results = ds.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithConstant1(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a, 4 as 'four, 'b)
- .groupBy('four, 'a)
- .select('four, 'b.sum)
-
- val expected = "4,2\n" + "4,3\n" + "4,5\n" + "4,5\n" + "4,5\n" + "4,6\n" +
- "4,6\n" + "4,6\n" + "4,3\n" + "4,4\n" + "4,6\n" + "4,1\n" + "4,4\n" +
- "4,4\n" + "4,5\n" + "4,6\n" + "4,2\n" + "4,3\n" + "4,4\n" + "4,5\n" + "4,6\n"
- val results = t.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithConstant2(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('b, 4 as 'four, 'a)
- .groupBy('b, 'four)
- .select('four, 'a.sum)
-
- val expected = "4,1\n" + "4,5\n" + "4,15\n" + "4,34\n" + "4,65\n" + "4,111\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithExpression(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .groupBy('e, 'b % 3)
- .select('c.min, 'e, 'a.avg, 'd.count)
-
- val expected = "0,1,1,1\n" + "3,2,3,3\n" + "7,1,4,2\n" + "14,2,5,1\n" +
- "5,3,4,2\n" + "2,1,3,2\n" + "1,2,3,3\n" + "12,3,5,1"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('b, 'a.sum)
- .where('b === 2)
-
- val expected = "2,5\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAnalyticAggregation(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val ds = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, BigDecimal.ONE),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, new BigDecimal(2))).toTable(tEnv)
- val res = ds.select(
- '_1.stddevPop, '_2.stddevPop, '_3.stddevPop, '_4.stddevPop, '_5.stddevPop,
- '_6.stddevPop, '_7.stddevPop,
- '_1.stddevSamp, '_2.stddevSamp, '_3.stddevSamp, '_4.stddevSamp, '_5.stddevSamp,
- '_6.stddevSamp, '_7.stddevSamp,
- '_1.varPop, '_2.varPop, '_3.varPop, '_4.varPop, '_5.varPop,
- '_6.varPop, '_7.varPop,
- '_1.varSamp, '_2.varSamp, '_3.varSamp, '_4.varSamp, '_5.varSamp,
- '_6.varSamp, '_7.varSamp)
- val expected =
- "0,0,0," +
- "0,0.5,0.5,0.5," +
- "1,1,1," +
- "1,0.70710677,0.7071067811865476,0.7071067811865476," +
- "0,0,0," +
- "0,0.25,0.25,0.25," +
- "1,1,1," +
- "1,0.5,0.5,0.5"
- val results = res.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
-
-case class WC(word: String, frequency: Long)
[20/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/OverWindowITCase.scala
new file mode 100644
index 0000000..cc47a69
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/OverWindowITCase.scala
@@ -0,0 +1,854 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.sql
+
+import org.apache.flink.api.common.time.Time
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.source.SourceFunction
+import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TimeTestUtil.EventTimeSourceFunction
+import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamTestData, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit._
+
+import scala.collection.mutable
+
+class OverWindowITCase extends StreamingWithStateTestBase {
+
+ val data = List(
+ (1L, 1, "Hello"),
+ (2L, 2, "Hello"),
+ (3L, 3, "Hello"),
+ (4L, 4, "Hello"),
+ (5L, 5, "Hello"),
+ (6L, 6, "Hello"),
+ (7L, 7, "Hello World"),
+ (8L, 8, "Hello World"),
+ (20L, 20, "Hello World"))
+
+ @Test
+ def testProcTimeBoundedPartitionedRowsOver(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
+ tEnv.registerTable("MyTable", t)
+
+ val sqlQuery = "SELECT a, " +
+ " SUM(c) OVER (" +
+ " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW), " +
+ " MIN(c) OVER (" +
+ " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) " +
+ "FROM MyTable"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,0,0",
+ "2,1,1",
+ "2,3,1",
+ "3,3,3",
+ "3,7,3",
+ "3,12,3",
+ "4,6,6",
+ "4,13,6",
+ "4,21,6",
+ "4,30,6",
+ "5,10,10",
+ "5,21,10",
+ "5,33,10",
+ "5,46,10",
+ "5,60,10")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeBoundedNonPartitionedRowsOver(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
+ tEnv.registerTable("MyTable", t)
+
+ val sqlQuery = "SELECT a, " +
+ " SUM(c) OVER (" +
+ " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW), " +
+ " MIN(c) OVER (" +
+ " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) " +
+ "FROM MyTable"
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,0,0",
+ "2,1,0",
+ "2,3,0",
+ "3,6,0",
+ "3,10,0",
+ "3,15,0",
+ "4,21,0",
+ "4,28,0",
+ "4,36,0",
+ "4,45,0",
+ "5,55,0",
+ "5,66,1",
+ "5,77,2",
+ "5,88,3",
+ "5,99,4")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeUnboundedPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ // for sum aggregation ensure that every time the order of each element is consistent
+ env.setParallelism(1)
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
+ "sum(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) " +
+ "from T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello World,1,7", "Hello World,2,15", "Hello World,3,35",
+ "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeUnboundedPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT c, cnt1 from " +
+ "(SELECT " +
+ "c, " +
+ "count(a) " +
+ " OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
+ "as cnt1 from T1)"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello World,1", "Hello World,2", "Hello World,3",
+ "Hello,1", "Hello,2", "Hello,3", "Hello,4", "Hello,5", "Hello,6")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRangeOver(): Unit = {
+ val queryConfig =
+ new StreamQueryConfig().withIdleStateRetentionTime(Time.hours(2), Time.hours(3))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ // for sum aggregation ensure that every time the order of each element is consistent
+ env.setParallelism(1)
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding), " +
+ "sum(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) " +
+ "from T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row](queryConfig)
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello World,7,28", "Hello World,8,36", "Hello World,9,56",
+ "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "count(a) OVER (ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
+ "from T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("1", "2", "3", "4", "5", "6", "7", "8", "9")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRangeOver(): Unit = {
+ val data = Seq(
+ Left((1500L, (1L, 15, "Hello"))),
+ Left((1600L, (1L, 16, "Hello"))),
+ Left((1000L, (1L, 1, "Hello"))),
+ Left((2000L, (2L, 2, "Hello"))),
+ Right(1000L),
+ Left((2000L, (2L, 2, "Hello"))),
+ Left((2000L, (2L, 3, "Hello"))),
+ Left((3000L, (3L, 3, "Hello"))),
+ Right(2000L),
+ Left((4000L, (4L, 4, "Hello"))),
+ Right(3000L),
+ Left((5000L, (5L, 5, "Hello"))),
+ Right(5000L),
+ Left((6000L, (6L, 6, "Hello"))),
+ Left((6500L, (6L, 65, "Hello"))),
+ Right(7000L),
+ Left((9000L, (6L, 9, "Hello"))),
+ Left((9500L, (6L, 18, "Hello"))),
+ Left((9000L, (6L, 9, "Hello"))),
+ Right(10000L),
+ Left((10000L, (7L, 7, "Hello World"))),
+ Left((11000L, (7L, 17, "Hello World"))),
+ Left((11000L, (7L, 77, "Hello World"))),
+ Right(12000L),
+ Left((14000L, (7L, 18, "Hello World"))),
+ Right(14000L),
+ Left((15000L, (8L, 8, "Hello World"))),
+ Right(17000L),
+ Left((20000L, (20L, 20, "Hello World"))),
+ Right(19000L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ " c, b, " +
+ " COUNT(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
+ " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
+ " SUM(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
+ " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW)" +
+ " FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
+ "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
+ "Hello,3,4,9",
+ "Hello,4,2,7",
+ "Hello,5,2,9",
+ "Hello,6,2,11", "Hello,65,2,12",
+ "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
+ "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
+ "Hello World,8,2,15",
+ "Hello World,20,1,20")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRowsOver(): Unit = {
+ val data = Seq(
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((3L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Right(2L),
+ Left((3L, (3L, 3, "Hello"))),
+ Left((4L, (4L, 4, "Hello"))),
+ Left((5L, (5L, 5, "Hello"))),
+ Left((6L, (6L, 6, "Hello"))),
+ Left((20L, (20L, 20, "Hello World"))),
+ Right(6L),
+ Left((8L, (8L, 8, "Hello World"))),
+ Left((7L, (7L, 7, "Hello World"))),
+ Right(20L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ " c, a, " +
+ " COUNT(a) " +
+ " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), " +
+ " SUM(a) " +
+ " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
+ "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
+ "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
+ "Hello,6,3,15",
+ "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
+ "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRangeOver(): Unit = {
+ val data = Seq(
+ Left((1500L, (1L, 15, "Hello"))),
+ Left((1600L, (1L, 16, "Hello"))),
+ Left((1000L, (1L, 1, "Hello"))),
+ Left((2000L, (2L, 2, "Hello"))),
+ Right(1000L),
+ Left((2000L, (2L, 2, "Hello"))),
+ Left((2000L, (2L, 3, "Hello"))),
+ Left((3000L, (3L, 3, "Hello"))),
+ Right(2000L),
+ Left((4000L, (4L, 4, "Hello"))),
+ Right(3000L),
+ Left((5000L, (5L, 5, "Hello"))),
+ Right(5000L),
+ Left((6000L, (6L, 6, "Hello"))),
+ Left((6500L, (6L, 65, "Hello"))),
+ Right(7000L),
+ Left((9000L, (6L, 9, "Hello"))),
+ Left((9500L, (6L, 18, "Hello"))),
+ Left((9000L, (6L, 9, "Hello"))),
+ Right(10000L),
+ Left((10000L, (7L, 7, "Hello World"))),
+ Left((11000L, (7L, 17, "Hello World"))),
+ Left((11000L, (7L, 77, "Hello World"))),
+ Right(12000L),
+ Left((14000L, (7L, 18, "Hello World"))),
+ Right(14000L),
+ Left((15000L, (8L, 8, "Hello World"))),
+ Right(17000L),
+ Left((20000L, (20L, 20, "Hello World"))),
+ Right(19000L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ " c, b, " +
+ " COUNT(a) " +
+ " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
+ " SUM(a) " +
+ " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW) " +
+ " FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
+ "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
+ "Hello,3,4,9",
+ "Hello,4,2,7",
+ "Hello,5,2,9",
+ "Hello,6,2,11", "Hello,65,2,12",
+ "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
+ "Hello World,7,4,25", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
+ "Hello World,8,2,15",
+ "Hello World,20,1,20")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRowsOver(): Unit = {
+
+ val data = Seq(
+ Left((2L, (2L, 2, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((20L, (20L, 20, "Hello World"))), // early row
+ Right(3L),
+ Left((2L, (2L, 2, "Hello"))), // late row
+ Left((3L, (3L, 3, "Hello"))),
+ Left((4L, (4L, 4, "Hello"))),
+ Left((5L, (5L, 5, "Hello"))),
+ Left((6L, (6L, 6, "Hello"))),
+ Left((7L, (7L, 7, "Hello World"))),
+ Right(7L),
+ Left((9L, (9L, 9, "Hello World"))),
+ Left((8L, (8L, 8, "Hello World"))),
+ Left((8L, (8L, 8, "Hello World"))),
+ Right(20L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env
+ .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT " +
+ "c, a, " +
+ " COUNT(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW), " +
+ " SUM(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW) " +
+ "FROM T1"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
+ "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
+ "Hello,3,3,7",
+ "Hello,4,3,9", "Hello,5,3,12",
+ "Hello,6,3,15", "Hello World,7,3,18",
+ "Hello World,8,3,21", "Hello World,8,3,23",
+ "Hello World,9,3,25",
+ "Hello World,20,3,37")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT a, b, c, " +
+ " SUM(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " COUNT(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " AVG(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MAX(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MIN(b) OVER (" +
+ " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (1, 1L, "Hello")),
+ Left(14000002L, (1, 2L, "Hello")),
+ Left(14000002L, (1, 3L, "Hello world")),
+ Left(14000003L, (2, 2L, "Hello world")),
+ Left(14000003L, (2, 3L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 4L, "Hello world")),
+ Left(14000022L, (1, 5L, "Hello world")),
+ Left(14000022L, (1, 6L, "Hello world")),
+ Left(14000022L, (1, 7L, "Hello world")),
+ Left(14000023L, (2, 4L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000030L))
+
+ val t1 = env
+ .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,1,Hello,6,3,2,3,1",
+ "1,2,Hello,6,3,2,3,1",
+ "1,3,Hello world,6,3,2,3,1",
+ "1,1,Hi,7,4,1,3,1",
+ "2,1,Hello,1,1,1,1,1",
+ "2,2,Hello world,6,3,2,3,1",
+ "2,3,Hello world,6,3,2,3,1",
+ "1,4,Hello world,11,5,2,4,1",
+ "1,5,Hello world,29,8,3,7,1",
+ "1,6,Hello world,29,8,3,7,1",
+ "1,7,Hello world,29,8,3,7,1",
+ "2,4,Hello world,15,5,3,5,1",
+ "2,5,Hello world,15,5,3,5,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val sqlQuery = "SELECT a, b, c, " +
+ "SUM(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "count(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "avg(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "max(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "min(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row) " +
+ "from T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (3, 1L, "Hello")),
+ Left(14000003L, (1, 2L, "Hello")),
+ Left(14000004L, (1, 3L, "Hello world")),
+ Left(14000007L, (3, 2L, "Hello world")),
+ Left(14000008L, (2, 2L, "Hello world")),
+ Right(14000010L),
+ Left(14000012L, (1, 5L, "Hello world")),
+ Left(14000021L, (1, 6L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000020L),
+ Left(14000024L, (3, 5L, "Hello world")),
+ Left(14000026L, (1, 7L, "Hello world")),
+ Left(14000025L, (1, 8L, "Hello world")),
+ Left(14000022L, (1, 9L, "Hello world")),
+ Right(14000030L))
+
+ val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,2,Hello,2,1,2,2,2",
+ "1,3,Hello world,5,2,2,3,2",
+ "1,1,Hi,6,3,2,3,1",
+ "2,1,Hello,1,1,1,1,1",
+ "2,2,Hello world,3,2,1,2,1",
+ "3,1,Hello,1,1,1,1,1",
+ "3,2,Hello world,3,2,1,2,1",
+ "1,5,Hello world,11,4,2,5,1",
+ "1,6,Hello world,17,5,3,6,1",
+ "1,9,Hello world,26,6,4,9,1",
+ "1,8,Hello world,34,7,4,9,1",
+ "1,7,Hello world,41,8,5,9,1",
+ "2,5,Hello world,8,3,2,5,1",
+ "3,5,Hello world,8,3,2,5,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedNonPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT a, b, c, " +
+ " SUM(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " COUNT(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " AVG(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MAX(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MIN(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (1, 1L, "Hello")),
+ Left(14000002L, (1, 2L, "Hello")),
+ Left(14000002L, (1, 3L, "Hello world")),
+ Left(14000003L, (2, 2L, "Hello world")),
+ Left(14000003L, (2, 3L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 4L, "Hello world")),
+ Left(14000022L, (1, 5L, "Hello world")),
+ Left(14000022L, (1, 6L, "Hello world")),
+ Left(14000022L, (1, 7L, "Hello world")),
+ Left(14000023L, (2, 4L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000030L))
+
+ val t1 = env
+ .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "2,1,Hello,1,1,1,1,1",
+ "1,1,Hello,7,4,1,3,1",
+ "1,2,Hello,7,4,1,3,1",
+ "1,3,Hello world,7,4,1,3,1",
+ "2,2,Hello world,12,6,2,3,1",
+ "2,3,Hello world,12,6,2,3,1",
+ "1,1,Hi,13,7,1,3,1",
+ "1,4,Hello world,17,8,2,4,1",
+ "1,5,Hello world,35,11,3,7,1",
+ "1,6,Hello world,35,11,3,7,1",
+ "1,7,Hello world,35,11,3,7,1",
+ "2,4,Hello world,44,13,3,7,1",
+ "2,5,Hello world,44,13,3,7,1")
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedNonPartitionedRowsOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.clear
+ env.setParallelism(1)
+
+ val sqlQuery = "SELECT a, b, c, " +
+ " SUM(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " COUNT(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " AVG(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MAX(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
+ " MIN(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
+ "FROM T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 2L, "Hello")),
+ Left(14000002L, (3, 5L, "Hello")),
+ Left(14000003L, (1, 3L, "Hello")),
+ Left(14000004L, (3, 7L, "Hello world")),
+ Left(14000007L, (4, 9L, "Hello world")),
+ Left(14000008L, (5, 8L, "Hello world")),
+ Right(14000010L),
+ // this element will be discard because it is late
+ Left(14000008L, (6, 8L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (6, 8L, "Hello world")),
+ Right(14000030L)
+ )
+
+ val t1 = env
+ .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "2,2,Hello,2,1,2,2,2",
+ "3,5,Hello,7,2,3,5,2",
+ "1,3,Hello,10,3,3,5,2",
+ "3,7,Hello world,17,4,4,7,2",
+ "1,1,Hi,18,5,3,7,1",
+ "4,9,Hello world,27,6,4,9,1",
+ "5,8,Hello world,35,7,5,9,1",
+ "6,8,Hello world,43,8,5,9,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test sliding event-time unbounded window with partition by **/
+ @Test
+ def testRowTimeUnBoundedPartitionedRowsOver2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.clear
+ env.setParallelism(1)
+
+ val sqlQuery = "SELECT a, b, c, " +
+ "SUM(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "count(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "avg(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "max(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row), " +
+ "min(b) over (" +
+ "partition by a order by rowtime rows between unbounded preceding and current row) " +
+ "from T1"
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (3, 1L, "Hello")),
+ Left(14000003L, (1, 2L, "Hello")),
+ Left(14000004L, (1, 3L, "Hello world")),
+ Left(14000007L, (3, 2L, "Hello world")),
+ Left(14000008L, (2, 2L, "Hello world")),
+ Right(14000010L),
+ // the next 3 elements are late
+ Left(14000008L, (1, 4L, "Hello world")),
+ Left(14000008L, (2, 3L, "Hello world")),
+ Left(14000008L, (3, 3L, "Hello world")),
+ Left(14000012L, (1, 5L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 6L, "Hello world")),
+ // the next 3 elements are late
+ Left(14000019L, (1, 6L, "Hello world")),
+ Left(14000018L, (2, 4L, "Hello world")),
+ Left(14000018L, (3, 4L, "Hello world")),
+ Left(14000022L, (2, 5L, "Hello world")),
+ Left(14000022L, (3, 5L, "Hello world")),
+ Left(14000024L, (1, 7L, "Hello world")),
+ Left(14000023L, (1, 8L, "Hello world")),
+ Left(14000021L, (1, 9L, "Hello world")),
+ Right(14000030L)
+ )
+
+ val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,2,Hello,2,1,2,2,2",
+ "1,3,Hello world,5,2,2,3,2",
+ "1,1,Hi,6,3,2,3,1",
+ "2,1,Hello,1,1,1,1,1",
+ "2,2,Hello world,3,2,1,2,1",
+ "3,1,Hello,1,1,1,1,1",
+ "3,2,Hello world,3,2,1,2,1",
+ "1,5,Hello world,11,4,2,5,1",
+ "1,6,Hello world,17,5,3,6,1",
+ "1,9,Hello world,26,6,4,9,1",
+ "1,8,Hello world,34,7,4,9,1",
+ "1,7,Hello world,41,8,5,9,1",
+ "2,5,Hello world,8,3,2,5,1",
+ "3,5,Hello world,8,3,2,5,1"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
+
+object OverWindowITCase {
+
+ class EventTimeSourceFunction[T](
+ dataWithTimestampList: Seq[Either[(Long, T), Long]]) extends SourceFunction[T] {
+ override def run(ctx: SourceContext[T]): Unit = {
+ dataWithTimestampList.foreach {
+ case Left(t) => ctx.collectWithTimestamp(t._2, t._1)
+ case Right(w) => ctx.emitWatermark(new Watermark(w))
+ }
+ }
+
+ override def cancel(): Unit = ???
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SortITCase.scala
new file mode 100644
index 0000000..2c59f8c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SortITCase.scala
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TimeTestUtil.EventTimeSourceFunction
+import org.apache.flink.table.runtime.stream.sql.SortITCase.StringRowSelectorSink
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit._
+
+import scala.collection.mutable
+
+class SortITCase extends StreamingWithStateTestBase {
+
+ @Test
+ def testEventTimeOrderBy(): Unit = {
+ val data = Seq(
+ Left((1500L, (1L, 15, "Hello"))),
+ Left((1600L, (1L, 16, "Hello"))),
+ Left((1000L, (1L, 1, "Hello"))),
+ Left((2000L, (2L, 2, "Hello"))),
+ Right(1000L),
+ Left((2000L, (2L, 2, "Hello"))),
+ Left((2000L, (2L, 3, "Hello"))),
+ Left((3000L, (3L, 3, "Hello"))),
+ Left((2000L, (3L, 1, "Hello"))),
+ Right(2000L),
+ Left((4000L, (4L, 4, "Hello"))),
+ Right(3000L),
+ Left((5000L, (5L, 5, "Hello"))),
+ Right(5000L),
+ Left((6000L, (6L, 65, "Hello"))),
+ Left((6000L, (6L, 6, "Hello"))),
+ Left((6000L, (6L, 67, "Hello"))),
+ Left((6000L, (6L, -1, "Hello"))),
+ Left((6000L, (6L, 6, "Hello"))),
+ Right(7000L),
+ Left((9000L, (6L, 9, "Hello"))),
+ Left((8500L, (6L, 18, "Hello"))),
+ Left((9000L, (6L, 7, "Hello"))),
+ Right(10000L),
+ Left((10000L, (7L, 7, "Hello World"))),
+ Left((11000L, (7L, 77, "Hello World"))),
+ Left((11000L, (7L, 17, "Hello World"))),
+ Right(12000L),
+ Left((14000L, (7L, 18, "Hello World"))),
+ Right(14000L),
+ Left((15000L, (8L, 8, "Hello World"))),
+ Right(17000L),
+ Left((20000L, (20L, 20, "Hello World"))),
+ Right(19000L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t1 = env.addSource(new EventTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ tEnv.registerTable("T1", t1)
+
+ val sqlQuery = "SELECT b FROM T1 ORDER BY rowtime, b ASC "
+
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StringRowSelectorSink(0)).setParallelism(1)
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1", "15", "16",
+ "1", "2", "2", "3",
+ "3",
+ "4",
+ "5",
+ "-1", "6", "6", "65", "67",
+ "18", "7", "9",
+ "7", "17", "77",
+ "18",
+ "8",
+ "20")
+ assertEquals(expected, SortITCase.testResults)
+ }
+}
+
+object SortITCase {
+
+ final class StringRowSelectorSink(private val field:Int) extends RichSinkFunction[Row]() {
+ def invoke(value: Row) {
+ testResults.synchronized {
+ testResults += value.getField(field).toString
+ }
+ }
+ }
+
+ var testResults: mutable.MutableList[String] = mutable.MutableList.empty[String]
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SqlITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SqlITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SqlITCase.scala
new file mode 100644
index 0000000..d2f9a9a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/SqlITCase.scala
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.sql
+
+import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamTestData, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit._
+
+class SqlITCase extends StreamingWithStateTestBase {
+
+ /** test row stream registered table **/
+ @Test
+ def testRowRegister(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM MyTableRow WHERE c < 3"
+
+ val data = List(
+ Row.of("Hello", "Worlds", Int.box(1)),
+ Row.of("Hello", "Hiden", Int.box(5)),
+ Row.of("Hello again", "Worlds", Int.box(2)))
+
+ implicit val tpe: TypeInformation[Row] = new RowTypeInfo(
+ BasicTypeInfo.STRING_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO,
+ BasicTypeInfo.INT_TYPE_INFO) // tpe is automatically
+
+ val ds = env.fromCollection(data)
+
+ val t = ds.toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTableRow", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("Hello,Worlds,1","Hello again,Worlds,2")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test unbounded groupBy (without window) **/
+ @Test
+ def testUnboundedGroupBy(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT b, COUNT(a) FROM MyTable GROUP BY b"
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toRetractStream[Row]
+ result.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = List("1,1", "2,2", "3,3", "4,4", "5,5", "6,6")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ /** test selection **/
+ @Test
+ def testSelectExpressionFromTable(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT a * 2, b - 1 FROM MyTable"
+
+ val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("2,0", "4,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test filtering with registered table **/
+ @Test
+ def testSimpleFilter(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE a = 3"
+
+ val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test filtering with registered datastream **/
+ @Test
+ def testDatastreamFilter(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE _1 = 3"
+
+ val t = StreamTestData.getSmall3TupleDataStream(env)
+ tEnv.registerDataStream("MyTable", t)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test union with registered tables **/
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM T1 " +
+ "UNION ALL " +
+ "SELECT * FROM T2"
+
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T1", t1)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T2", t2)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,1,Hi", "1,1,Hi",
+ "2,2,Hello", "2,2,Hello",
+ "3,2,Hello world", "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test union with filter **/
+ @Test
+ def testUnionWithFilter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT * FROM T1 WHERE a = 3 " +
+ "UNION ALL " +
+ "SELECT * FROM T2 WHERE a = 2"
+
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T1", t1)
+ val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T2", t2)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ /** test union of a table and a datastream **/
+ @Test
+ def testUnionTableWithDataSet(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val sqlQuery = "SELECT c FROM T1 WHERE a = 3 " +
+ "UNION ALL " +
+ "SELECT c FROM T2 WHERE a = 2"
+
+ val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("T1", t1)
+ val t2 = StreamTestData.get3TupleDataStream(env)
+ tEnv.registerDataStream("T2", t2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List("Hello", "Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnnestPrimitiveArrayFromTable(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val data = List(
+ (1, Array(12, 45), Array(Array(12, 45))),
+ (2, Array(41, 5), Array(Array(18), Array(87))),
+ (3, Array(18, 42), Array(Array(1), Array(45)))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, b, s FROM T, UNNEST(T.b) AS A (s)"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,[12, 45],12",
+ "1,[12, 45],45",
+ "2,[41, 5],41",
+ "2,[41, 5],5",
+ "3,[18, 42],18",
+ "3,[18, 42],42"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnnestArrayOfArrayFromTable(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val data = List(
+ (1, Array(12, 45), Array(Array(12, 45))),
+ (2, Array(41, 5), Array(Array(18), Array(87))),
+ (3, Array(18, 42), Array(Array(1), Array(45)))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) AS A (s)"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "1,[12, 45]",
+ "2,[18]",
+ "2,[87]",
+ "3,[1]",
+ "3,[45]")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnnestObjectArrayFromTableWithFilter(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val data = List(
+ (1, Array((12, "45.6"), (12, "45.612"))),
+ (2, Array((13, "41.6"), (14, "45.2136"))),
+ (3, Array((18, "42.6")))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataStream("T", stream, 'a, 'b)
+
+ val sqlQuery = "SELECT a, b, s, t FROM T, UNNEST(T.b) AS A (s, t) WHERE s > 13"
+
+ val result = tEnv.sql(sqlQuery).toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = List(
+ "2,[(13,41.6), (14,45.2136)],14,45.2136",
+ "3,[(18,42.6)],18,42.6")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/TableSourceITCase.scala
new file mode 100644
index 0000000..be876a8
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/sql/TableSourceITCase.scala
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.{CommonTestData, StreamITCase}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class TableSourceITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testCsvTableSource(): Unit = {
+
+ val csvTable = CommonTestData.getCsvTableSource
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ tEnv.registerTableSource("persons", csvTable)
+
+ tEnv.sql(
+ "SELECT id, `first`, `last`, score FROM persons WHERE id < 4 ")
+ .toAppendStream[Row]
+ .addSink(new StreamITCase.StringSink[Row])
+
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,Mike,Smith,12.3",
+ "2,Bob,Taylor,45.6",
+ "3,Sam,Miller,7.89")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/AggregateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/AggregateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/AggregateITCase.scala
new file mode 100644
index 0000000..744ac46
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/AggregateITCase.scala
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import org.apache.flink.api.common.time.Time
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.StreamITCase.RetractingSink
+import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamTestData, StreamingWithStateTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+import scala.collection.mutable
+
+/**
+ * Tests of groupby (without window) aggregations
+ */
+class AggregateITCase extends StreamingWithStateTestBase {
+ private val queryConfig = new StreamQueryConfig()
+ queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
+
+
+ @Test
+ def testDistinct(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('b).distinct()
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = mutable.MutableList("1", "2", "3", "4", "5", "6")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testDistinctAfterAggregate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .groupBy('e).select('e, 'a.count).distinct()
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = mutable.MutableList("1,5", "2,7", "3,3")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testNonKeyedGroupAggregate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a.sum, 'b.sum)
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = List("231,91")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testGroupAggregate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('b, 'a.sum)
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = List("1,1", "2,5", "3,15", "4,34", "5,65", "6,111")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testDoubleGroupAggregation(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('a.count as 'cnt, 'b)
+ .groupBy('cnt)
+ .select('cnt, 'b.count as 'freq)
+
+ val results = t.toRetractStream[Row](queryConfig)
+
+ results.addSink(new RetractingSink)
+ env.execute()
+ val expected = List("1,1", "2,1", "3,1", "4,1", "5,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ @Test
+ def testGroupAggregateWithExpression(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .groupBy('e, 'b % 3)
+ .select('c.min, 'e, 'a.avg, 'd.count)
+
+ val results = t.toRetractStream[Row](queryConfig)
+ results.addSink(new RetractingSink)
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "0,1,1,1", "7,1,4,2", "2,1,3,2",
+ "3,2,3,3", "1,2,3,3", "14,2,5,1",
+ "12,3,5,1", "5,3,4,2")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CalcITCase.scala
new file mode 100644
index 0000000..c62349c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CalcITCase.scala
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.expressions.utils.{Func13, RichFunc1, RichFunc2}
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamTestData}
+import org.apache.flink.table.runtime.utils.UserDefinedFunctionTestUtils
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class CalcITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testSimpleSelectAll(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1, '_2, '_3)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hi",
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSelectFirst(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("1", "2", "3")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSimpleSelectWithNaming(): Unit = {
+
+ // verify ProjectMergeRule.
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv)
+ .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
+ .select('a, 'b)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1", "2,2", "3,2", "4,3", "5,3", "6,3", "7,4",
+ "8,4", "9,4", "10,4", "11,5", "12,5", "13,5", "14,5", "15,5",
+ "16,6", "17,6", "18,6", "19,6", "20,6", "21,6")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSimpleSelectAllWithAs(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a, 'b, 'c)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hi",
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testSimpleFilter(): Unit = {
+ /*
+ * Test simple filter
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter('a === 3)
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+ /*
+ * Test all-rejecting filter
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(false) )
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ assertEquals(true, StreamITCase.testResults.isEmpty)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+ /*
+ * Test all-passing filter
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(true) )
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hi",
+ "2,2,Hello",
+ "3,2,Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testFilterOnIntegerTupleField(): Unit = {
+ /*
+ * Test filter on Integer tuple field.
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 === 0 )
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "2,2,Hello", "4,3,Hello world, how are you?",
+ "6,3,Luke Skywalker", "8,4,Comment#2", "10,4,Comment#4",
+ "12,5,Comment#6", "14,5,Comment#8", "16,6,Comment#10",
+ "18,6,Comment#12", "20,6,Comment#14")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testNotEquals(): Unit = {
+ /*
+ * Test filter on Integer tuple field.
+ */
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 !== 0)
+ val results = filterDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+ val expected = mutable.MutableList(
+ "1,1,Hi", "3,2,Hello world",
+ "5,3,I am fine.", "7,4,Comment#1", "9,4,Comment#3",
+ "11,5,Comment#5", "13,5,Comment#7", "15,5,Comment#9",
+ "17,6,Comment#11", "19,6,Comment#13", "21,6,Comment#15")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedFunctionWithParameter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
+
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.get3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .where("RichFunc2(c)='ABC#Hello'")
+ .select('c)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Hello")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testMultipleUserDefinedFunctions(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc1", new RichFunc1)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
+
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.get3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .where("RichFunc2(c)='Abc#Hello' || RichFunc1(a)=3 && b=2")
+ .select('c)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Hello", "Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testScalarFunctionConstructorWithParams(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+
+ val testData = new mutable.MutableList[(Int, Long, String)]
+ testData.+=((1, 1L, "Jack#22"))
+ testData.+=((2, 2L, "John#19"))
+ testData.+=((3, 2L, "Anna#44"))
+ testData.+=((4, 3L, "nosharp"))
+
+ val t = env.fromCollection(testData).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new Func13("default")
+ val func1 = new Func13("Sunny")
+ val func2 = new Func13("kevin2")
+
+ val result = t.select(func0('c), func1('c),func2('c))
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44",
+ "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22",
+ "default-John#19,Sunny-John#19,kevin2-John#19",
+ "default-nosharp,Sunny-nosharp,kevin2-nosharp"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CorrelateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CorrelateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CorrelateITCase.scala
new file mode 100644
index 0000000..3f96253
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/stream/table/CorrelateITCase.scala
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.runtime.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils.{Func18, RichFunc2}
+import org.apache.flink.table.runtime.utils.{StreamITCase, StreamTestData}
+import org.apache.flink.table.runtime.utils._
+import org.apache.flink.table.utils._
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.{Before, Test}
+
+import scala.collection.mutable
+
+class CorrelateITCase extends StreamingMultipleProgramsTestBase {
+
+ val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv: StreamTableEnvironment = TableEnvironment.getTableEnvironment(env)
+
+ @Before
+ def clear(): Unit = {
+ StreamITCase.clear
+ }
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+ val pojoFunc0 = new PojoTableFunc()
+
+ val result = t
+ .join(func0('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .join(pojoFunc0('c))
+ .where('age > 20)
+ .select('c, 'name, 'age)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Jack#22,Jack,22", "Anna#44,Anna,44")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = t
+ .leftOuterJoin(func0('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "nosharp,null,null", "Jack#22,Jack,22",
+ "John#19,John,19", "Anna#44,Anna,44")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = t
+ .join(func0('c) as('d, 'e))
+ .where(Func18('d, "J"))
+ .select('c, 'd, 'e)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Jack#22,Jack,22", "John#19,John,19")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithParameter(): Unit = {
+ val tableFunc1 = new RichTableFunc1
+ tEnv.registerFunction("RichTableFunc1", tableFunc1)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> " "))
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.getSmall3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(tableFunc1('c) as 's)
+ .select('a, 's)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("3,Hello", "3,world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithUserDefinedScalarFunction(): Unit = {
+ val tableFunc1 = new RichTableFunc1
+ val richFunc2 = new RichFunc2
+ tEnv.registerFunction("RichTableFunc1", tableFunc1)
+ tEnv.registerFunction("RichFunc2", richFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(
+ env,
+ Map("word_separator" -> "#", "string.value" -> "test"))
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.getSmall3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(tableFunc1(richFunc2('c)) as 's)
+ .select('a, 's)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,Hi",
+ "1,test",
+ "2,Hello",
+ "2,test",
+ "3,Hello world",
+ "3,test")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testTableFunctionConstructorWithParams(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val config = Map("key1" -> "value1", "key2" -> "value2")
+ val func30 = new TableFunc3(null)
+ val func31 = new TableFunc3("OneConf_")
+ val func32 = new TableFunc3("TwoConf_", config)
+
+ val result = t
+ .join(func30('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .join(func31('c) as ('f, 'g))
+ .select('c, 'd, 'e, 'f, 'g)
+ .join(func32('c) as ('h, 'i))
+ .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Anna#44,Anna,OneConf_Anna,TwoConf__key=key1_value=value1_Anna,44,44,44",
+ "Anna#44,Anna,OneConf_Anna,TwoConf__key=key2_value=value2_Anna,44,44,44",
+ "Jack#22,Jack,OneConf_Jack,TwoConf__key=key1_value=value1_Jack,22,22,22",
+ "Jack#22,Jack,OneConf_Jack,TwoConf__key=key2_value=value2_Jack,22,22,22",
+ "John#19,John,OneConf_John,TwoConf__key=key1_value=value1_John,19,19,19",
+ "John#19,John,OneConf_John,TwoConf__key=key2_value=value2_John,19,19,19"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testTableFunctionWithVariableArguments(): Unit = {
+ val varArgsFunc0 = new VarArgsFunc0
+ tEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
+
+ val result = testData(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .select('c)
+ .join(varArgsFunc0("1", "2", 'c))
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Anna#44,1",
+ "Anna#44,2",
+ "Anna#44,Anna#44",
+ "Jack#22,1",
+ "Jack#22,2",
+ "Jack#22,Jack#22",
+ "John#19,1",
+ "John#19,2",
+ "John#19,John#19",
+ "nosharp,1",
+ "nosharp,2",
+ "nosharp,nosharp")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ private def testData(
+ env: StreamExecutionEnvironment)
+ : DataStream[(Int, Long, String)] = {
+
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Jack#22"))
+ data.+=((2, 2L, "John#19"))
+ data.+=((3, 2L, "Anna#44"))
+ data.+=((4, 3L, "nosharp"))
+ env.fromCollection(data)
+ }
+
+}
[40/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/JoinStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/JoinStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/JoinStringExpressionTest.scala
new file mode 100644
index 0000000..2302cb9
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/JoinStringExpressionTest.scala
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.utils.TableTestBase
+import org.junit._
+
+class JoinStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testJoin(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1Scala = ds1.join(ds2).where('b === 'e).select('c, 'g)
+ val t1Java = ds1.join(ds2).where("b === e").select("c, g")
+
+ verifyTableEquals(t1Scala, t1Java)
+ }
+
+ @Test
+ def testJoinWithFilter(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1Scala = ds1.join(ds2).where('b === 'e && 'b < 2).select('c, 'g)
+ val t1Java = ds1.join(ds2).where("b === e && b < 2").select("c, g")
+
+ verifyTableEquals(t1Scala, t1Java)
+ }
+
+ @Test
+ def testJoinWithJoinFilter(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1Scala = ds1.join(ds2).where('b === 'e && 'a < 6 && 'h < 'b).select('c, 'g)
+ val t1Java = ds1.join(ds2).where("b === e && a < 6 && h < b").select("c, g")
+
+ verifyTableEquals(t1Scala, t1Java)
+ }
+
+ @Test
+ def testJoinWithMultipleKeys(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1Scala = ds1.join(ds2).filter('a === 'd && 'b === 'h).select('c, 'g)
+ val t1Java = ds1.join(ds2).filter("a === d && b === h").select("c, g")
+
+ verifyTableEquals(t1Scala, t1Java)
+ }
+
+ @Test
+ def testJoinWithAggregation(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1Scala = ds1.join(ds2).where('a === 'd).select('g.count)
+ val t1Java = ds1.join(ds2).where("a === d").select("g.count")
+
+ verifyTableEquals(t1Scala, t1Java)
+ }
+
+ @Test
+ def testJoinWithGroupedAggregation(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.join(ds2)
+ .where('a === 'd)
+ .groupBy('a, 'd)
+ .select('b.sum, 'g.count)
+ val t2 = ds1.join(ds2)
+ .where("a = d")
+ .groupBy("a, d")
+ .select("b.sum, g.count")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testJoinPushThroughJoin(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds3 = util.addTable[(Int, Long, String)]("Table4",'j, 'k, 'l)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.join(ds2)
+ .where(Literal(true))
+ .join(ds3)
+ .where('a === 'd && 'e === 'k)
+ .select('a, 'f, 'l)
+ val t2 = ds1.join(ds2)
+ .where("true")
+ .join(ds3)
+ .where("a === d && e === k")
+ .select("a, f, l")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testJoinWithDisjunctivePred(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.join(ds2).filter('a === 'd && ('b === 'e || 'b === 'e - 10)).select('c, 'g)
+ val t2 = ds1.join(ds2).filter("a = d && (b = e || b = e - 10)").select("c, g")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testJoinWithExpressionPreds(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.join(ds2).filter('b === 'h + 1 && 'a - 1 === 'd + 2).select('c, 'g)
+ val t2 = ds1.join(ds2).filter("b = h + 1 && a - 1 = d + 2").select("c, g")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testLeftJoinWithMultipleKeys(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.leftOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+ val t2 = ds1.leftOuterJoin(ds2, "a = d && b = h").select("c, g")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testRightJoinWithMultipleKeys(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.rightOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+ val t2 = ds1.rightOuterJoin(ds2, "a = d && b = h").select("c, g")
+
+ verifyTableEquals(t1, t2)
+ }
+
+ @Test
+ def testFullOuterJoinWithMultipleKeys(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ val t1 = ds1.fullOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+ val t2 = ds1.fullOuterJoin(ds2, "a = d && b = h").select("c, g")
+
+ verifyTableEquals(t1, t2)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/AggregateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/AggregateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/AggregateValidationTest.scala
new file mode 100644
index 0000000..57d5488
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/AggregateValidationTest.scala
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMergeAndReset
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit._
+
+class AggregateValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testNonWorkingAggregationDataTypes(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(String, Int)]("Table2")
+
+ // Must fail. Field '_1 is not a numeric type.
+ t.select('_1.sum)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testNoNestedAggregations(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(String, Int)]("Table2")
+
+ // Must fail. Sum aggregation can not be chained.
+ t.select('_2.sum.sum)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupingOnNonExistentField(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ // must fail. '_foo not a valid field
+ t.groupBy('_foo).select('a.avg)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupingInvalidSelection(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ t.groupBy('a, 'b)
+ // must fail. 'c is not a grouping key or aggregation
+ .select('c)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testAggregationOnNonExistingField(): Unit = {
+
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ // Must fail. Field 'foo does not exist.
+ t.select('foo.avg)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testInvalidUdAggArgs() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val myWeightedAvg = new WeightedAvgWithMergeAndReset
+
+ // must fail. UDAGG does not accept String type
+ t.select(myWeightedAvg('c, 'a))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testGroupingInvalidUdAggArgs() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val myWeightedAvg = new WeightedAvgWithMergeAndReset
+
+ t.groupBy('b)
+ // must fail. UDAGG does not accept String type
+ .select(myWeightedAvg('c, 'a))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testGroupingNestedUdAgg() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val myWeightedAvg = new WeightedAvgWithMergeAndReset
+
+ t.groupBy('c)
+ // must fail. UDAGG does not accept String type
+ .select(myWeightedAvg(myWeightedAvg('b, 'a), 'a))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testAggregationOnNonExistingFieldJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ t.select("foo.avg")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testNonWorkingAggregationDataTypesJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2",'b, 'c)
+ // Must fail. Cannot compute SUM aggregate on String field.
+ t.select("c.sum")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testNoNestedAggregationsJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2",'b, 'c)
+ // Must fail. Aggregation on aggregation not allowed.
+ t.select("b.sum.sum")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testGroupingOnNonExistentFieldJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ // must fail. Field foo is not in input
+ t.groupBy("foo")
+ .select("a.avg")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testGroupingInvalidSelectionJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ t.groupBy("a, b")
+ // must fail. Field c is not a grouping key or aggregation
+ .select("c")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testUnknownUdAggJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ // must fail. unknown is not known
+ t.select("unknown(c)")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testGroupingUnknownUdAggJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ t.groupBy("a, b")
+ // must fail. unknown is not known
+ .select("unknown(c)")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testInvalidUdAggArgsJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val myWeightedAvg = new WeightedAvgWithMergeAndReset
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+
+ // must fail. UDAGG does not accept String type
+ t.select("myWeightedAvg(c, a)")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ @throws[Exception]
+ def testGroupingInvalidUdAggArgsJava() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ val myWeightedAvg = new WeightedAvgWithMergeAndReset
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+
+ t.groupBy("b")
+ // must fail. UDAGG does not accept String type
+ .select("myWeightedAvg(c, a)")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/CalcValidationTest.scala
new file mode 100644
index 0000000..b37339a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/CalcValidationTest.scala
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit._
+
+class CalcValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testSelectInvalidFieldFields(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ // must fail. Field 'foo does not exist
+ .select('a, 'foo)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSelectAmbiguousRenaming(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ // must fail. 'a and 'b are both renamed to 'foo
+ .select('a + 1 as 'foo, 'b + 2 as 'foo).toDataSet[Row].print()
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSelectAmbiguousRenaming2(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ // must fail. 'a and 'b are both renamed to 'a
+ .select('a, 'b as 'a).toDataSet[Row].print()
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFilterInvalidFieldName(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ // must fail. Field 'foo does not exist
+ t.filter( 'foo === 2 )
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSelectInvalidField() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ // Must fail. Field foo does not exist
+ t.select("a + 1, foo + 2")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSelectAmbiguousFieldNames() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ // Must fail. Field foo does not exist
+ t.select("a + 1 as foo, b + 2 as foo")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFilterInvalidField() {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ // Must fail. Field foo does not exist.
+ t.filter("foo = 17")
+ }
+
+ @Test
+ def testAliasStarException(): Unit = {
+ val util = batchTestUtil()
+
+ try {
+ util.addTable[(Int, Long, String)]("Table1", '*, 'b, 'c)
+ fail("TableException expected")
+ } catch {
+ case _: TableException => //ignore
+ }
+
+ try {
+ util.addTable[(Int, Long, String)]("Table2")
+ .select('_1 as '*, '_2 as 'b, '_1 as 'c)
+ fail("ValidationException expected")
+ } catch {
+ case _: ValidationException => //ignore
+ }
+
+ try {
+ util.addTable[(Int, Long, String)]("Table3").as('*, 'b, 'c)
+ fail("ValidationException expected")
+ } catch {
+ case _: ValidationException => //ignore
+ }
+ try {
+ util.addTable[(Int, Long, String)]("Table4", 'a, 'b, 'c).select('*, 'b)
+ fail("ValidationException expected")
+ } catch {
+ case _: ValidationException => //ignore
+ }
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testDuplicateFlattening(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
+
+ table.select('a.flatten(), 'a.flatten())
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/GroupWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/GroupWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/GroupWindowValidationTest.scala
new file mode 100644
index 0000000..7cf1b82
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/GroupWindowValidationTest.scala
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMerge
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowValidationTest extends TableTestBase {
+
+ //===============================================================================================
+ // Common test
+ //===============================================================================================
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupByWithoutWindowAlias(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidRowTimeRef(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
+ .groupBy('w2)
+ .select('string)
+ }
+
+ //===============================================================================================
+ // Tumbling Windows
+ //===============================================================================================
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidProcessingTimeDefinition(): Unit = {
+ val util = batchTestUtil()
+ // proctime is not allowed
+ util.addTable[(Long, Int, String)]('long.proctime, 'int, 'string)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidProcessingTimeDefinition2(): Unit = {
+ val util = batchTestUtil()
+ // proctime is not allowed
+ util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidEventTimeDefinition(): Unit = {
+ val util = batchTestUtil()
+ // definition must not extend schema
+ util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Tumble over 2.minutes on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testAllTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Tumble over 2.minutes on 'rowtime as 'w)
+ .groupBy('w)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ //===============================================================================================
+ // Sliding Windows
+ //===============================================================================================
+
+ @Test(expected = classOf[ValidationException])
+ def testSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Slide over 2.minutes every 1.minute on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testAllSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Slide over 2.minutes every 1.minute on 'long as 'w)
+ .groupBy('w)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Session withGap 2.minutes on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testAllSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Session withGap 2.minutes on 'rowtime as 'w)
+ .groupBy('w)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/JoinValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/JoinValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/JoinValidationTest.scala
new file mode 100644
index 0000000..3cc278b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/JoinValidationTest.scala
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, TableException, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit._
+
+class JoinValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinNonExistingKey(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.join(ds2)
+ // must fail. Field 'foo does not exist
+ .where('foo === 'e)
+ .select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinWithNonMatchingKeyTypes(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.join(ds2)
+ // must fail. Field 'a is Int, and 'g is String
+ .where('a === 'g)
+ .select('c, 'g)
+
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinWithAmbiguousFields(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
+
+ ds1.join(ds2)
+ // must fail. Both inputs share the same field 'c
+ .where('a === 'd)
+ .select('c, 'g)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testNoEqualityJoinPredicate1(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.join(ds2)
+ // must fail. No equality join predicate
+ .where('d === 'f)
+ .select('c, 'g)
+ .toDataSet[Row]
+ }
+
+ @Test(expected = classOf[TableException])
+ def testNoEqualityJoinPredicate2(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.join(ds2)
+ // must fail. No equality join predicate
+ .where('a < 'd)
+ .select('c, 'g)
+ .toDataSet[Row]
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testNoJoinCondition(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds2.leftOuterJoin(ds1, 'b === 'd && 'b < 3).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testNoEquiJoin(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds2.leftOuterJoin(ds1, 'b < 'd).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testRightJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testLeftJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFullJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testRightJoinWithLocalPredicate(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testLeftJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFullJoinWithNonEquiJoinPredicate(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
+ ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinTablesFromDifferentEnvs(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ val in1 = tEnv1.fromDataSet(ds1, 'a, 'b, 'c)
+ val in2 = tEnv2.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'c)
+
+ // Must fail. Tables are bound to different TableEnvironments.
+ in1.join(in2).where('b === 'e).select('c, 'g)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testJoinTablesFromDifferentEnvsJava() {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ val in1 = tEnv1.fromDataSet(ds1, 'a, 'b, 'c)
+ val in2 = tEnv2.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'c)
+ // Must fail. Tables are bound to different TableEnvironments.
+ in1.join(in2).where("a === d").select("g.count")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/OverWindowValidationTest.scala
new file mode 100644
index 0000000..df8f7df
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/OverWindowValidationTest.scala
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.OverAgg0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit._
+
+class OverWindowValidationTest extends TableTestBase {
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
+ val overAgg = new OverAgg0
+ t.select('c.count, overAgg('b, 'a))
+ }
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation2(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+ val overAgg = new OverAgg0
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('string,'w)
+ .select(overAgg('long, 'int))
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SetOperatorsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SetOperatorsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SetOperatorsValidationTest.scala
new file mode 100644
index 0000000..814298a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SetOperatorsValidationTest.scala
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit._
+
+class SetOperatorsValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionDifferentColumnSize(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'd, 'c, 'e)
+
+ // must fail. Union inputs have different column size.
+ ds1.unionAll(ds2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionDifferentFieldTypes(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
+ .select('a, 'b, 'c)
+
+ // must fail. Union inputs have different field types.
+ ds1.unionAll(ds2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionTablesFromDifferentEnvs(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv1, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv2, 'a, 'b, 'c)
+
+ // Must fail. Tables are bound to different TableEnvironments.
+ ds1.unionAll(ds2).select('c)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMinusDifferentFieldTypes(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
+ .select('a, 'b, 'c)
+
+ // must fail. Minus inputs have different field types.
+ ds1.minus(ds2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMinusAllTablesFromDifferentEnvs(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv1, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv2, 'a, 'b, 'c)
+
+ // Must fail. Tables are bound to different TableEnvironments.
+ ds1.minusAll(ds2).select('c)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testIntersectWithDifferentFieldTypes(): Unit = {
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
+ .select('a, 'b, 'c)
+
+ // must fail. Intersect inputs have different field types.
+ ds1.intersect(ds2)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testIntersectTablesFromDifferentEnvs(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv1, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv2, 'a, 'b, 'c)
+
+ // Must fail. Tables are bound to different TableEnvironments.
+ ds1.intersect(ds2).select('c)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SortValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SortValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SortValidationTest.scala
new file mode 100644
index 0000000..5064687
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/table/validation/SortValidationTest.scala
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit._
+
+class SortValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testFetchWithoutOrder(): Unit = {
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ ds.limit(0, 5)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala
deleted file mode 100644
index f492995..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch
-
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo._
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.{GenericTypeInfo, RowTypeInfo, TupleTypeInfo, TypeExtractor}
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.{Alias, UnresolvedFieldReference}
-import org.apache.flink.table.runtime.types.CRowTypeInfo
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{MockTableEnvironment, TableTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-class TableEnvironmentTest extends TableTestBase {
-
- val tEnv = new MockTableEnvironment
-
- val tupleType = new TupleTypeInfo(
- INT_TYPE_INFO,
- STRING_TYPE_INFO,
- DOUBLE_TYPE_INFO)
-
- val rowType = new RowTypeInfo(INT_TYPE_INFO, STRING_TYPE_INFO,DOUBLE_TYPE_INFO)
-
- val cRowType = new CRowTypeInfo(rowType)
-
- val caseClassType: TypeInformation[CClass] = implicitly[TypeInformation[CClass]]
-
- val pojoType: TypeInformation[PojoClass] = TypeExtractor.createTypeInfo(classOf[PojoClass])
-
- val atomicType = INT_TYPE_INFO
-
- val genericRowType = new GenericTypeInfo[Row](classOf[Row])
-
- @Test
- def testGetFieldInfoRow(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(rowType)
-
- fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoRowNames(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- rowType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoTuple(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(tupleType)
-
- fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoCClass(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(caseClassType)
-
- fieldInfo._1.zip(Array("cf1", "cf2", "cf3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoPojo(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(pojoType)
-
- fieldInfo._1.zip(Array("pf1", "pf2", "pf3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoAtomic(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(atomicType)
-
- fieldInfo._1.zip(Array("f0")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoTupleNames(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- tupleType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoCClassNames(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- caseClassType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoPojoNames2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- pojoType,
- Array(
- UnresolvedFieldReference("pf3"),
- UnresolvedFieldReference("pf1"),
- UnresolvedFieldReference("pf2")
- ))
-
- fieldInfo._1.zip(Array("pf3", "pf1", "pf2")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoAtomicName1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- atomicType,
- Array(UnresolvedFieldReference("name")))
-
- fieldInfo._1.zip(Array("name")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoTupleAlias1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- tupleType,
- Array(
- Alias(UnresolvedFieldReference("f0"), "name1"),
- Alias(UnresolvedFieldReference("f1"), "name2"),
- Alias(UnresolvedFieldReference("f2"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoTupleAlias2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- tupleType,
- Array(
- Alias(UnresolvedFieldReference("f2"), "name1"),
- Alias(UnresolvedFieldReference("f0"), "name2"),
- Alias(UnresolvedFieldReference("f1"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoCClassAlias1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- caseClassType,
- Array(
- Alias(UnresolvedFieldReference("cf1"), "name1"),
- Alias(UnresolvedFieldReference("cf2"), "name2"),
- Alias(UnresolvedFieldReference("cf3"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoCClassAlias2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- caseClassType,
- Array(
- Alias(UnresolvedFieldReference("cf3"), "name1"),
- Alias(UnresolvedFieldReference("cf1"), "name2"),
- Alias(UnresolvedFieldReference("cf2"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoPojoAlias1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- pojoType,
- Array(
- Alias(UnresolvedFieldReference("pf1"), "name1"),
- Alias(UnresolvedFieldReference("pf2"), "name2"),
- Alias(UnresolvedFieldReference("pf3"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoPojoAlias2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- pojoType,
- Array(
- Alias(UnresolvedFieldReference("pf3"), "name1"),
- Alias(UnresolvedFieldReference("pf1"), "name2"),
- Alias(UnresolvedFieldReference("pf2"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testSqlWithoutRegisteringForBatchTables(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
-
- val sqlTable = util.tableEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a, b, c"),
- term("where", ">(b, 12)"))
-
- util.verifyTable(sqlTable, expected)
-
- val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
-
- val sqlTable2 = util.tableEnv.sql(s"SELECT d, e, f FROM $table, $table2 WHERE c = d")
-
- val join = unaryNode(
- "DataSetJoin",
- binaryNode(
- "DataSetCalc",
- batchTableNode(0),
- batchTableNode(1),
- term("select", "c")),
- term("where", "=(c, d)"),
- term("join", "c, d, e, f"),
- term("joinType", "InnerJoin"))
-
- val expected2 = unaryNode(
- "DataSetCalc",
- join,
- term("select", "d, e, f"))
-
- util.verifyTable(sqlTable2, expected2)
- }
-
- @Test
- def testSqlWithoutRegisteringForStreamTables(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
-
- val sqlTable = util.tableEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a, b, c"),
- term("where", ">(b, 12)"))
-
- util.verifyTable(sqlTable, expected)
-
- val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
-
- val sqlTable2 = util.tableEnv.sql(s"SELECT d, e, f FROM $table2 " +
- s"UNION ALL SELECT a, b, c FROM $table")
-
- val expected2 = binaryNode(
- "DataStreamUnion",
- streamTableNode(1),
- streamTableNode(0),
- term("union all", "d, e, f"))
-
- util.verifyTable(sqlTable2, expected2)
- }
-
-}
-
-case class CClass(cf1: Int, cf2: String, cf3: Double)
-
-class PojoClass(var pf1: Int, var pf2: String, var pf3: Double) {
- def this() = this(0, "", 0.0)
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala
deleted file mode 100644
index 57e32ad..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Assert.{assertEquals, assertTrue}
-import org.junit.Test
-
-class TableSchemaTest extends TableTestBase {
-
- @Test
- def testBatchTableSchema(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
- val schema = table.getSchema
-
- assertEquals("a", schema.getColumnNames.apply(0))
- assertEquals("b", schema.getColumnNames.apply(1))
-
- assertEquals(Types.INT, schema.getTypes.apply(0))
- assertEquals(Types.STRING, schema.getTypes.apply(1))
-
- val expectedString = "root\n" +
- " |-- a: Integer\n" +
- " |-- b: String\n"
- assertEquals(expectedString, schema.toString)
-
- assertTrue(schema.getColumnName(3).isEmpty)
- assertTrue(schema.getType(-1).isEmpty)
- assertTrue(schema.getType("c").isEmpty)
- }
-
- @Test
- def testStreamTableSchema(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
- val schema = table.getSchema
-
- assertEquals("a", schema.getColumnNames.apply(0))
- assertEquals("b", schema.getColumnNames.apply(1))
-
- assertEquals(Types.INT, schema.getTypes.apply(0))
- assertEquals(Types.STRING, schema.getTypes.apply(1))
-
- val expectedString = "root\n" +
- " |-- a: Integer\n" +
- " |-- b: String\n"
- assertEquals(expectedString, schema.toString)
-
- assertTrue(schema.getColumnName(3).isEmpty)
- assertTrue(schema.getType(-1).isEmpty)
- assertTrue(schema.getType("c").isEmpty)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala
deleted file mode 100644
index b987e40..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for testing aggregate plans.
- */
-class AggregationsTest extends TableTestBase {
-
- @Test
- def testAggregate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable"
-
- val setValues = unaryNode(
- "DataSetValues",
- batchTableNode(0),
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- util.verifySql(sqlQuery, aggregate)
- }
-
- @Test
- def testAggregateWithFilter(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1"
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", "=(a, 1)")
- )
-
- val setValues = unaryNode(
- "DataSetValues",
- calcNode,
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
-
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- util.verifySql(sqlQuery, aggregate)
- }
-
- @Test
- def testGroupAggregate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable GROUP BY a"
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "a"),
- term("select",
- "a",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- val expected = unaryNode(
- "DataSetCalc",
- aggregate,
- term("select",
- "EXPR$0",
- "EXPR$1",
- "EXPR$2")
- )
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testGroupAggregateWithFilter(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1 GROUP BY a"
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select","a", "b", "c") ,
- term("where","=(a, 1)")
- )
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- calcNode,
- term("groupBy", "a"),
- term("select",
- "a",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- val expected = unaryNode(
- "DataSetCalc",
- aggregate,
- term("select",
- "EXPR$0",
- "EXPR$1",
- "EXPR$2")
- )
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala
deleted file mode 100644
index 6ae48f8..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-
-class CompositeFlatteningTest extends TableTestBase {
-
- @Test
- def testMultipleFlattening(): Unit = {
- val util = batchTestUtil()
- util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "a._1 AS _1",
- "a._2 AS _2",
- "c",
- "b._1 AS _10",
- "b._2 AS _20"
- )
- )
-
- util.verifySql(
- "SELECT MyTable.a.*, c, MyTable.b.* FROM MyTable",
- expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DataSetSingleRowJoinTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DataSetSingleRowJoinTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DataSetSingleRowJoinTest.scala
deleted file mode 100644
index 1f7ce84..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/DataSetSingleRowJoinTest.scala
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class DataSetSingleRowJoinTest extends TableTestBase {
-
- @Test
- def testSingleRowCrossJoin(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Int)]("A", 'a1, 'a2)
-
- val query =
- "SELECT a1, asum " +
- "FROM A, (SELECT sum(a1) + sum(a2) AS asum FROM A)"
-
- val expected =
- binaryNode(
- "DataSetSingleRowJoin",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a1")
- ),
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- batchTableNode(0),
- tuples(List(null, null)),
- term("values", "a1", "a2")
- ),
- term("union","a1","a2")
- ),
- term("select", "SUM(a1) AS $f0", "SUM(a2) AS $f1")
- ),
- term("select", "+($f0, $f1) AS asum")
- ),
- term("where", "true"),
- term("join", "a1", "asum"),
- term("joinType", "NestedLoopInnerJoin")
- )
-
- util.verifySql(query, expected)
- }
-
- @Test
- def testSingleRowEquiJoin(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, String)]("A", 'a1, 'a2)
-
- val query =
- "SELECT a1, a2 " +
- "FROM A, (SELECT count(a1) AS cnt FROM A) " +
- "WHERE a1 = cnt"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetSingleRowJoin",
- batchTableNode(0),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a1")
- ),
- tuples(List(null)),
- term("values", "a1")
- ),
- term("union","a1")
- ),
- term("select", "COUNT(a1) AS cnt")
- ),
- term("where", "=(CAST(a1), cnt)"),
- term("join", "a1", "a2", "cnt"),
- term("joinType", "NestedLoopInnerJoin")
- ),
- term("select", "a1", "a2")
- )
-
- util.verifySql(query, expected)
- }
-
- @Test
- def testSingleRowNotEquiJoin(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, String)]("A", 'a1, 'a2)
-
- val query =
- "SELECT a1, a2 " +
- "FROM A, (SELECT count(a1) AS cnt FROM A) " +
- "WHERE a1 < cnt"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- binaryNode(
- "DataSetSingleRowJoin",
- batchTableNode(0),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a1")
- ),
- tuples(List(null)),
- term("values", "a1")
- ),
- term("union", "a1")
- ),
- term("select", "COUNT(a1) AS cnt")
- ),
- term("where", "<(a1, cnt)"),
- term("join", "a1", "a2", "cnt"),
- term("joinType", "NestedLoopInnerJoin")
- ),
- term("select", "a1", "a2")
- )
-
- util.verifySql(query, expected)
- }
-
- @Test
- def testSingleRowJoinWithComplexPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long)]("A", 'a1, 'a2)
- util.addTable[(Int, Long)]("B", 'b1, 'b2)
-
- val query =
- "SELECT a1, a2, b1, b2 " +
- "FROM A, (SELECT min(b1) AS b1, max(b2) AS b2 FROM B) " +
- "WHERE a1 < b1 AND a2 = b2"
-
- val expected = binaryNode(
- "DataSetSingleRowJoin",
- batchTableNode(0),
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- batchTableNode(1),
- tuples(List(null, null)),
- term("values", "b1", "b2")
- ),
- term("union","b1","b2")
- ),
- term("select", "MIN(b1) AS b1", "MAX(b2) AS b2")
- ),
- term("where", "AND(<(a1, b1)", "=(a2, b2))"),
- term("join", "a1", "a2", "b1", "b2"),
- term("joinType", "NestedLoopInnerJoin")
- )
-
- util.verifySql(query, expected)
- }
-
- @Test
- def testRightSingleLeftJoinEqualPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Long, Int)]("A", 'a1, 'a2)
- util.addTable[(Int, Int)]("B", 'b1, 'b2)
-
- val queryLeftJoin =
- "SELECT a2 " +
- "FROM A " +
- " LEFT JOIN " +
- "(SELECT COUNT(*) AS cnt FROM B) AS x " +
- " ON a1 = cnt"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetSingleRowJoin",
- batchTableNode(0),
- term("where", "=(a1, cnt)"),
- term("join", "a1", "a2", "cnt"),
- term("joinType", "NestedLoopLeftJoin")
- ),
- term("select", "a2")
- ) + "\n" +
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetCalc",
- batchTableNode(1),
- term("select", "0 AS $f0")),
- tuples(List(null)), term("values", "$f0")
- ),
- term("union", "$f0")
- ),
- term("select", "COUNT(*) AS cnt")
- )
-
- util.verifySql(queryLeftJoin, expected)
- }
-
- @Test
- def testRightSingleLeftJoinNotEqualPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Long, Int)]("A", 'a1, 'a2)
- util.addTable[(Int, Int)]("B", 'b1, 'b2)
-
- val queryLeftJoin =
- "SELECT a2 " +
- "FROM A " +
- " LEFT JOIN " +
- "(SELECT COUNT(*) AS cnt FROM B) AS x " +
- " ON a1 > cnt"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetSingleRowJoin",
- batchTableNode(0),
- term("where", ">(a1, cnt)"),
- term("join", "a1", "a2", "cnt"),
- term("joinType", "NestedLoopLeftJoin")
- ),
- term("select", "a2")
- ) + "\n" +
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetCalc",
- batchTableNode(1),
- term("select", "0 AS $f0")),
- tuples(List(null)), term("values", "$f0")
- ),
- term("union", "$f0")
- ),
- term("select", "COUNT(*) AS cnt")
- )
-
- util.verifySql(queryLeftJoin, expected)
- }
-
- @Test
- def testLeftSingleRightJoinEqualPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Long, Long)]("A", 'a1, 'a2)
- util.addTable[(Long, Long)]("B", 'b1, 'b2)
-
- val queryRightJoin =
- "SELECT a1 " +
- "FROM (SELECT COUNT(*) AS cnt FROM B) " +
- " RIGHT JOIN " +
- "A " +
- " ON cnt = a2"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetSingleRowJoin",
- "",
- term("where", "=(cnt, a2)"),
- term("join", "cnt", "a1", "a2"),
- term("joinType", "NestedLoopRightJoin")
- ),
- term("select", "a1")
- ) + unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetCalc",
- batchTableNode(1),
- term("select", "0 AS $f0")),
- tuples(List(null)), term("values", "$f0")
- ),
- term("union", "$f0")
- ),
- term("select", "COUNT(*) AS cnt")
- ) + "\n" +
- batchTableNode(0)
-
- util.verifySql(queryRightJoin, expected)
- }
-
- @Test
- def testLeftSingleRightJoinNotEqualPredicate(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Long, Long)]("A", 'a1, 'a2)
- util.addTable[(Long, Long)]("B", 'b1, 'b2)
-
- val queryRightJoin =
- "SELECT a1 " +
- "FROM (SELECT COUNT(*) AS cnt FROM B) " +
- " RIGHT JOIN " +
- "A " +
- " ON cnt < a2"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetSingleRowJoin",
- "",
- term("where", "<(cnt, a2)"),
- term("join", "cnt", "a1", "a2"),
- term("joinType", "NestedLoopRightJoin")
- ),
- term("select", "a1")
- ) +
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetCalc",
- batchTableNode(1),
- term("select", "0 AS $f0")),
- tuples(List(null)), term("values", "$f0")
- ),
- term("union", "$f0")
- ),
- term("select", "COUNT(*) AS cnt")
- ) + "\n" +
- batchTableNode(0)
-
- util.verifySql(queryRightJoin, expected)
- }
-
- @Test
- def testSingleRowJoinInnerJoin(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Int)]("A", 'a1, 'a2)
- val query =
- "SELECT a2, sum(a1) " +
- "FROM A " +
- "GROUP BY a2 " +
- "HAVING sum(a1) > (SELECT sum(a1) * 0.1 FROM A)"
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetSingleRowJoin",
- unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "a2"),
- term("select", "a2", "SUM(a1) AS EXPR$1")
- ),
- term("where", ">(EXPR$1, EXPR$0)"),
- term("join", "a2", "EXPR$1", "EXPR$0"),
- term("joinType", "NestedLoopInnerJoin")
- ),
- term("select", "a2", "EXPR$1")
- ) + "\n" +
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetValues",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a1")
- ),
- tuples(List(null)), term("values", "a1")
- ),
- term("union", "a1")
- ),
- term("select", "SUM(a1) AS $f0")
- ),
- term("select", "*($f0, 0.1) AS EXPR$0")
- )
-
- util.verifySql(query, expected)
- }
-}
[22/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala
deleted file mode 100644
index 2e8f206..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/CalcITCase.scala
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.expressions.utils.{RichFunc1, RichFunc2}
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.utils.UserDefinedFunctionTestUtils
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class CalcITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testSimpleSelectAll(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1, '_2, '_3)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hi",
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSelectFirst(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("1", "2", "3")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSimpleSelectWithNaming(): Unit = {
-
- // verify ProjectMergeRule.
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv)
- .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
- .select('a, 'b)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1", "2,2", "3,2", "4,3", "5,3", "6,3", "7,4",
- "8,4", "9,4", "10,4", "11,5", "12,5", "13,5", "14,5", "15,5",
- "16,6", "17,6", "18,6", "19,6", "20,6", "21,6")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSimpleSelectAllWithAs(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a, 'b, 'c)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hi",
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSimpleFilter(): Unit = {
- /*
- * Test simple filter
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter('a === 3)
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
- /*
- * Test all-rejecting filter
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(false) )
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- assertEquals(true, StreamITCase.testResults.isEmpty)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
- /*
- * Test all-passing filter
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(true) )
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hi",
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testFilterOnIntegerTupleField(): Unit = {
- /*
- * Test filter on Integer tuple field.
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 === 0 )
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "2,2,Hello", "4,3,Hello world, how are you?",
- "6,3,Luke Skywalker", "8,4,Comment#2", "10,4,Comment#4",
- "12,5,Comment#6", "14,5,Comment#8", "16,6,Comment#10",
- "18,6,Comment#12", "20,6,Comment#14")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testNotEquals(): Unit = {
- /*
- * Test filter on Integer tuple field.
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 !== 0)
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
- val expected = mutable.MutableList(
- "1,1,Hi", "3,2,Hello world",
- "5,3,I am fine.", "7,4,Comment#1", "9,4,Comment#3",
- "11,5,Comment#5", "13,5,Comment#7", "15,5,Comment#9",
- "17,6,Comment#11", "19,6,Comment#13", "21,6,Comment#15")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUserDefinedFunctionWithParameter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
-
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.get3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .where("RichFunc2(c)='ABC#Hello'")
- .select('c)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Hello")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testMultipleUserDefinedFunctions(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc1", new RichFunc1)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
-
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.get3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .where("RichFunc2(c)='Abc#Hello' || RichFunc1(a)=3 && b=2")
- .select('c)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Hello", "Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala
deleted file mode 100644
index 8df14e8..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupAggregationsITCase.scala
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import org.apache.flink.api.common.time.Time
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.runtime.datastream.StreamITCase.RetractingSink
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
-import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-import scala.collection.mutable
-
-/**
- * Tests of groupby (without window) aggregations
- */
-class GroupAggregationsITCase extends StreamingWithStateTestBase {
- private val queryConfig = new StreamQueryConfig()
- queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
-
-
- @Test
- def testDistinct(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .select('b).distinct()
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = mutable.MutableList("1", "2", "3", "4", "5", "6")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testDistinctAfterAggregate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .groupBy('e).select('e, 'a.count).distinct()
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = mutable.MutableList("1,5", "2,7", "3,3")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testNonKeyedGroupAggregate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a.sum, 'b.sum)
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = List("231,91")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testGroupAggregate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('b, 'a.sum)
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = List("1,1", "2,5", "3,15", "4,34", "5,65", "6,111")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testDoubleGroupAggregation(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('a.count as 'cnt, 'b)
- .groupBy('cnt)
- .select('cnt, 'b.count as 'freq)
-
- val results = t.toRetractStream[Row](queryConfig)
-
- results.addSink(new RetractingSink)
- env.execute()
- val expected = List("1,1", "2,1", "3,1", "4,1", "5,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testGroupAggregateWithExpression(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .groupBy('e, 'b % 3)
- .select('c.min, 'e, 'a.avg, 'd.count)
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new RetractingSink)
- env.execute()
-
- val expected = mutable.MutableList(
- "0,1,1,1", "7,1,4,2", "2,1,3,2",
- "3,2,3,3", "1,2,3,3", "14,2,5,1",
- "12,3,5,1", "5,3,4,2")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala
deleted file mode 100644
index 1af85d9..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/GroupWindowAggregationsITCase.scala
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.common.time.Time
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.runtime.datastream.table.GroupWindowAggregationsITCase._
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-/**
- * We only test some aggregations until better testing of constructed DataStream
- * programs is possible.
- */
-class GroupWindowAggregationsITCase extends StreamingMultipleProgramsTestBase {
- private val queryConfig = new StreamQueryConfig()
- queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
-
- val data = List(
- (1L, 1, "Hi"),
- (2L, 2, "Hello"),
- (4L, 2, "Hello"),
- (8L, 3, "Hello world"),
- (16L, 3, "Hello world"))
-
- val data2 = List(
- (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
- (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
- (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
- (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
- (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
- (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
- (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
-
- @Test
- def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
-
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, countFun('int), 'int.avg,
- weightAvgFun('long, 'int), weightAvgFun('int, 'int))
-
- val results = windowedTable.toAppendStream[Row](queryConfig)
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("Hello world,1,3,8,3", "Hello world,2,3,12,3", "Hello,1,2,2,2",
- "Hello,2,2,3,2", "Hi,1,1,1,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSessionGroupWindowOverTime(): Unit = {
- //To verify the "merge" functionality, we create this test with the following characteristics:
- // 1. set the Parallelism to 1, and have the test data out of order
- // 2. create a waterMark with 10ms offset to delay the window emission by 10ms
- val sessionWindowTestdata = List(
- (1L, 1, "Hello"),
- (2L, 2, "Hello"),
- (8L, 8, "Hello"),
- (9L, 9, "Hello World"),
- (4L, 4, "Hello"),
- (16L, 16, "Hello"))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvgWithMerge
-
- val stream = env
- .fromCollection(sessionWindowTestdata)
- .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset[(Long, Int, String)](10L))
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Session withGap 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, countFun('int), 'int.avg,
- weightAvgFun('long, 'int), weightAvgFun('int, 'int))
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("Hello World,1,9,9,9", "Hello,1,16,16,16", "Hello,4,3,5,5")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'proctime.proctime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w)
- .select(countFun('string), 'int.avg,
- weightAvgFun('long, 'int), weightAvgFun('int, 'int))
-
- val results = windowedTable.toAppendStream[Row](queryConfig)
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("2,1,1,1", "2,2,6,2")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeTumblingWindow(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampAndWatermarkWithOffset[(Long, Int, String)](0L))
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'rowtime.rowtime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, countFun('string), 'int.avg, weightAvgFun('long, 'int),
- weightAvgFun('int, 'int), 'int.min, 'int.max, 'int.sum, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hello world,1,3,8,3,3,3,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01",
- "Hello world,1,3,16,3,3,3,3,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02",
- "Hello,2,2,3,2,2,2,4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hi,1,1,1,1,1,1,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testGroupWindowWithoutKeyInProjection(): Unit = {
- val data = List(
- (1L, 1, "Hi", 1, 1),
- (2L, 2, "Hello", 2, 2),
- (4L, 2, "Hello", 2, 2),
- (8L, 3, "Hello world", 3, 3),
- (16L, 3, "Hello world", 3, 3))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'long, 'int, 'string, 'int2, 'int3, 'proctime.proctime)
-
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'int2, 'int3, 'string)
- .select(weightAvgFun('long, 'int))
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq("12", "8", "2", "3", "1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-
-
- // ----------------------------------------------------------------------------------------------
- // Sliding windows
- // ----------------------------------------------------------------------------------------------
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data2)
- .assignTimestampsAndWatermarks(
- new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 2.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
- "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
- "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019",
- "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
- "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003",
- "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011",
- "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007",
- "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
- "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data2)
- .assignTimestampsAndWatermarks(
- new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 10.milli every 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
- "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
- "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
- "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02",
- "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025",
- "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
- "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
- "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
- "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data2)
- .assignTimestampsAndWatermarks(
- new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 4.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
- "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
- "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
- "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data2)
- .assignTimestampsAndWatermarks(
- new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data2)
- .assignTimestampsAndWatermarks(
- new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 3.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeGroupWindowWithoutExplicitTimeField(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data2)
- .assignTimestampsAndWatermarks(
- new TimestampAndWatermarkWithOffset[(Long, Int, Double, Float, BigDecimal, String)](0L))
- .map(t => (t._2, t._6))
- val table = stream.toTable(tEnv, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 3.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
-
-object GroupWindowAggregationsITCase {
-
- class TimestampAndWatermarkWithOffset[T <: Product](
- offset: Long) extends AssignerWithPunctuatedWatermarks[T] {
-
- override def checkAndGetNextWatermark(
- lastElement: T,
- extractedTimestamp: Long): Watermark = {
- new Watermark(extractedTimestamp - offset)
- }
-
- override def extractTimestamp(
- element: T,
- previousElementTimestamp: Long): Long = {
- element.productElement(0).asInstanceOf[Long]
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala
deleted file mode 100644
index 531e26f..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.source.SourceFunction
-import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
-import org.apache.flink.table.api.java.utils.UserDefinedScalarFunctions.JavaFunc0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.table.runtime.datastream.table.OverWindowITCase._
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class OverWindowITCase extends StreamingWithStateTestBase {
-
- @Test
- def testProcTimeUnBoundedPartitionedRowOver(): Unit = {
-
- val data = List(
- (1L, 1, "Hello"),
- (2L, 2, "Hello"),
- (3L, 3, "Hello"),
- (4L, 4, "Hello"),
- (5L, 5, "Hello"),
- (6L, 6, "Hello"),
- (7L, 7, "Hello World"),
- (8L, 8, "Hello World"),
- (20L, 20, "Hello World"))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- StreamITCase.clear
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(
- Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
- .select('c, countFun('b) over 'w as 'mycount, weightAvgFun('a, 'b) over 'w as 'wAvg)
- .select('c, 'mycount, 'wAvg)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hello World,1,7", "Hello World,2,7", "Hello World,3,14",
- "Hello,1,1", "Hello,2,1", "Hello,3,2", "Hello,4,3", "Hello,5,3", "Hello,6,4")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.testResults = mutable.MutableList()
- StreamITCase.clear
- env.setParallelism(1)
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (1, 1L, "Hello")),
- Left(14000002L, (1, 2L, "Hello")),
- Left(14000002L, (1, 3L, "Hello world")),
- Left(14000003L, (2, 2L, "Hello world")),
- Left(14000003L, (2, 3L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 4L, "Hello world")),
- Left(14000022L, (1, 5L, "Hello world")),
- Left(14000022L, (1, 6L, "Hello world")),
- Left(14000022L, (1, 7L, "Hello world")),
- Left(14000023L, (2, 4L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000030L)
- )
- val table = env
- .addSource(new RowTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
- val plusOne = new JavaFunc0
-
- val windowedTable = table
- .window(Over partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_RANGE following
- CURRENT_RANGE as 'w)
- .select(
- 'a, 'b, 'c,
- 'b.sum over 'w,
- "SUM:".toExpr + ('b.sum over 'w),
- countFun('b) over 'w,
- (countFun('b) over 'w) + 1,
- plusOne(countFun('b) over 'w),
- array('b.avg over 'w, 'b.max over 'w),
- 'b.avg over 'w,
- 'b.max over 'w,
- 'b.min over 'w,
- ('b.min over 'w).abs(),
- weightAvgFun('b, 'a) over 'w)
-
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,2,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,1,Hi,7,SUM:7,4,5,5,[1, 3],1,3,1,1,1",
- "2,1,Hello,1,SUM:1,1,2,2,[1, 1],1,1,1,1,1",
- "2,2,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "2,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,4,Hello world,11,SUM:11,5,6,6,[2, 4],2,4,1,1,2",
- "1,5,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
- "1,6,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
- "1,7,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
- "2,4,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3",
- "2,5,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3"
- )
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeBoundedPartitionedRowsOver(): Unit = {
-
- val data = List(
- (1, 1L, 0, "Hallo", 1L),
- (2, 2L, 1, "Hallo Welt", 2L),
- (2, 3L, 2, "Hallo Welt wie", 1L),
- (3, 4L, 3, "Hallo Welt wie gehts?", 2L),
- (3, 5L, 4, "ABC", 2L),
- (3, 6L, 5, "BCD", 3L),
- (4, 7L, 6, "CDE", 2L),
- (4, 8L, 7, "DEF", 1L),
- (4, 9L, 8, "EFG", 1L),
- (4, 10L, 9, "FGH", 2L),
- (5, 11L, 10, "GHI", 1L),
- (5, 12L, 11, "HIJ", 3L),
- (5, 13L, 12, "IJK", 3L),
- (5, 14L, 13, "JKL", 2L),
- (5, 15L, 14, "KLM", 2L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setParallelism(1)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
-
- val windowedTable = table
- .window(Over partitionBy 'a orderBy 'proctime preceding 4.rows following CURRENT_ROW as 'w)
- .select('a, 'c.sum over 'w, 'c.min over 'w)
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,0,0",
- "2,1,1",
- "2,3,1",
- "3,3,3",
- "3,7,3",
- "3,12,3",
- "4,6,6",
- "4,13,6",
- "4,21,6",
- "4,30,6",
- "5,10,10",
- "5,21,10",
- "5,33,10",
- "5,46,10",
- "5,60,10")
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRowOver(): Unit = {
- val data = Seq(
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((3L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Right(2L),
- Left((3L, (3L, 3, "Hello"))),
- Left((4L, (4L, 4, "Hello"))),
- Left((5L, (5L, 5, "Hello"))),
- Left((6L, (6L, 6, "Hello"))),
- Left((20L, (20L, 20, "Hello World"))),
- Right(6L),
- Left((8L, (8L, 8, "Hello World"))),
- Left((7L, (7L, 7, "Hello World"))),
- Right(20L))
-
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val table = env.addSource[(Long, Int, String)](
- new RowTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_ROW as 'w)
- .select('c, 'a, 'a.count over 'w, 'a.sum over 'w)
-
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
- "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
- "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
- "Hello,6,3,15",
- "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
- "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRangeOver(): Unit = {
- val data = Seq(
- Left((1500L, (1L, 15, "Hello"))),
- Left((1600L, (1L, 16, "Hello"))),
- Left((1000L, (1L, 1, "Hello"))),
- Left((2000L, (2L, 2, "Hello"))),
- Right(1000L),
- Left((2000L, (2L, 2, "Hello"))),
- Left((2000L, (2L, 3, "Hello"))),
- Left((3000L, (3L, 3, "Hello"))),
- Right(2000L),
- Left((4000L, (4L, 4, "Hello"))),
- Right(3000L),
- Left((5000L, (5L, 5, "Hello"))),
- Right(5000L),
- Left((6000L, (6L, 6, "Hello"))),
- Left((6500L, (6L, 65, "Hello"))),
- Right(7000L),
- Left((9000L, (6L, 9, "Hello"))),
- Left((9500L, (6L, 18, "Hello"))),
- Left((9000L, (6L, 9, "Hello"))),
- Right(10000L),
- Left((10000L, (7L, 7, "Hello World"))),
- Left((11000L, (7L, 17, "Hello World"))),
- Left((11000L, (7L, 77, "Hello World"))),
- Right(12000L),
- Left((14000L, (7L, 18, "Hello World"))),
- Right(14000L),
- Left((15000L, (8L, 8, "Hello World"))),
- Right(17000L),
- Left((20000L, (20L, 20, "Hello World"))),
- Right(19000L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val table = env.addSource[(Long, Int, String)](
- new RowTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(
- Over partitionBy 'c orderBy 'rowtime preceding 1.seconds following CURRENT_RANGE as 'w)
- .select('c, 'b, 'a.count over 'w, 'a.sum over 'w)
-
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
- "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
- "Hello,3,4,9",
- "Hello,4,2,7",
- "Hello,5,2,9",
- "Hello,6,2,11", "Hello,65,2,12",
- "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
- "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
- "Hello World,8,2,15",
- "Hello World,20,1,20")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
-
-object OverWindowITCase {
-
- class RowTimeSourceFunction[T](
- dataWithTimestampList: Seq[Either[(Long, T), Long]]) extends SourceFunction[T] {
- override def run(ctx: SourceContext[T]): Unit = {
- dataWithTimestampList.foreach {
- case Left(t) => ctx.collectWithTimestamp(t._2, t._1)
- case Right(w) => ctx.emitWatermark(new Watermark(w))
- }
- }
-
- override def cancel(): Unit = ???
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala
deleted file mode 100644
index e8cfd75..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.table.utils.TableFunc0
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-
-/**
- * tests for retraction
- */
-class RetractionITCase extends StreamingWithStateTestBase {
- // input data
- val data = List(
- ("Hello", 1),
- ("word", 1),
- ("Hello", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("flink", 1)
- )
-
- // keyed groupby + keyed groupby
- @Test
- def testWordCount(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .groupBy('word)
- .select('num.sum as 'count)
- .groupBy('count)
- .select('count, 'count.count as 'frequency)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = Seq("1,2", "2,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- // keyed groupby + non-keyed groupby
- @Test
- def testGroupByAndNonKeyedGroupBy(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .groupBy('word)
- .select('word as 'word, 'num.sum as 'cnt)
- .select('cnt.sum)
-
- val results = resultTable.toRetractStream[Row]
-
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = Seq("10")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- // non-keyed groupby + keyed groupby
- @Test
- def testNonKeyedGroupByAndGroupBy(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .select('num.sum as 'count)
- .groupBy('count)
- .select('count, 'count.count)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = Seq("10,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- // test unique process, if the current output message of unbounded groupby equals the
- // previous message, unbounded groupby will ignore the current one.
- @Test
- def testUniqueProcess(): Unit = {
- // data input
- val data = List(
- (1, 1L),
- (2, 2L),
- (3, 3L),
- (3, 3L),
- (4, 1L),
- (4, 0L),
- (4, 0L),
- (4, 0L),
- (5, 1L),
- (6, 6L),
- (6, 6L),
- (6, 6L),
- (7, 8L)
- )
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'pk, 'value)
- val resultTable = table
- .groupBy('pk)
- .select('pk as 'pk, 'value.sum as 'sum)
- .groupBy('sum)
- .select('sum, 'pk.count as 'count)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractMessagesSink)
- env.execute()
-
- val expected = Seq(
- "+1,1", "+2,1", "+3,1", "-3,1", "+6,1", "-1,1", "+1,2", "-1,2", "+1,3", "-6,1", "+6,2",
- "-6,2", "+6,1", "+12,1", "-12,1", "+18,1", "+8,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- // correlate should handle retraction messages correctly
- @Test
- def testCorrelate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val func0 = new TableFunc0
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .groupBy('word)
- .select('word as 'word, 'num.sum as 'cnt)
- .leftOuterJoin(func0('word))
- .groupBy('cnt)
- .select('cnt, 'word.count as 'frequency)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = Seq("1,2", "2,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala
deleted file mode 100644
index 8a1e398..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import java.io.File
-import java.lang.{Boolean => JBool}
-
-import org.apache.flink.api.common.functions.MapFunction
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.tuple.{Tuple2 => JTuple2}
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.streaming.api.functions.sink.SinkFunction
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.sinks._
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class TableSinksITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testStreamTableSink(): Unit = {
-
- val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
- tmpFile.deleteOnExit()
- val path = tmpFile.toURI.toString
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setParallelism(4)
-
- val input = StreamTestData.get3TupleDataStream(env)
- .map(x => x).setParallelism(4) // increase DOP to 4
-
- val results = input.toTable(tEnv, 'a, 'b, 'c)
- .where('a < 5 || 'a > 17)
- .select('c, 'b)
- .writeToSink(new CsvTableSink(path))
-
- env.execute()
-
- val expected = Seq(
- "Hi,1", "Hello,2", "Hello world,2", "Hello world, how are you?,3",
- "Comment#12,6", "Comment#13,6", "Comment#14,6", "Comment#15,6").mkString("\n")
-
- TestBaseUtils.compareResultsByLinesInMemory(expected, path)
- }
-
- @Test
- def testAppendSinkOnAppendTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.end, 'id.count, 'num.sum)
- .writeToSink(new TestAppendSink)
-
- env.execute()
-
- val result = RowCollector.getAndClearValues.map(_.f1.toString).sorted
- val expected = List(
- "1970-01-01 00:00:00.005,4,8",
- "1970-01-01 00:00:00.01,5,18",
- "1970-01-01 00:00:00.015,5,24",
- "1970-01-01 00:00:00.02,5,29",
- "1970-01-01 00:00:00.025,2,12")
- .sorted
- assertEquals(expected, result)
- }
-
- @Test
- def testRetractSinkOnUpdatingTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text)
-
- t.select('id, 'num, 'text.charLength() as 'len)
- .groupBy('len)
- .select('len, 'id.count, 'num.sum)
- .writeToSink(new TestRetractSink)
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- val retracted = restractResults(results).sorted
- val expected = List(
- "2,1,1",
- "5,1,2",
- "11,1,2",
- "25,1,3",
- "10,7,39",
- "14,1,3",
- "9,9,41").sorted
- assertEquals(expected, retracted)
-
- }
-
- @Test
- def testRetractSinkOnAppendTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.end, 'id.count, 'num.sum)
- .writeToSink(new TestRetractSink)
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = restractResults(results).sorted
- val expected = List(
- "1970-01-01 00:00:00.005,4,8",
- "1970-01-01 00:00:00.01,5,18",
- "1970-01-01 00:00:00.015,5,24",
- "1970-01-01 00:00:00.02,5,29",
- "1970-01-01 00:00:00.025,2,12")
- .sorted
- assertEquals(expected, retracted)
-
- }
-
- @Test
- def testUpsertSinkOnUpdatingTableWithFullKey(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text)
-
- t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
- .groupBy('len, 'cTrue)
- .select('len, 'id.count as 'cnt, 'cTrue)
- .groupBy('cnt, 'cTrue)
- .select('cnt, 'len.count, 'cTrue)
- .writeToSink(new TestUpsertSink(Array("cnt", "cTrue"), false))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertTrue(
- "Results must include delete messages",
- results.exists(_.f0 == false)
- )
-
- val retracted = upsertResults(results, Array(0, 2)).sorted
- val expected = List(
- "1,5,true",
- "7,1,true",
- "9,1,true").sorted
- assertEquals(expected, retracted)
-
- }
-
-
-
- @Test
- def testUpsertSinkOnAppendingTableWithFullKey1(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('num, 'w.end as 'wend, 'id.count)
- .writeToSink(new TestUpsertSink(Array("wend", "num"), true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = upsertResults(results, Array(0, 1, 2)).sorted
- val expected = List(
- "1,1970-01-01 00:00:00.005,1",
- "2,1970-01-01 00:00:00.005,2",
- "3,1970-01-01 00:00:00.005,1",
- "3,1970-01-01 00:00:00.01,2",
- "4,1970-01-01 00:00:00.01,3",
- "4,1970-01-01 00:00:00.015,1",
- "5,1970-01-01 00:00:00.015,4",
- "5,1970-01-01 00:00:00.02,1",
- "6,1970-01-01 00:00:00.02,4",
- "6,1970-01-01 00:00:00.025,2").sorted
- assertEquals(expected, retracted)
- }
-
- @Test
- def testUpsertSinkOnAppendingTableWithFullKey2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('w.start as 'wstart, 'w.end as 'wend, 'num, 'id.count)
- .writeToSink(new TestUpsertSink(Array("wstart", "wend", "num"), true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = upsertResults(results, Array(0, 1, 2)).sorted
- val expected = List(
- "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,1,1",
- "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,2,2",
- "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,3,1",
- "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,3,2",
- "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,4,3",
- "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,4,1",
- "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,5,4",
- "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,5,1",
- "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,6,4",
- "1970-01-01 00:00:00.02,1970-01-01 00:00:00.025,6,2").sorted
- assertEquals(expected, retracted)
- }
-
- @Test
- def testUpsertSinkOnAppendingTableWithoutFullKey1(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('w.end as 'wend, 'id.count as 'cnt)
- .writeToSink(new TestUpsertSink(null, true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = results.map(_.f1.toString).sorted
- val expected = List(
- "1970-01-01 00:00:00.005,1",
- "1970-01-01 00:00:00.005,2",
- "1970-01-01 00:00:00.005,1",
- "1970-01-01 00:00:00.01,2",
- "1970-01-01 00:00:00.01,3",
- "1970-01-01 00:00:00.015,1",
- "1970-01-01 00:00:00.015,4",
- "1970-01-01 00:00:00.02,1",
- "1970-01-01 00:00:00.02,4",
- "1970-01-01 00:00:00.025,2").sorted
- assertEquals(expected, retracted)
- }
-
- @Test
- def testUpsertSinkOnAppendingTableWithoutFullKey2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('num, 'id.count as 'cnt)
- .writeToSink(new TestUpsertSink(null, true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = results.map(_.f1.toString).sorted
- val expected = List(
- "1,1",
- "2,2",
- "3,1",
- "3,2",
- "4,3",
- "4,1",
- "5,4",
- "5,1",
- "6,4",
- "6,2").sorted
- assertEquals(expected, retracted)
- }
-
- /** Converts a list of retraction messages into a list of final results. */
- private def restractResults(results: List[JTuple2[JBool, Row]]): List[String] = {
-
- val retracted = results
- .foldLeft(Map[String, Int]()){ (m: Map[String, Int], v: JTuple2[JBool, Row]) =>
- val cnt = m.getOrElse(v.f1.toString, 0)
- if (v.f0) {
- m + (v.f1.toString -> (cnt + 1))
- } else {
- m + (v.f1.toString -> (cnt - 1))
- }
- }.filter{ case (_, c: Int) => c != 0 }
-
- assertFalse(
- "Received retracted rows which have not been accumulated.",
- retracted.exists{ case (_, c: Int) => c < 0})
-
- retracted.flatMap { case (r: String, c: Int) => (0 until c).map(_ => r) }.toList
- }
-
- /** Converts a list of upsert messages into a list of final results. */
- private def upsertResults(results: List[JTuple2[JBool, Row]], keys: Array[Int]): List[String] = {
-
- def getKeys(r: Row): List[String] =
- keys.foldLeft(List[String]())((k, i) => r.getField(i).toString :: k)
-
- val upserted = results.foldLeft(Map[String, String]()){ (o: Map[String, String], r) =>
- val key = getKeys(r.f1).mkString("")
- if (r.f0) {
- o + (key -> r.f1.toString)
- } else {
- o - key
- }
- }
-
- upserted.values.toList
- }
-
-}
-
-private[flink] class TestAppendSink extends AppendStreamTableSink[Row] {
-
- var fNames: Array[String] = _
- var fTypes: Array[TypeInformation[_]] = _
-
- override def emitDataStream(s: DataStream[Row]): Unit = {
- s.map(
- new MapFunction[Row, JTuple2[JBool, Row]] {
- override def map(value: Row): JTuple2[JBool, Row] = new JTuple2(true, value)
- })
- .addSink(new RowSink)
- }
-
- override def getOutputType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
-
- override def getFieldNames: Array[String] = fNames
-
- override def getFieldTypes: Array[TypeInformation[_]] = fTypes
-
- override def configure(
- fieldNames: Array[String],
- fieldTypes: Array[TypeInformation[_]]): TableSink[Row] = {
- val copy = new TestAppendSink
- copy.fNames = fieldNames
- copy.fTypes = fieldTypes
- copy
- }
-}
-
-private[flink] class TestRetractSink extends RetractStreamTableSink[Row] {
-
- var fNames: Array[String] = _
- var fTypes: Array[TypeInformation[_]] = _
-
- override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
- s.addSink(new RowSink)
- }
-
- override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
-
- override def getFieldNames: Array[String] = fNames
-
- override def getFieldTypes: Array[TypeInformation[_]] = fTypes
-
- override def configure(
- fieldNames: Array[String],
- fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
- val copy = new TestRetractSink
- copy.fNames = fieldNames
- copy.fTypes = fieldTypes
- copy
- }
-
-}
-
-private[flink] class TestUpsertSink(
- expectedKeys: Array[String],
- expectedIsAppendOnly: Boolean)
- extends UpsertStreamTableSink[Row] {
-
- var fNames: Array[String] = _
- var fTypes: Array[TypeInformation[_]] = _
-
- override def setKeyFields(keys: Array[String]): Unit =
- if (keys != null) {
- assertEquals("Provided key fields do not match expected keys",
- expectedKeys.sorted.mkString(","),
- keys.sorted.mkString(","))
- } else {
- assertNull("Provided key fields should not be null.", expectedKeys)
- }
-
- override def setIsAppendOnly(isAppendOnly: JBool): Unit =
- assertEquals(
- "Provided isAppendOnly does not match expected isAppendOnly",
- expectedIsAppendOnly,
- isAppendOnly)
-
- override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
-
- override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
- s.addSink(new RowSink)
- }
-
- override def getFieldNames: Array[String] = fNames
-
- override def getFieldTypes: Array[TypeInformation[_]] = fTypes
-
- override def configure(
- fieldNames: Array[String],
- fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
- val copy = new TestUpsertSink(expectedKeys, expectedIsAppendOnly)
- copy.fNames = fieldNames
- copy.fTypes = fieldTypes
- copy
- }
-}
-
-class RowSink extends SinkFunction[JTuple2[JBool, Row]] {
- override def invoke(value: JTuple2[JBool, Row]): Unit = RowCollector.addValue(value)
-}
-
-object RowCollector {
- private val sink: mutable.ArrayBuffer[JTuple2[JBool, Row]] =
- new mutable.ArrayBuffer[JTuple2[JBool, Row]]()
-
- def addValue(value: JTuple2[JBool, Row]): Unit = {
- sink.synchronized {
- sink += value
- }
- }
-
- def getAndClearValues: List[JTuple2[JBool, Row]] = {
- val out = sink.toList
- sink.clear()
- out
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala
deleted file mode 100644
index 07b748c..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.utils.{CommonTestData, TestFilterableTableSource}
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class TableSourceITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testCsvTableSource(): Unit = {
-
- val csvTable = CommonTestData.getCsvTableSource
- StreamITCase.testResults = mutable.MutableList()
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- tEnv.registerTableSource("csvTable", csvTable)
- tEnv.scan("csvTable")
- .where('id > 4)
- .select('last, 'score * 2)
- .toAppendStream[Row]
- .addSink(new StreamITCase.StringSink[Row])
-
- env.execute()
-
- val expected = mutable.MutableList(
- "Williams,69.0",
- "Miller,13.56",
- "Smith,180.2",
- "Williams,4.68")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testCsvTableSourceWithFilterable(): Unit = {
- StreamITCase.testResults = mutable.MutableList()
- val tableName = "MyTable"
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerTableSource(tableName, new TestFilterableTableSource)
- tEnv.scan(tableName)
- .where("amount > 4 && price < 9")
- .select("id, name")
- .addSink(new StreamITCase.StringSink[Row])
-
- env.execute()
-
- val expected = mutable.MutableList(
- "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
[25/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableEnvironmentITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableEnvironmentITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableEnvironmentITCase.scala
new file mode 100644
index 0000000..2e23161
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableEnvironmentITCase.scala
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import java.util
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.runtime.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableEnvironmentITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSimpleRegister(): Unit = {
+
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet(tableName, ds)
+ val t = tEnv.scan(tableName).select('_1, '_2, '_3)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRegisterWithFields(): Unit = {
+
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet(tableName, ds, 'a, 'b, 'c)
+ val t = tEnv.scan(tableName).select('a, 'b)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" +
+ "7,4\n" + "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
+ "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableRegister(): Unit = {
+
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ tEnv.registerTable(tableName, t)
+
+ val regT = tEnv.scan(tableName).select('a, 'b).filter('a > 8)
+
+ val expected = "9,4\n" + "10,4\n" +
+ "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
+ "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" +
+ "19,6\n" + "20,6\n" + "21,6\n"
+
+ val results = regT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testToTable(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .select('a, 'b, 'c)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testToTableFromCaseClass(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ SomeCaseClass("Peter", 28, 4000.00, "Sales"),
+ SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
+ SomeCaseClass("Lucy", 42, 6000.00, "HR"))
+
+ val t = env.fromCollection(data)
+ .toTable(tEnv, 'a, 'b, 'c, 'd)
+ .select('a, 'b, 'c, 'd)
+
+ val expected: String =
+ "Peter,28,4000.0,Sales\n" +
+ "Anna,56,10000.0,Engineering\n" +
+ "Lucy,42,6000.0,HR\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testToTableFromAndToCaseClass(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ SomeCaseClass("Peter", 28, 4000.00, "Sales"),
+ SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
+ SomeCaseClass("Lucy", 42, 6000.00, "HR"))
+
+ val t = env.fromCollection(data)
+ .toTable(tEnv, 'a, 'b, 'c, 'd)
+ .select('a, 'b, 'c, 'd)
+
+ val expected: String =
+ "SomeCaseClass(Peter,28,4000.0,Sales)\n" +
+ "SomeCaseClass(Anna,56,10000.0,Engineering)\n" +
+ "SomeCaseClass(Lucy,42,6000.0,HR)\n"
+ val results = t.toDataSet[SomeCaseClass].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+}
+
+object TableEnvironmentITCase {
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](
+ Array(TableProgramsTestBase.DEFAULT)
+ ).asJava
+ }
+}
+
+case class SomeCaseClass(name: String, age: Int, salary: Double, department: String) {
+ def this() { this("", 0, 0.0, "") }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSinkITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSinkITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSinkITCase.scala
new file mode 100644
index 0000000..d8ba29a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSinkITCase.scala
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import java.io.File
+
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.api.scala.{ExecutionEnvironment, _}
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.sinks.CsvTableSink
+import org.apache.flink.test.util.TestBaseUtils
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@RunWith(classOf[Parameterized])
+class TableSinkITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testBatchTableSink(): Unit = {
+
+ val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
+ tmpFile.deleteOnExit()
+ val path = tmpFile.toURI.toString
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ env.setParallelism(4)
+
+ val input = CollectionDataSets.get3TupleDataSet(env)
+ .map(x => x).setParallelism(4) // increase DOP to 4
+
+ val results = input.toTable(tEnv, 'a, 'b, 'c)
+ .where('a < 5 || 'a > 17)
+ .select('c, 'b)
+ .writeToSink(new CsvTableSink(path, fieldDelim = "|"))
+
+ env.execute()
+
+ val expected = Seq(
+ "Hi|1", "Hello|2", "Hello world|2", "Hello world, how are you?|3",
+ "Comment#12|6", "Comment#13|6", "Comment#14|6", "Comment#15|6").mkString("\n")
+
+ TestBaseUtils.compareResultsByLinesInMemory(expected, path)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSourceITCase.scala
new file mode 100644
index 0000000..5e214b1
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/TableSourceITCase.scala
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import org.apache.flink.api.scala.ExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.{CommonTestData, TableProgramsCollectionTestBase}
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.utils.TestFilterableTableSource
+import org.apache.flink.test.util.TestBaseUtils
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableSourceITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testCsvTableSourceWithProjection(): Unit = {
+ val csvTable = CommonTestData.getCsvTableSource
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ tEnv.registerTableSource("csvTable", csvTable)
+
+ val results = tEnv
+ .scan("csvTable")
+ .where('score < 20)
+ .select('last, 'id.floor(), 'score * 2)
+ .collect()
+
+ val expected = Seq(
+ "Smith,1,24.6",
+ "Miller,3,15.78",
+ "Smith,4,0.24",
+ "Miller,6,13.56",
+ "Williams,8,4.68").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableSourceWithFilterable(): Unit = {
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ tableEnv.registerTableSource(tableName, new TestFilterableTableSource)
+ val results = tableEnv
+ .scan(tableName)
+ .where("amount > 4 && price < 9")
+ .select("id, name")
+ .collect()
+
+ val expected = Seq(
+ "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala
deleted file mode 100644
index eb516e7..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.sql
-
-import java.sql.Timestamp
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class AggregationsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testAggregationTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1), min(_1), max(_1), count(_1), avg(_1) FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231,1,21,21,11"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1) FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDataSetAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1) FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationDataTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), avg(b), avg(c), avg(d), avg(e), avg(f), count(g), " +
- "min(g), min('Ciao'), max(g), max('Ciao'), sum(CAST(f AS DECIMAL)) FROM MyTable"
-
- val ds = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'f, 'g)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,1,1,1.5,1.5,2,Ciao,Ciao,Hello,Ciao,3.0"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), sum(a), count(a), avg(b), sum(b) " +
- "FROM MyTable"
-
- val ds = env.fromElements((1: Byte, 1: Short), (2: Byte, 2: Short)).toTable(tEnv, 'a, 'b)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,3,2,1,3"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableAggregationWithArithmetic(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a + 2) + 2, count(b) + 5 " +
- "FROM MyTable"
-
- val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv, 'a, 'b)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "5.5,7"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationWithTwoCount(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT count(_1), count(_2) FROM MyTable"
-
- val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "2,2"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-
- @Test
- def testAggregationAfterProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM " +
- "(SELECT _1 as a, _2 as b, _3 as c FROM MyTable)"
-
- val ds = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,3,2"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDistinctAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1) as a, count(distinct _3) as b FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231,21"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedDistinctAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT _2, avg(distinct _1) as a, count(_3) as b FROM MyTable GROUP BY _2"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected =
- "6,18,6\n5,13,5\n4,8,4\n3,5,3\n2,2,2\n1,1,1"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupingSetAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery =
- "SELECT _2, _3, avg(_1) as a, GROUP_ID() as g FROM MyTable GROUP BY GROUPING SETS (_2, _3)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
-
- val expected =
- "6,null,18,1\n5,null,13,1\n4,null,8,1\n3,null,5,1\n2,null,2,1\n1,null,1,1\n" +
- "null,Luke Skywalker,6,2\nnull,I am fine.,5,2\nnull,Hi,1,2\n" +
- "null,Hello world, how are you?,4,2\nnull,Hello world,3,2\nnull,Hello,2,2\n" +
- "null,Comment#9,15,2\nnull,Comment#8,14,2\nnull,Comment#7,13,2\n" +
- "null,Comment#6,12,2\nnull,Comment#5,11,2\nnull,Comment#4,10,2\n" +
- "null,Comment#3,9,2\nnull,Comment#2,8,2\nnull,Comment#15,21,2\n" +
- "null,Comment#14,20,2\nnull,Comment#13,19,2\nnull,Comment#12,18,2\n" +
- "null,Comment#11,17,2\nnull,Comment#10,16,2\nnull,Comment#1,7,2"
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testAggregateEmptyDataSets(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), sum(a), count(b) " +
- "FROM MyTable where a = 4 group by a"
-
- val sqlQuery2 = "SELECT avg(a), sum(a), count(b) " +
- "FROM MyTable where a = 4"
-
- val sqlQuery3 = "SELECT avg(a), sum(a), count(b) " +
- "FROM MyTable"
-
- val ds = env.fromElements(
- (1: Byte, 1: Short),
- (2: Byte, 2: Short))
- .toTable(tEnv, 'a, 'b)
-
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
- val result2 = tEnv.sql(sqlQuery2)
- val result3 = tEnv.sql(sqlQuery3)
-
- val results = result.toDataSet[Row].collect()
- val expected = Seq.empty
- val results2 = result2.toDataSet[Row].collect()
- val expected2 = "null,null,0"
- val results3 = result3.toDataSet[Row].collect()
- val expected3 = "1,3,2"
-
- assert(results.equals(expected),
- "Empty result is expected for grouped set, but actual: " + results)
- TestBaseUtils.compareResultAsText(results2.asJava, expected2)
- TestBaseUtils.compareResultAsText(results3.asJava, expected3)
- }
-
- @Test
- def testTumbleWindowAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.registerFunction("countFun", new CountAggFunction)
- tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
-
- val sqlQuery =
- "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
- "FROM T " +
- "GROUP BY b, TUMBLE(ts, INTERVAL '3' SECOND)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- // create timestamps
- .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
- tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- val expected = Seq(
- "1,1,1,1,1",
- "2,2,1,2,2", "2,3,1,2,3",
- "3,9,2,3,4", "3,6,1,3,6",
- "4,15,2,4,7", "4,19,2,4,9",
- "5,11,1,5,11", "5,39,3,5,13", "5,15,1,5,15",
- "6,33,2,6,16", "6,57,3,6,19", "6,21,1,6,21"
- ).mkString("\n")
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testHopWindowAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.registerFunction("countFun", new CountAggFunction)
- tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
-
- env.setParallelism(1)
-
- val sqlQuery =
- "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
- "FROM T " +
- "GROUP BY b, HOP(ts, INTERVAL '2' SECOND, INTERVAL '4' SECOND)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- // create timestamps
- .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
- tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- val expected = Seq(
- "1,1,1,1,1","1,1,1,1,1",
- "2,5,2,2,2","2,5,2,2,2",
- "3,9,2,3,4", "3,15,3,3,5", "3,6,1,3,6",
- "4,7,1,4,7", "4,24,3,4,8", "4,27,3,4,9", "4,10,1,4,10",
- "5,11,1,5,11", "5,36,3,5,12", "5,54,4,5,13", "5,29,2,5,14",
- "6,33,2,6,16", "6,70,4,6,17", "6,78,4,6,19", "6,41,2,6,20"
- ).mkString("\n")
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testSessionWindowAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.registerFunction("countFun", new CountAggFunction)
- tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
-
- env.setParallelism(1)
-
- val sqlQuery =
- "SELECT MIN(a), MAX(a), SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), " +
- "wAvgWithMergeAndReset(a, a)" +
- "FROM T " +
- "GROUP BY SESSION(ts, INTERVAL '4' SECOND)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- // create timestamps
- .filter(x => (x._2 % 2) == 0)
- .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
- tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- val expected = Seq(
- "2,10,39,6,3,7",
- "16,21,111,6,6,18"
- ).mkString("\n")
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala
deleted file mode 100644
index 926dc43..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.sql
-
-import java.sql.{Date, Time, Timestamp}
-import java.util
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.table.runtime.dataset.table.OldHashCode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class CalcITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSelectStarFromTable(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectStarFromDataSet(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectAll(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT a, b, c FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectWithNaming(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT _1 as a, _2 as b FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
- "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidFields(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT a, foo FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- tEnv.sql(sqlQuery)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE false"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE true"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
- "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
- "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
- "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
- "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
- "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnString(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE c LIKE '%world%'"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnInteger(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)=0"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
- "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
- "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
- "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDisjunctivePredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE a < 2 OR a > 20"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterWithAnd(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)<>0 AND MOD(b,2)=0"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
- "9,4,Comment#3\n" + "17,6,Comment#11\n" +
- "19,6,Comment#13\n" + "21,6,Comment#15\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAdvancedDataTypes(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT a, b, c, DATE '1984-07-12', TIME '14:34:24', " +
- "TIMESTAMP '1984-07-12 14:34:24' FROM MyTable"
-
- val ds = env.fromElements((
- Date.valueOf("1984-07-12"),
- Time.valueOf("14:34:24"),
- Timestamp.valueOf("1984-07-12 14:34:24")))
- tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
- "1984-07-12,14:34:24,1984-07-12 14:34:24.0"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedScalarFunction(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- tEnv.registerFunction("hashCode", OldHashCode)
- tEnv.registerFunction("hashCode", MyHashCode)
-
- val ds = env.fromElements("a", "b", "c")
- tEnv.registerDataSet("MyTable", ds, 'text)
-
- val result = tEnv.sql("SELECT hashCode(text) FROM MyTable")
-
- val expected = "97\n98\n99"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
-
-object MyHashCode extends ScalarFunction {
- def eval(s: String): Int = s.hashCode()
-}
-
-object CalcITCase {
-
- @Parameterized.Parameters(name = "Table config = {0}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](
- Array(TableProgramsTestBase.DEFAULT),
- Array(TableProgramsTestBase.NO_NULL)).asJava
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala
deleted file mode 100644
index aad4b3b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Assert.assertEquals
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class JoinITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND b < 2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi,Hallo\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND a < 6 AND h < b"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithMultipleKeys(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d AND b = h"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
- "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithAlias(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT Table5.c, Table3.c FROM Table3, Table5 WHERE a = d AND a < 4"
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'c)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = "1,Hi\n" + "2,Hello\n" + "1,Hello\n" +
- "2,Hello world\n" + "2,Hello world\n" + "3,Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDataSetJoinWithAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT COUNT(g), COUNT(b) FROM Table3, Table5 WHERE a = d"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("Table3", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("Table5", ds2, 'd, 'e, 'f, 'g, 'h)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "6,6"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableJoinWithAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT COUNT(b), COUNT(g) FROM Table3, Table5 WHERE a = d"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "6,6"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFullOuterJoin(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
- "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
- "null,IJK\n" + "null,JKL\n" + "null,KLM"
-
- val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table5 LEFT OUTER JOIN Table3 ON b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
- "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
- "null,IJK\n" + "null,JKL\n" + "null,KLM"
- val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightOuterJoin(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
- tEnv.registerTable("Table3", ds1)
- tEnv.registerTable("Table5", ds2)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
- "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
- "null,IJK\n" + "null,JKL\n" + "null,KLM"
- val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCrossJoinWithLeftSingleRowInput(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
- tEnv.registerTable("A", table)
-
- val sqlQuery2 = "SELECT * FROM (SELECT count(*) FROM A) CROSS JOIN A"
- val expected =
- "3,1,1,Hi\n" +
- "3,2,2,Hello\n" +
- "3,3,2,Hello world"
- val result = tEnv.sql(sqlQuery2).collect()
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testCrossJoinWithRightSingleRowInput(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
- tEnv.registerTable("A", table)
-
- val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A)"
- val expected =
- "1,1,Hi,3\n" +
- "2,2,Hello,3\n" +
- "3,2,Hello world,3"
- val result = tEnv.sql(sqlQuery1).collect()
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testCrossJoinWithEmptySingleRowInput(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
- tEnv.registerTable("A", table)
-
- val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A HAVING count(*) < 0)"
- val result = tEnv.sql(sqlQuery1).count()
- Assert.assertEquals(0, result)
- }
-
- @Test
- def testLeftNullRightJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt " +
- "FROM (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) RIGHT JOIN A ON a < cnt"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,null",
- "2,null", "2,null",
- "3,null", "3,null", "3,null",
- "4,null", "4,null", "4,null", "4,null",
- "5,null", "5,null", "5,null", "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-
- @Test
- def testLeftSingleRightJoinEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt = a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,null", "2,null", "2,null", "3,3", "3,3",
- "3,3", "4,null", "4,null", "4,null",
- "4,null", "5,null", "5,null", "5,null",
- "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLeftSingleRightJoinNotEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt > a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,3", "2,3", "2,3", "3,null", "3,null",
- "3,null", "4,null", "4,null", "4,null",
- "4,null", "5,null", "5,null", "5,null",
- "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightNullLeftJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt " +
- "FROM A LEFT JOIN (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) ON cnt > a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("A", ds2)
- tEnv.registerTable("B", ds1)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = Seq(
- "2,null", "3,null", "1,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightSingleLeftJoinEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt = a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = Seq(
- "1,null", "2,null", "2,null", "3,3", "3,3",
- "3,3", "4,null", "4,null", "4,null",
- "4,null", "5,null", "5,null", "5,null",
- "5,null", "5,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightSingleLeftJoinNotEqualPredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt < a"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("A", ds1)
- tEnv.registerTable("B", ds2)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = Seq(
- "1,null", "2,null", "2,null", "3,null", "3,null",
- "3,null", "4,3", "4,3", "4,3",
- "4,3", "5,3", "5,3", "5,3",
- "5,3", "5,3").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightSingleLeftJoinTwoFields(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val sqlQuery =
- "SELECT a, cnt, cnt2 " +
- "FROM t1 LEFT JOIN (SELECT COUNT(*) AS cnt,COUNT(*) AS cnt2 FROM t2 ) AS x ON a = cnt"
-
- val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("t1", ds1)
- tEnv.registerTable("t2", ds2)
-
- val result = tEnv.sql(sqlQuery)
- val expected = Seq(
- "1,null,null",
- "2,null,null", "2,null,null",
- "3,3,3", "3,3,3", "3,3,3",
- "4,null,null", "4,null,null", "4,null,null", "4,null,null",
- "5,null,null", "5,null,null", "5,null,null", "5,null,null", "5,null,null").mkString("\n")
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCrossWithUnnest(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- (1, 1L, Array("Hi", "w")),
- (2, 2L, Array("Hello", "k")),
- (3, 2L, Array("Hello world", "x"))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataSet("T", stream, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) as A (s)"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = List("1,Hi", "1,w", "2,Hello", "2,k", "3,Hello world", "3,x")
- val results = result.toDataSet[Row].collect().toList
- assertEquals(expected.toString(), results.sortWith(_.toString < _.toString).toString())
- }
-
- @Test
- def testJoinWithUnnestOfTuple(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- (1, Array((12, "45.6"), (2, "45.612"))),
- (2, Array((13, "41.6"), (1, "45.2136"))),
- (3, Array((18, "42.6")))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataSet("T", stream, 'a, 'b)
-
- val sqlQuery = "" +
- "SELECT a, b, x, y " +
- "FROM " +
- " (SELECT a, b FROM T WHERE a < 3) as tf, " +
- " UNNEST(tf.b) as A (x, y) " +
- "WHERE x > a"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = List(
- "1,[(12,45.6), (2,45.612)],12,45.6",
- "1,[(12,45.6), (2,45.612)],2,45.612",
- "2,[(13,41.6), (1,45.2136)],13,41.6").mkString(", ")
- val results = result.toDataSet[Row].collect().map(_.toString)
- assertEquals(expected, results.sorted.mkString(", "))
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala
deleted file mode 100644
index 631ce2b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-import scala.util.Random
-
-@RunWith(classOf[Parameterized])
-class SetOperatorsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testUnionAll(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 UNION ALL (SELECT f FROM t2)"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnion(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 UNION (SELECT f FROM t2)"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnionWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM (" +
- "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))" +
- "WHERE b < 2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hallo\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnionWithAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT count(c) FROM (" +
- "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "18"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testExcept(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 EXCEPT (SELECT c FROM t2)"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = env.fromElements((1, 1L, "Hi"))
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @Ignore
- // calcite sql parser doesn't support EXCEPT ALL
- def testExceptAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 EXCEPT ALL SELECT c FROM t2"
-
- val data1 = new mutable.MutableList[Int]
- data1 += (1, 1, 1, 2, 2)
- val data2 = new mutable.MutableList[Int]
- data2 += (1, 2, 2, 3)
- val ds1 = env.fromCollection(data1)
- val ds2 = env.fromCollection(data2)
-
- tEnv.registerDataSet("t1", ds1, 'c)
- tEnv.registerDataSet("t2", ds2, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1\n1"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testExceptWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM (" +
- "SELECT * FROM t1 EXCEPT (SELECT a, b, c FROM t2))" +
- "WHERE b < 2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersect(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 INTERSECT SELECT c FROM t2"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Hi"))
- data.+=((2, 2L, "Hello"))
- data.+=((2, 2L, "Hello"))
- data.+=((3, 2L, "Hello world!"))
- val ds2 = env.fromCollection(Random.shuffle(data))
-
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hi\n" + "Hello\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @Ignore
- // calcite sql parser doesn't support INTERSECT ALL
- def testIntersectAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM t1 INTERSECT ALL SELECT c FROM t2"
-
- val data1 = new mutable.MutableList[Int]
- data1 += (1, 1, 1, 2, 2)
- val data2 = new mutable.MutableList[Int]
- data2 += (1, 2, 2, 3)
- val ds1 = env.fromCollection(data1)
- val ds2 = env.fromCollection(data2)
-
- tEnv.registerDataSet("t1", ds1, 'c)
- tEnv.registerDataSet("t2", ds2, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1\n2\n2"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectWithFilter(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT c FROM ((SELECT * FROM t1) INTERSECT (SELECT * FROM t2)) WHERE a > 1"
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get3TupleDataSet(env)
-
- tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
- tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello\n" + "Hello world\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala
deleted file mode 100644
index f06517a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.sql
-
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.api.scala.{ExecutionEnvironment, _}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.SortTestUtils._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-@RunWith(classOf[Parameterized])
-class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- private def getExecutionEnvironment = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- // set the parallelism explicitly to make sure the query is executed in
- // a distributed manner
- env.setParallelism(3)
- env
- }
-
- @Test
- def testOrderByMultipleFieldsWithSql(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC, _2 DESC"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- (- x.productElement(0).asInstanceOf[Int], - x.productElement(1).asInstanceOf[Long]))
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- def rowOrdering = Ordering.by((r : Row) => {
- // ordering for this tuple will fall into the previous defined tupleOrdering,
- // so we just need to return the field by their defining sequence
- (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
- })
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(rowOrdering)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByWithOffset(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC OFFSET 2 ROWS"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- - x.productElement(0).asInstanceOf[Int] )
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings, 2, 21)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results.
- filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByWithOffsetAndFetch(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings, 2, 7)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByLimit(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable ORDER BY _2, _1 LIMIT 5"
-
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- (x.productElement(1).asInstanceOf[Long], x.productElement(0).asInstanceOf[Int]) )
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
- // squash all rows inside a partition into one element
- val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- def rowOrdering = Ordering.by((r : Row) => {
- // ordering for this tuple will fall into the previous defined tupleOrdering,
- // so we just need to return the field by their defining sequence
- (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
- })
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(rowOrdering)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala
deleted file mode 100644
index e7db602..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.sql
-
-import org.apache.flink.api.scala.ExecutionEnvironment
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.utils.CommonTestData
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class TableSourceITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testCsvTableSource(): Unit = {
-
- val csvTable = CommonTestData.getCsvTableSource
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- tEnv.registerTableSource("csvTable", csvTable)
- val results = tEnv.sql(
- "SELECT id, `first`, `last`, score FROM csvTable").collect()
-
- val expected = Seq(
- "1,Mike,Smith,12.3",
- "2,Bob,Taylor,45.6",
- "3,Sam,Miller,7.89",
- "4,Peter,Smith,0.12",
- "5,Liz,Williams,34.5",
- "6,Sally,Miller,6.78",
- "7,Alice,Smith,90.1",
- "8,Kelly,Williams,2.34").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testNested(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val nestedTable = CommonTestData.getNestedTableSource
-
- tableEnv.registerTableSource("NestedPersons", nestedTable)
-
- val result = tableEnv.sql("SELECT NestedPersons.firstName, NestedPersons.lastName," +
- "NestedPersons.address.street, NestedPersons.address.city AS city " +
- "FROM NestedPersons " +
- "WHERE NestedPersons.address.city LIKE 'Dublin'").collect()
-
- val expected = "Bob,Taylor,Pearse Street,Dublin"
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala
deleted file mode 100644
index b31c1fb..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class TableWithSQLITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSQLTable(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE a > 9"
-
- val result = tEnv.sql(sqlQuery).select('a.avg, 'b.sum, 'c.count)
-
- val expected = "15,65,12"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableSQLTable(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val t1 = ds.filter('a > 9)
-
- tEnv.registerTable("MyTable", t1)
-
- val sqlQuery = "SELECT avg(a) as a1, sum(b) as b1, count(c) as c1 FROM MyTable"
-
- val result = tEnv.sql(sqlQuery).select('a1 + 1, 'b1 - 5, 'c1)
-
- val expected = "16,60,12"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMultipleSQLQueries(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val sqlQuery = "SELECT a as aa FROM MyTable WHERE b = 6"
- val result1 = tEnv.sql(sqlQuery)
- tEnv.registerTable("ResTable", result1)
-
- val sqlQuery2 = "SELECT count(aa) FROM ResTable"
- val result2 = tEnv.sql(sqlQuery2)
-
- val expected = "6"
- val results = result2.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectWithCompositeType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT MyTable.a2, MyTable.a1._2 FROM MyTable"
-
- val ds = env.fromElements(((12, true), "Hello")).toTable(tEnv).as('a1, 'a2)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello,true\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
[04/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala
new file mode 100644
index 0000000..6b68665
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+import scala.util.Random
+
+@RunWith(classOf[Parameterized])
+class SetOperatorsITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testUnionAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
+
+ val unionDs = ds1.unionAll(ds2).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
+
+ val unionDs = ds1.union(ds2).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTernaryUnionAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val unionDs = ds1.unionAll(ds2).unionAll(ds3).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" +
+ "Hi\n" + "Hello\n" + "Hello world\n" +
+ "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTernaryUnion(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val unionDs = ds1.union(ds2).union(ds3).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMinusAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
+
+ val minusDs = ds1.unionAll(ds1).unionAll(ds1)
+ .minusAll(ds2.unionAll(ds2)).select('c)
+
+ val results = minusDs.toDataSet[Row].collect()
+ val expected = "Hi\n" +
+ "Hello\n" + "Hello world\n" +
+ "Hello\n" + "Hello world\n" +
+ "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMinus(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
+
+ val minusDs = ds1.unionAll(ds1).unionAll(ds1)
+ .minus(ds2.unionAll(ds2)).select('c)
+
+ val results = minusDs.toDataSet[Row].collect()
+ val expected = "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMinusDifferentFieldNames(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'd, 'e, 'f)
+
+ val minusDs = ds1.unionAll(ds1).unionAll(ds1)
+ .minus(ds2.unionAll(ds2)).select('c)
+
+ val results = minusDs.toDataSet[Row].collect()
+ val expected = "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersect(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Hi"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((3, 2L, "Hello world!"))
+ val ds2 = env.fromCollection(Random.shuffle(data)).toTable(tEnv, 'a, 'b, 'c)
+
+ val intersectDS = ds1.intersect(ds2).select('c).toDataSet[Row]
+
+ val results = intersectDS.collect()
+
+ val expected = "Hi\n" + "Hello\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data1 = new mutable.MutableList[Int]
+ data1 += (1, 1, 1, 2, 2)
+ val data2 = new mutable.MutableList[Int]
+ data2 += (1, 2, 2, 2, 3)
+ val ds1 = env.fromCollection(data1).toTable(tEnv, 'c)
+ val ds2 = env.fromCollection(data2).toTable(tEnv, 'c)
+
+ val intersectDS = ds1.intersectAll(ds2).select('c).toDataSet[Row]
+
+ val expected = "1\n2\n2"
+ val results = intersectDS.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectWithDifferentFieldNames(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'e, 'f, 'g)
+
+ val intersectDs = ds1.intersect(ds2).select('c)
+
+ val results = intersectDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectWithScalarExpression(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a + 1, 'b, 'c)
+ val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a + 1, 'b, 'c)
+
+ val intersectDs = ds1.intersect(ds2)
+
+ val results = intersectDs.toDataSet[Row].collect()
+ val expected = "2,1,Hi\n" + "3,2,Hello\n" + "4,2,Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala
new file mode 100644
index 0000000..1784d81
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.api.scala.{ExecutionEnvironment, _}
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.SortTestUtils._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+@RunWith(classOf[Parameterized])
+class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ private def getExecutionEnvironment = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ // set the parallelism explicitly to make sure the query is executed in
+ // a distributed manner
+ env.setParallelism(3)
+ env
+ }
+
+ @Test
+ def testOrderByDesc(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.desc)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ - x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByAsc(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.asc)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByMultipleFieldsDifferentDirections(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_2.asc, '_1.desc)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ (x.productElement(1).asInstanceOf[Long], - x.productElement(0).asInstanceOf[Int]) )
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ def rowOrdering = Ordering.by((r : Row) => {
+ // ordering for this tuple will fall into the previous defined tupleOrdering,
+ // so we just need to return the field by their defining sequence
+ (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
+ })
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(rowOrdering)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByOffset(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.asc).limit(3)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings, 3, 21)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByOffsetAndFetch(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.desc).limit(3, 5)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ - x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings, 3, 8)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByFetch(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.asc).limit(0, 5)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ implicit def rowOrdering = Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int])
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala
new file mode 100644
index 0000000..c7153dd
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import java.util
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableEnvironmentITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSimpleRegister(): Unit = {
+
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet(tableName, ds)
+ val t = tEnv.scan(tableName).select('_1, '_2, '_3)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRegisterWithFields(): Unit = {
+
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet(tableName, ds, 'a, 'b, 'c)
+ val t = tEnv.scan(tableName).select('a, 'b)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" +
+ "7,4\n" + "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
+ "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableRegister(): Unit = {
+
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ tEnv.registerTable(tableName, t)
+
+ val regT = tEnv.scan(tableName).select('a, 'b).filter('a > 8)
+
+ val expected = "9,4\n" + "10,4\n" +
+ "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
+ "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" +
+ "19,6\n" + "20,6\n" + "21,6\n"
+
+ val results = regT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testToTable(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .select('a, 'b, 'c)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testToTableFromCaseClass(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ SomeCaseClass("Peter", 28, 4000.00, "Sales"),
+ SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
+ SomeCaseClass("Lucy", 42, 6000.00, "HR"))
+
+ val t = env.fromCollection(data)
+ .toTable(tEnv, 'a, 'b, 'c, 'd)
+ .select('a, 'b, 'c, 'd)
+
+ val expected: String =
+ "Peter,28,4000.0,Sales\n" +
+ "Anna,56,10000.0,Engineering\n" +
+ "Lucy,42,6000.0,HR\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testToTableFromAndToCaseClass(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ SomeCaseClass("Peter", 28, 4000.00, "Sales"),
+ SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
+ SomeCaseClass("Lucy", 42, 6000.00, "HR"))
+
+ val t = env.fromCollection(data)
+ .toTable(tEnv, 'a, 'b, 'c, 'd)
+ .select('a, 'b, 'c, 'd)
+
+ val expected: String =
+ "SomeCaseClass(Peter,28,4000.0,Sales)\n" +
+ "SomeCaseClass(Anna,56,10000.0,Engineering)\n" +
+ "SomeCaseClass(Lucy,42,6000.0,HR)\n"
+ val results = t.toDataSet[SomeCaseClass].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+}
+
+object TableEnvironmentITCase {
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](
+ Array(TableProgramsTestBase.DEFAULT)
+ ).asJava
+ }
+}
+
+case class SomeCaseClass(name: String, age: Int, salary: Double, department: String) {
+ def this() { this("", 0, 0.0, "") }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala
new file mode 100644
index 0000000..c8f26ec
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import java.io.File
+
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.api.scala.{ExecutionEnvironment, _}
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.sinks.CsvTableSink
+import org.apache.flink.test.util.TestBaseUtils
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+
+@RunWith(classOf[Parameterized])
+class TableSinkITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testBatchTableSink(): Unit = {
+
+ val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
+ tmpFile.deleteOnExit()
+ val path = tmpFile.toURI.toString
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ env.setParallelism(4)
+
+ val input = CollectionDataSets.get3TupleDataSet(env)
+ .map(x => x).setParallelism(4) // increase DOP to 4
+
+ val results = input.toTable(tEnv, 'a, 'b, 'c)
+ .where('a < 5 || 'a > 17)
+ .select('c, 'b)
+ .writeToSink(new CsvTableSink(path, fieldDelim = "|"))
+
+ env.execute()
+
+ val expected = Seq(
+ "Hi|1", "Hello|2", "Hello world|2", "Hello world, how are you?|3",
+ "Comment#12|6", "Comment#13|6", "Comment#14|6", "Comment#15|6").mkString("\n")
+
+ TestBaseUtils.compareResultsByLinesInMemory(expected, path)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala
new file mode 100644
index 0000000..fb93f26
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import org.apache.flink.api.scala.ExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.utils.{CommonTestData, TestFilterableTableSource}
+import org.apache.flink.test.util.TestBaseUtils
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableSourceITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testCsvTableSourceWithProjection(): Unit = {
+ val csvTable = CommonTestData.getCsvTableSource
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ tEnv.registerTableSource("csvTable", csvTable)
+
+ val results = tEnv
+ .scan("csvTable")
+ .where('score < 20)
+ .select('last, 'id.floor(), 'score * 2)
+ .collect()
+
+ val expected = Seq(
+ "Smith,1,24.6",
+ "Miller,3,15.78",
+ "Smith,4,0.24",
+ "Miller,6,13.56",
+ "Williams,8,4.68").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableSourceWithFilterable(): Unit = {
+ val tableName = "MyTable"
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ tableEnv.registerTableSource(tableName, new TestFilterableTableSource)
+ val results = tableEnv
+ .scan(tableName)
+ .where("amount > 4 && price < 9")
+ .select("id, name")
+ .collect()
+
+ val expected = Seq(
+ "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamAggregateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamAggregateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamAggregateITCase.scala
deleted file mode 100644
index 8837e03..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamAggregateITCase.scala
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.scala.stream.utils.StreamITCase
-import org.apache.flink.table.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.runtime.datastream.DataStreamAggregateITCase.TimestampWithEqualWatermark
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class DataStreamAggregateITCase extends StreamingMultipleProgramsTestBase {
-
- val data = List(
- (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
- (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
- (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
- (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
- (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
- (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
- (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
-
- // ----------------------------------------------------------------------------------------------
- // Sliding windows
- // ----------------------------------------------------------------------------------------------
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 2.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
- "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
- "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019",
- "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
- "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003",
- "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011",
- "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007",
- "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
- "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 10.milli every 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
- "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
- "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
- "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02",
- "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025",
- "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015",
- "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
- "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01",
- "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 4.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
- "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013",
- "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017",
- "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021",
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataSet variant
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'long.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 3.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testEventTimeGroupWindowWithoutExplicitTimeField(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- .map(t => (t._2, t._6))
- val table = stream.toTable(tEnv, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 3.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
- val expected = Seq(
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003",
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
-
-object DataStreamAggregateITCase {
- class TimestampWithEqualWatermark
- extends AssignerWithPunctuatedWatermarks[(Long, Int, Double, Float, BigDecimal, String)] {
-
- override def checkAndGetNextWatermark(
- lastElement: (Long, Int, Double, Float, BigDecimal, String),
- extractedTimestamp: Long)
- : Watermark = {
- new Watermark(extractedTimestamp)
- }
-
- override def extractTimestamp(
- element: (Long, Int, Double, Float, BigDecimal, String),
- previousElementTimestamp: Long): Long = {
- element._1
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamCalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamCalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamCalcITCase.scala
deleted file mode 100644
index dcd7800..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamCalcITCase.scala
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamTestData}
-import org.apache.flink.table.expressions.utils.{RichFunc1, RichFunc2}
-import org.apache.flink.table.utils.UserDefinedFunctionTestUtils
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class DataStreamCalcITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testUserDefinedFunctionWithParameter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
-
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.get3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .where("RichFunc2(c)='ABC#Hello'")
- .select('c)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Hello")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testMultipleUserDefinedFunctions(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc1", new RichFunc1)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
-
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.get3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .where("RichFunc2(c)='Abc#Hello' || RichFunc1(a)=3 && b=2")
- .select('c)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Hello", "Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamUserDefinedFunctionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamUserDefinedFunctionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamUserDefinedFunctionITCase.scala
deleted file mode 100644
index 53caee3..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/DataStreamUserDefinedFunctionITCase.scala
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.runtime.datastream
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamTestData}
-import org.apache.flink.table.expressions.utils.{Func13, Func18, RichFunc2}
-import org.apache.flink.table.utils._
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.{Before, Test}
-
-import scala.collection.mutable
-
-class DataStreamUserDefinedFunctionITCase extends StreamingMultipleProgramsTestBase {
-
- val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv: StreamTableEnvironment = TableEnvironment.getTableEnvironment(env)
-
- @Before
- def clear(): Unit = {
- StreamITCase.clear
- }
-
- @Test
- def testCrossJoin(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
- val pojoFunc0 = new PojoTableFunc()
-
- val result = t
- .join(func0('c) as('d, 'e))
- .select('c, 'd, 'e)
- .join(pojoFunc0('c))
- .where('age > 20)
- .select('c, 'name, 'age)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Jack#22,Jack,22", "Anna#44,Anna,44")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = t
- .leftOuterJoin(func0('c) as('d, 'e))
- .select('c, 'd, 'e)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "nosharp,null,null", "Jack#22,Jack,22",
- "John#19,John,19", "Anna#44,Anna,44")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = t
- .join(func0('c) as('d, 'e))
- .where(Func18('d, "J"))
- .select('c, 'd, 'e)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Jack#22,Jack,22", "John#19,John,19")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUserDefinedTableFunctionWithParameter(): Unit = {
- val tableFunc1 = new RichTableFunc1
- tEnv.registerFunction("RichTableFunc1", tableFunc1)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> " "))
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.getSmall3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(tableFunc1('c) as 's)
- .select('a, 's)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("3,Hello", "3,world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUserDefinedTableFunctionWithUserDefinedScalarFunction(): Unit = {
- val tableFunc1 = new RichTableFunc1
- val richFunc2 = new RichFunc2
- tEnv.registerFunction("RichTableFunc1", tableFunc1)
- tEnv.registerFunction("RichFunc2", richFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(
- env,
- Map("word_separator" -> "#", "string.value" -> "test"))
- StreamITCase.testResults = mutable.MutableList()
-
- val result = StreamTestData.getSmall3TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(tableFunc1(richFunc2('c)) as 's)
- .select('a, 's)
-
- val results = result.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,Hi",
- "1,test",
- "2,Hello",
- "2,test",
- "3,Hello world",
- "3,test")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testTableFunctionConstructorWithParams(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val config = Map("key1" -> "value1", "key2" -> "value2")
- val func30 = new TableFunc3(null)
- val func31 = new TableFunc3("OneConf_")
- val func32 = new TableFunc3("TwoConf_", config)
-
- val result = t
- .join(func30('c) as('d, 'e))
- .select('c, 'd, 'e)
- .join(func31('c) as ('f, 'g))
- .select('c, 'd, 'e, 'f, 'g)
- .join(func32('c) as ('h, 'i))
- .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
- .toAppendStream[Row]
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Anna#44,Anna,OneConf_Anna,TwoConf__key=key1_value=value1_Anna,44,44,44",
- "Anna#44,Anna,OneConf_Anna,TwoConf__key=key2_value=value2_Anna,44,44,44",
- "Jack#22,Jack,OneConf_Jack,TwoConf__key=key1_value=value1_Jack,22,22,22",
- "Jack#22,Jack,OneConf_Jack,TwoConf__key=key2_value=value2_Jack,22,22,22",
- "John#19,John,OneConf_John,TwoConf__key=key1_value=value1_John,19,19,19",
- "John#19,John,OneConf_John,TwoConf__key=key2_value=value2_John,19,19,19"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testScalarFunctionConstructorWithParams(): Unit = {
- val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
- val func0 = new Func13("default")
- val func1 = new Func13("Sunny")
- val func2 = new Func13("kevin2")
-
- val result = t.select(func0('c), func1('c),func2('c))
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44",
- "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22",
- "default-John#19,Sunny-John#19,kevin2-John#19",
- "default-nosharp,Sunny-nosharp,kevin2-nosharp"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testTableFunctionWithVariableArguments(): Unit = {
- val varArgsFunc0 = new VarArgsFunc0
- tEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
-
- val result = testData(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .select('c)
- .join(varArgsFunc0("1", "2", 'c))
-
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Anna#44,1",
- "Anna#44,2",
- "Anna#44,Anna#44",
- "Jack#22,1",
- "Jack#22,2",
- "Jack#22,Jack#22",
- "John#19,1",
- "John#19,2",
- "John#19,John#19",
- "nosharp,1",
- "nosharp,2",
- "nosharp,nosharp")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- private def testData(
- env: StreamExecutionEnvironment)
- : DataStream[(Int, Long, String)] = {
-
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Jack#22"))
- data.+=((2, 2L, "John#19"))
- data.+=((3, 2L, "Anna#44"))
- data.+=((4, 3L, "nosharp"))
- env.fromCollection(data)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala
new file mode 100644
index 0000000..e04bd75
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream
+
+import java.util.Collections
+
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction
+import org.apache.flink.types.Row
+import org.junit.Assert._
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+import scala.collection.mutable.ArrayBuffer
+
+object StreamITCase {
+
+ var testResults: mutable.MutableList[String] = mutable.MutableList.empty[String]
+ var retractedResults: ArrayBuffer[String] = mutable.ArrayBuffer.empty[String]
+
+ def clear = {
+ StreamITCase.testResults.clear()
+ StreamITCase.retractedResults.clear()
+ }
+
+ def compareWithList(expected: java.util.List[String]): Unit = {
+ Collections.sort(expected)
+ assertEquals(expected.asScala, StreamITCase.testResults.sorted)
+ }
+
+ final class StringSink[T] extends RichSinkFunction[T]() {
+ def invoke(value: T) {
+ testResults.synchronized {
+ testResults += value.toString
+ }
+ }
+ }
+
+ final class RetractMessagesSink extends RichSinkFunction[(Boolean, Row)]() {
+ def invoke(v: (Boolean, Row)) {
+ testResults.synchronized {
+ testResults += (if (v._1) "+" else "-") + v._2
+ }
+ }
+ }
+
+ final class RetractingSink() extends RichSinkFunction[(Boolean, Row)] {
+ def invoke(v: (Boolean, Row)) {
+ retractedResults.synchronized {
+ val value = v._2.toString
+ if (v._1) {
+ retractedResults += value
+ } else {
+ val idx = retractedResults.indexOf(value)
+ if (idx >= 0) {
+ retractedResults.remove(idx)
+ } else {
+ throw new RuntimeException("Tried to retract a value that wasn't added first. " +
+ "This is probably an incorrectly implemented test. " +
+ "Try to set the parallelism of the sink to 1.")
+ }
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala
new file mode 100644
index 0000000..c32dd00
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.runtime.datastream
+
+import org.apache.flink.contrib.streaming.state.RocksDBStateBackend
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.junit.Rule
+import org.junit.rules.TemporaryFolder
+
+class StreamingWithStateTestBase extends StreamingMultipleProgramsTestBase {
+
+ val _tempFolder = new TemporaryFolder
+
+ @Rule
+ def tempFolder: TemporaryFolder = _tempFolder
+
+ def getStateBackend: RocksDBStateBackend = {
+ val dbPath = tempFolder.newFolder().getAbsolutePath
+ val checkpointPath = tempFolder.newFolder().toURI.toString
+ val backend = new RocksDBStateBackend(checkpointPath)
+ backend.setDbStoragePath(dbPath)
+ backend
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/TimeAttributesITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/TimeAttributesITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/TimeAttributesITCase.scala
deleted file mode 100644
index c434f47..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/TimeAttributesITCase.scala
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.java.utils.Pojos.Pojo1
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamITCase
-import org.apache.flink.table.api.{TableEnvironment, TableException, Types, ValidationException}
-import org.apache.flink.table.calcite.RelTimeIndicatorConverterTest.TableFunc
-import org.apache.flink.table.expressions.{ExpressionParser, TimeIntervalUnit}
-import org.apache.flink.table.runtime.datastream.TimeAttributesITCase.{TestPojo, TimestampWithEqualWatermark, TimestampWithEqualWatermarkPojo}
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-/**
- * Tests for access and materialization of time attributes.
- */
-class TimeAttributesITCase extends StreamingMultipleProgramsTestBase {
-
- val data = List(
- (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
- (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
- (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
- (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
- (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
- (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
- (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
-
- @Test(expected = classOf[TableException])
- def testInvalidTimeCharacteristic(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidUseOfRowtime(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- .select('rowtime.rowtime)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidUseOfRowtime2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- stream
- .toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- .window(Tumble over 2.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.end.rowtime, 'int.count as 'int) // no rowtime on non-window reference
- }
-
- @Test
- def testCalcMaterialization(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table.select('rowtime.cast(Types.STRING))
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.001",
- "1970-01-01 00:00:00.002",
- "1970-01-01 00:00:00.003",
- "1970-01-01 00:00:00.004",
- "1970-01-01 00:00:00.007",
- "1970-01-01 00:00:00.008",
- "1970-01-01 00:00:00.016")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testCalcMaterialization2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table
- .filter('rowtime.cast(Types.LONG) > 4)
- .select('rowtime, 'rowtime.floor(TimeIntervalUnit.DAY), 'rowtime.ceil(TimeIntervalUnit.DAY))
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.007,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
- "1970-01-01 00:00:00.008,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
- "1970-01-01 00:00:00.016,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testTableFunction(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(
- tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
- val func = new TableFunc
-
- val t = table.join(func('rowtime, 'proctime, 'string) as 's).select('rowtime, 's)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.001,1trueHi",
- "1970-01-01 00:00:00.002,2trueHallo",
- "1970-01-01 00:00:00.003,3trueHello",
- "1970-01-01 00:00:00.004,4trueHello",
- "1970-01-01 00:00:00.007,7trueHello",
- "1970-01-01 00:00:00.008,8trueHello world",
- "1970-01-01 00:00:00.016,16trueHello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testWindowAfterTableFunction(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(
- tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
- val func = new TableFunc
-
- val t = table
- .join(func('rowtime, 'proctime, 'string) as 's)
- .window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.rowtime, 's.count)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.004,4",
- "1970-01-01 00:00:00.009,2",
- "1970-01-01 00:00:00.019,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(
- tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table.unionAll(table).select('rowtime)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.001",
- "1970-01-01 00:00:00.001",
- "1970-01-01 00:00:00.002",
- "1970-01-01 00:00:00.002",
- "1970-01-01 00:00:00.003",
- "1970-01-01 00:00:00.003",
- "1970-01-01 00:00:00.004",
- "1970-01-01 00:00:00.004",
- "1970-01-01 00:00:00.007",
- "1970-01-01 00:00:00.007",
- "1970-01-01 00:00:00.008",
- "1970-01-01 00:00:00.008",
- "1970-01-01 00:00:00.016",
- "1970-01-01 00:00:00.016")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testWindowWithAggregationOnRowtimeSql(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- tEnv.registerTable("MyTable", table)
-
- val t = tEnv.sql("SELECT COUNT(`rowtime`) FROM MyTable " +
- "GROUP BY TUMBLE(rowtime, INTERVAL '0.003' SECOND)")
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1",
- "2",
- "2",
- "2"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testMultiWindow(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
-
- val t = table
- .window(Tumble over 2.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.rowtime as 'rowtime, 'int.count as 'int)
- .window(Tumble over 4.millis on 'rowtime as 'w2)
- .groupBy('w2)
- .select('w2.rowtime, 'w2.end, 'int.count)
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.003,1970-01-01 00:00:00.004,2",
- "1970-01-01 00:00:00.007,1970-01-01 00:00:00.008,2",
- "1970-01-01 00:00:00.011,1970-01-01 00:00:00.012,1",
- "1970-01-01 00:00:00.019,1970-01-01 00:00:00.02,1"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testCalcMaterializationWithPojoType(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- tEnv.registerTable("T1", table)
- val querySql = "select rowtime as ts, string as msg from T1"
-
- val results = tEnv.sql(querySql).toAppendStream[Pojo1]
- results.addSink(new StreamITCase.StringSink[Pojo1])
- env.execute()
-
- val expected = Seq(
- "Pojo1{ts=1970-01-01 00:00:00.001, msg='Hi'}",
- "Pojo1{ts=1970-01-01 00:00:00.002, msg='Hallo'}",
- "Pojo1{ts=1970-01-01 00:00:00.003, msg='Hello'}",
- "Pojo1{ts=1970-01-01 00:00:00.004, msg='Hello'}",
- "Pojo1{ts=1970-01-01 00:00:00.007, msg='Hello'}",
- "Pojo1{ts=1970-01-01 00:00:00.008, msg='Hello world'}",
- "Pojo1{ts=1970-01-01 00:00:00.016, msg='Hello world'}")
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testPojoSupport(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val p1 = new TestPojo
- p1.a = 12
- p1.b = 42L
- p1.c = "Test me."
-
- val p2 = new TestPojo
- p2.a = 13
- p2.b = 43L
- p2.c = "And me."
-
- val stream = env
- .fromElements(p1, p2)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermarkPojo)
- // use aliases, swap all attributes, and skip b2
- val table = stream.toTable(tEnv, ('b as 'b).rowtime, 'c as 'c, 'a as 'a)
- // no aliases, no swapping
- val table2 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c)
- // use proctime, no skipping
- val table3 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c, 'b2, 'proctime.proctime)
-
- // Java expressions
-
- // use aliases, swap all attributes, and skip b2
- val table4 = stream.toTable(
- tEnv,
- ExpressionParser.parseExpressionList("(b as b).rowtime, c as c, a as a"): _*)
- // no aliases, no swapping
- val table5 = stream.toTable(
- tEnv,
- ExpressionParser.parseExpressionList("a, b.rowtime, c"): _*)
-
- val t = table.select('b, 'c , 'a)
- .unionAll(table2.select('b, 'c, 'a))
- .unionAll(table3.select('b, 'c, 'a))
- .unionAll(table4.select('b, 'c, 'a))
- .unionAll(table5.select('b, 'c, 'a))
-
- val results = t.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.042,Test me.,12",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13",
- "1970-01-01 00:00:00.043,And me.,13")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
-
-object TimeAttributesITCase {
- class TimestampWithEqualWatermark
- extends AssignerWithPunctuatedWatermarks[(Long, Int, Double, Float, BigDecimal, String)] {
-
- override def checkAndGetNextWatermark(
- lastElement: (Long, Int, Double, Float, BigDecimal, String),
- extractedTimestamp: Long)
- : Watermark = {
- new Watermark(extractedTimestamp)
- }
-
- override def extractTimestamp(
- element: (Long, Int, Double, Float, BigDecimal, String),
- previousElementTimestamp: Long): Long = {
- element._1
- }
- }
-
- class TimestampWithEqualWatermarkPojo
- extends AssignerWithPunctuatedWatermarks[TestPojo] {
-
- override def checkAndGetNextWatermark(
- lastElement: TestPojo,
- extractedTimestamp: Long)
- : Watermark = {
- new Watermark(extractedTimestamp)
- }
-
- override def extractTimestamp(
- element: TestPojo,
- previousElementTimestamp: Long): Long = {
- element.b
- }
- }
-
- class TestPojo() {
- var a: Int = _
- var b: Long = _
- var b2: String = "skip me"
- var c: String = _
- }
-}
[37/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala
deleted file mode 100644
index a377ca3..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableEnvironment, TableException, ValidationException}
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.types.Row
-import org.junit._
-
-class JoinValidationTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testJoinNonExistingKey(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- ds1.join(ds2)
- // must fail. Field 'foo does not exist
- .where('foo === 'e)
- .select('c, 'g)
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoinWithNonMatchingKeyTypes(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- ds1.join(ds2)
- // must fail. Field 'a is Int, and 'g is String
- .where('a === 'g)
- .select('c, 'g).collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoinWithAmbiguousFields(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
-
- ds1.join(ds2)
- // must fail. Both inputs share the same field 'c
- .where('a === 'd)
- .select('c, 'g)
- }
-
- @Test(expected = classOf[TableException])
- def testNoEqualityJoinPredicate1(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- ds1.join(ds2)
- // must fail. No equality join predicate
- .where('d === 'f)
- .select('c, 'g).collect()
- }
-
- @Test(expected = classOf[TableException])
- def testNoEqualityJoinPredicate2(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- ds1.join(ds2)
- // must fail. No equality join predicate
- .where('a < 'd)
- .select('c, 'g).collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoinTablesFromDifferentEnvs(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env)
- val tEnv2 = TableEnvironment.getTableEnvironment(env)
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- val in1 = tEnv1.fromDataSet(ds1, 'a, 'b, 'c)
- val in2 = tEnv2.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'c)
-
- // Must fail. Tables are bound to different TableEnvironments.
- in1.join(in2).where('b === 'e).select('c, 'g)
- }
-
- @Test(expected = classOf[ValidationException])
- def testNoJoinCondition(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- ds2.leftOuterJoin(ds1, 'b === 'd && 'b < 3).select('c, 'g)
- }
-
- @Test(expected = classOf[ValidationException])
- def testNoEquiJoin(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- ds2.leftOuterJoin(ds1, 'b < 'd).select('c, 'g)
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testJoinNonExistingKeyJava() {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- // Must fail. Field foo does not exist.
- ds1.join(ds2).where("foo === e").select("c, g")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testJoinWithNonMatchingKeyTypesJava() {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
- ds1.join(ds2)
- // Must fail. Types of join fields are not compatible (Integer and String)
- .where("a === g").select("c, g")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testJoinWithAmbiguousFieldsJava() {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
- // Must fail. Join input have overlapping field names.
- ds1.join(ds2).where("a === d").select("c, g")
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoinTablesFromDifferentEnvsJava() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env)
- val tEnv2 = TableEnvironment.getTableEnvironment(env)
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- val in1 = tEnv1.fromDataSet(ds1, 'a, 'b, 'c)
- val in2 = tEnv2.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'c)
- // Must fail. Tables are bound to different TableEnvironments.
- in1.join(in2).where("a === d").select("g.count")
- }
-
- @Test(expected = classOf[ValidationException])
- def testRightJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testLeftJoinWithLocalPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testFullJoinWithLocalPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testRightJoinWithLocalPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testLeftJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testFullJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala
deleted file mode 100644
index c5586bf..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit._
-
-class SetOperatorsValidationTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testUnionDifferentColumnSize(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'd, 'c, 'e)
-
- // must fail. Union inputs have different column size.
- ds1.unionAll(ds2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnionDifferentFieldTypes(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
- .select('a, 'b, 'c)
-
- // must fail. Union inputs have different field types.
- ds1.unionAll(ds2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnionTablesFromDifferentEnvs(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env)
- val tEnv2 = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv1, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv2, 'a, 'b, 'c)
-
- // Must fail. Tables are bound to different TableEnvironments.
- ds1.unionAll(ds2).select('c)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMinusDifferentFieldTypes(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
- .select('a, 'b, 'c)
-
- // must fail. Minus inputs have different field types.
- ds1.minus(ds2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMinusAllTablesFromDifferentEnvs(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env)
- val tEnv2 = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv1, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv2, 'a, 'b, 'c)
-
- // Must fail. Tables are bound to different TableEnvironments.
- ds1.minusAll(ds2).select('c)
- }
-
- @Test(expected = classOf[ValidationException])
- def testIntersectWithDifferentFieldTypes(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
- .select('a, 'b, 'c)
-
- // must fail. Intersect inputs have different field types.
- ds1.intersect(ds2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testIntersectTablesFromDifferentEnvs(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env)
- val tEnv2 = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv1, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv2, 'a, 'b, 'c)
-
- // Must fail. Tables are bound to different TableEnvironments.
- ds1.intersect(ds2).select('c)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala
deleted file mode 100644
index a82d4d6..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.types.Row
-import org.junit._
-
-class SortValidationTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testFetchWithoutOrder(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val t = ds.limit(0, 5).toDataSet[Row].collect()
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/LogicalPlanFormatUtils.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/LogicalPlanFormatUtils.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/LogicalPlanFormatUtils.scala
deleted file mode 100644
index 4a69271..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/LogicalPlanFormatUtils.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.utils
-
-object LogicalPlanFormatUtils {
- private val tempPattern = """TMP_\d+""".r
-
- def formatTempTableId(preStr: String): String = {
- val str = preStr.replaceAll("ArrayBuffer\\(", "List\\(")
- val minId = getMinTempTableId(str)
- tempPattern.replaceAllIn(str, s => "TMP_" + (s.matched.substring(4).toInt - minId) )
- }
-
- private def getMinTempTableId(logicalStr: String): Long = {
- val found = tempPattern.findAllIn(logicalStr).map(s => {
- s.substring(4).toInt
- })
- if (found.isEmpty) {
- 0L
- } else {
- found.min
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/SortTestUtils.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/SortTestUtils.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/SortTestUtils.scala
deleted file mode 100644
index ef425d3..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/SortTestUtils.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.utils
-
-object SortTestUtils {
-
- val tupleDataSetStrings = List((1, 1L, "Hi")
- ,(2, 2L, "Hello")
- ,(3, 2L, "Hello world")
- ,(4, 3L, "Hello world, how are you?")
- ,(5, 3L, "I am fine.")
- ,(6, 3L, "Luke Skywalker")
- ,(7, 4L, "Comment#1")
- ,(8, 4L, "Comment#2")
- ,(9, 4L, "Comment#3")
- ,(10, 4L, "Comment#4")
- ,(11, 5L, "Comment#5")
- ,(12, 5L, "Comment#6")
- ,(13, 5L, "Comment#7")
- ,(14, 5L, "Comment#8")
- ,(15, 5L, "Comment#9")
- ,(16, 6L, "Comment#10")
- ,(17, 6L, "Comment#11")
- ,(18, 6L, "Comment#12")
- ,(19, 6L, "Comment#13")
- ,(20, 6L, "Comment#14")
- ,(21, 6L, "Comment#15"))
-
- def sortExpectedly(dataSet: List[Product])
- (implicit ordering: Ordering[Product]): String =
- sortExpectedly(dataSet, 0, dataSet.length)
-
- def sortExpectedly(dataSet: List[Product], start: Int, end: Int)
- (implicit ordering: Ordering[Product]): String = {
- dataSet
- .sorted(ordering)
- .slice(start, end)
- .mkString("\n")
- .replaceAll("[\\(\\)]", "")
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala
deleted file mode 100644
index 712b818..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.utils
-
-import java.util
-
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.runtime.dataset.table.DataSetWindowAggregateITCase
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConversions._
-
-/**
- * This test base provides full cluster-like integration tests for batch programs. Only runtime
- * operator tests should use this test base as they are expensive.
- * (e.g. [[DataSetWindowAggregateITCase]])
- */
-class TableProgramsClusterTestBase(
- executionMode: TestExecutionMode,
- tableConfigMode: TableConfigMode)
- extends TableProgramsTestBase(executionMode, tableConfigMode) {
-}
-
-object TableProgramsClusterTestBase {
-
- @Parameterized.Parameters(name = "Execution mode = {0}, Table config = {1}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](
- Array(TestExecutionMode.CLUSTER, TableProgramsTestBase.DEFAULT),
- Array(TestExecutionMode.CLUSTER_OBJECT_REUSE, TableProgramsTestBase.DEFAULT)
- )
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsCollectionTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsCollectionTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsCollectionTestBase.scala
deleted file mode 100644
index cd7c12d..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsCollectionTestBase.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.utils
-
-import java.util
-
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConversions._
-
-/**
- * This test base provides lightweight integration tests for batch programs. However, it does
- * not test everything (e.g. combiners). Runtime operator tests should
- * use [[TableProgramsClusterTestBase]].
- */
-class TableProgramsCollectionTestBase(
- tableConfigMode: TableConfigMode)
- extends TableProgramsTestBase(TestExecutionMode.COLLECTION, tableConfigMode) {
-}
-
-object TableProgramsCollectionTestBase {
-
- @Parameterized.Parameters(name = "Table config = {0}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](Array(TableProgramsTestBase.DEFAULT))
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsTestBase.scala
deleted file mode 100644
index cf9d947..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsTestBase.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.utils
-
-import org.apache.flink.table.api.TableConfig
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.{NO_NULL, TableConfigMode}
-import org.apache.flink.test.util.MultipleProgramsTestBase
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-
-class TableProgramsTestBase(
- mode: TestExecutionMode,
- tableConfigMode: TableConfigMode)
- extends MultipleProgramsTestBase(mode) {
-
- def config: TableConfig = {
- val conf = new TableConfig
- tableConfigMode match {
- case NO_NULL =>
- conf.setNullCheck(false)
- case _ => // keep default
- }
- conf
- }
-}
-
-object TableProgramsTestBase {
- case class TableConfigMode(nullCheck: Boolean)
-
- val DEFAULT = TableConfigMode(nullCheck = true)
- val NO_NULL = TableConfigMode(nullCheck = false)
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala
deleted file mode 100644
index 030a415..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.validation
-
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo.{DOUBLE_TYPE_INFO, INT_TYPE_INFO, STRING_TYPE_INFO}
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.{GenericTypeInfo, RowTypeInfo, TupleTypeInfo, TypeExtractor}
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala.batch.{CClass, PojoClass}
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.table.expressions.{Alias, UnresolvedFieldReference}
-import org.apache.flink.table.runtime.types.CRowTypeInfo
-import org.apache.flink.types.Row
-import org.junit.Assert.assertTrue
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-@RunWith(classOf[Parameterized])
-class TableEnvironmentValidationTest(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val tupleType = new TupleTypeInfo(
- INT_TYPE_INFO,
- STRING_TYPE_INFO,
- DOUBLE_TYPE_INFO)
-
- val rowType = new RowTypeInfo(INT_TYPE_INFO, STRING_TYPE_INFO,DOUBLE_TYPE_INFO)
-
- val cRowType = new CRowTypeInfo(rowType)
-
- val caseClassType: TypeInformation[CClass] = implicitly[TypeInformation[CClass]]
-
- val pojoType: TypeInformation[PojoClass] = TypeExtractor.createTypeInfo(classOf[PojoClass])
-
- val atomicType = INT_TYPE_INFO
-
- val genericRowType = new GenericTypeInfo[Row](classOf[Row])
-
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoPojoNames1(): Unit = {
- tEnv.getFieldInfo(
- pojoType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoAtomicName2(): Unit = {
- tEnv.getFieldInfo(
- atomicType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoTupleAlias3(): Unit = {
- tEnv.getFieldInfo(
- tupleType,
- Array(
- Alias(UnresolvedFieldReference("xxx"), "name1"),
- Alias(UnresolvedFieldReference("yyy"), "name2"),
- Alias(UnresolvedFieldReference("zzz"), "name3")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoCClassAlias3(): Unit = {
- tEnv.getFieldInfo(
- caseClassType,
- Array(
- Alias(UnresolvedFieldReference("xxx"), "name1"),
- Alias(UnresolvedFieldReference("yyy"), "name2"),
- Alias(UnresolvedFieldReference("zzz"), "name3")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoPojoAlias3(): Unit = {
- tEnv.getFieldInfo(
- pojoType,
- Array(
- Alias(UnresolvedFieldReference("xxx"), "name1"),
- Alias(UnresolvedFieldReference("yyy"), "name2"),
- Alias(UnresolvedFieldReference("zzz"), "name3")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoAtomicAlias(): Unit = {
- tEnv.getFieldInfo(
- atomicType,
- Array(
- Alias(UnresolvedFieldReference("name1"), "name2")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoGenericRowAlias(): Unit = {
- tEnv.getFieldInfo(
- genericRowType,
- Array(UnresolvedFieldReference("first")))
- }
-
- @Test(expected = classOf[TableException])
- def testRegisterExistingDataSet(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds1)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- // Must fail. Name is already in use.
- tEnv.registerDataSet("MyTable", ds2)
- }
-
- @Test(expected = classOf[TableException])
- def testScanUnregisteredTable(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- // Must fail. No table registered under that name.
- tEnv.scan("someTable")
- }
-
- @Test(expected = classOf[TableException])
- def testRegisterExistingTable(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", t1)
- val t2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
- // Must fail. Name is already in use.
- tEnv.registerDataSet("MyTable", t2)
- }
-
- @Test(expected = classOf[TableException])
- def testRegisterTableFromOtherEnv(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env, config)
- val tEnv2 = TableEnvironment.getTableEnvironment(env, config)
-
- val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv1)
- // Must fail. Table is bound to different TableEnvironment.
- tEnv2.registerTable("MyTable", t1)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithToManyFields(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- CollectionDataSets.get3TupleDataSet(env)
- // Must fail. Number of fields does not match.
- .toTable(tEnv, 'a, 'b, 'c, 'd)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithAmbiguousFields(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- CollectionDataSets.get3TupleDataSet(env)
- // Must fail. Field names not unique.
- .toTable(tEnv, 'a, 'b, 'b)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithNonFieldReference1(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // Must fail. as() can only have field references
- CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a + 1, 'b, 'c)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithNonFieldReference2(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // Must fail. as() can only have field references
- CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a as 'foo, 'b, 'c)
- }
-
- @Test(expected = classOf[TableException])
- def testGenericRow() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // use null value the enforce GenericType
- val dataSet = env.fromElements(Row.of(null))
- assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
- assertTrue(dataSet.getType().getTypeClass == classOf[Row])
-
- // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
- tableEnv.fromDataSet(dataSet)
- }
-
- @Test(expected = classOf[TableException])
- def testGenericRowWithAlias() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // use null value the enforce GenericType
- val dataSet = env.fromElements(Row.of(null))
- assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
- assertTrue(dataSet.getType().getTypeClass == classOf[Row])
-
- // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
- tableEnv.fromDataSet(dataSet, "nullField")
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala
deleted file mode 100644
index ea09f32..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream
-
-import java.lang.{Integer => JInt, Long => JLong}
-
-import org.apache.flink.api.java.tuple.{Tuple5 => JTuple5}
-import org.apache.flink.api.java.typeutils.TupleTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.streaming.api.environment.{StreamExecutionEnvironment => JStreamExecEnv}
-import org.apache.flink.table.api.java.{StreamTableEnvironment => JStreamTableEnv}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableEnvironment, Types}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-import org.mockito.Mockito.{mock, when}
-
-class TableEnvironmentTest extends TableTestBase {
-
- @Test
- def testProctimeAttribute(): Unit = {
- val util = streamTestUtil()
- // cannot replace an attribute with proctime
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime)
- }
-
- @Test
- def testReplacedRowtimeAttribute(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e)
- }
-
- @Test
- def testAppendedRowtimeAttribute(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime)
- }
-
- @Test
- def testRowtimeAndProctimeAttribute1(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime, 'pt.proctime)
- }
-
- @Test
- def testRowtimeAndProctimeAttribute2(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime, 'rt.rowtime)
- }
-
- @Test
- def testRowtimeAndProctimeAttribute3(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e, 'pt.proctime)
- }
-
- @Test
- def testProctimeAttributeParsed(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime")
- }
-
- @Test
- def testReplacingRowtimeAttributeParsed(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a.rowtime, b, c, d, e")
- }
-
- @Test
- def testAppedingRowtimeAttributeParsed(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a, b, c, d, e, rt.rowtime")
- }
-
- @Test
- def testRowtimeAndProctimeAttributeParsed1(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime, rt.rowtime")
- }
-
- @Test
- def testRowtimeAndProctimeAttributeParsed2(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "rt.rowtime, b, c, d, e, pt.proctime")
- }
-
- private def prepareSchemaExpressionParser:
- (JStreamTableEnv, DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]) = {
-
- val jStreamExecEnv = mock(classOf[JStreamExecEnv])
- when(jStreamExecEnv.getStreamTimeCharacteristic).thenReturn(TimeCharacteristic.EventTime)
- val jTEnv = TableEnvironment.getTableEnvironment(jStreamExecEnv)
-
- val sType = new TupleTypeInfo(Types.LONG, Types.INT, Types.STRING, Types.INT, Types.LONG)
- .asInstanceOf[TupleTypeInfo[JTuple5[JLong, JInt, String, JInt, JLong]]]
- val ds = mock(classOf[DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]])
- when(ds.getType).thenReturn(sType)
-
- (jTEnv, ds)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala
deleted file mode 100644
index 1f976b7..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Assert.{assertEquals, assertTrue}
-import org.junit.Test
-
-class TableSchemaTest extends TableTestBase {
-
- @Test
- def testStreamTableSchema(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
- val schema = table.getSchema
-
- assertEquals("a", schema.getColumnNames.apply(0))
- assertEquals("b", schema.getColumnNames.apply(1))
-
- assertEquals(Types.INT, schema.getTypes.apply(0))
- assertEquals(Types.STRING, schema.getTypes.apply(1))
-
- val expectedString = "root\n" +
- " |-- a: Integer\n" +
- " |-- b: String\n"
- assertEquals(expectedString, schema.toString)
-
- assertTrue(schema.getColumnName(3).isEmpty)
- assertTrue(schema.getType(-1).isEmpty)
- assertTrue(schema.getType("c").isEmpty)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala
deleted file mode 100644
index af9ce74..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- )
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "*" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowTest.scala
deleted file mode 100644
index a79d48f..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowTest.scala
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.junit.Test
-
-class OverWindowTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- streamUtil.addTable[(Int, String, Long)](
- "MyTable",
- 'a, 'b, 'c,
- 'proctime.proctime, 'rowtime.rowtime)
-
- @Test
- def testProcTimeBoundedPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN 2 preceding AND " +
- "CURRENT ROW) as cnt1, " +
- "sum(a) OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN 2 preceding AND " +
- "CURRENT ROW) as sum1 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS cnt1, CASE(>(w0$o0, 0), CAST(w0$o1), null) AS sum1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testProcTimeBoundedPartitionedRangeOver() = {
-
- val sqlQuery =
- "SELECT a, " +
- " AVG(c) OVER (PARTITION BY a ORDER BY proctime " +
- " RANGE BETWEEN INTERVAL '2' HOUR PRECEDING AND CURRENT ROW) AS avgA " +
- "FROM MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("partitionBy", "a"),
- term("orderBy", "proctime"),
- term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "proctime",
- "COUNT(c) AS w0$o0",
- "$SUM0(c) AS w0$o1"
- )
- ),
- term("select", "a", "/(CASE(>(w0$o0, 0)", "CAST(w0$o1), null), w0$o0) AS avgA")
- )
-
- streamUtil.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testProcTimeBoundedNonPartitionedRangeOver() = {
-
- val sqlQuery =
- "SELECT a, " +
- " COUNT(c) OVER (ORDER BY proctime " +
- " RANGE BETWEEN INTERVAL '10' SECOND PRECEDING AND CURRENT ROW) " +
- "FROM MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("orderBy", "proctime"),
- term("range", "BETWEEN 10000 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(c) AS w0$o0")
- ),
- term("select", "a", "w0$o0 AS $1")
- )
-
- streamUtil.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testProcTimeBoundedNonPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY proctime ROWS BETWEEN 2 preceding AND " +
- "CURRENT ROW)" +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS $1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
-
- @Test
- def testProcTimeUnboundedPartitionedRangeOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) as cnt1, " +
- "sum(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) as cnt2 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "proctime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testProcTimeUnboundedPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND " +
- "CURRENT ROW) " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- streamTableNode(0),
- term("partitionBy", "c"),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "b", "c", "proctime", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS $1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRangeOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) as cnt1, " +
- "sum(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) as cnt2 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "proctime")
- ),
- term("orderBy", "proctime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND " +
- "CURRENT ROW) " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- streamTableNode(0),
- term("orderBy", "proctime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "b", "c", "proctime", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS $1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 5 preceding AND " +
- "CURRENT ROW) " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN 5 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS $1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRangeOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY rowtime " +
- "RANGE BETWEEN INTERVAL '1' SECOND preceding AND CURRENT ROW) " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN 1000 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS $1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY rowtime ROWS BETWEEN 5 preceding AND " +
- "CURRENT ROW) " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN 5 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS $1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRangeOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY rowtime " +
- "RANGE BETWEEN INTERVAL '1' SECOND preceding AND CURRENT ROW) as cnt1 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN 1000 PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
- ),
- term("select", "c", "w0$o0 AS $1")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeUnboundedPartitionedRangeOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt1, " +
- "sum(a) OVER (PARTITION BY c ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt2 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeUnboundedPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt1, " +
- "sum(a) OVER (PARTITION BY c ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt2 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("partitionBy", "c"),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "rowtime",
- "COUNT(a) AS w0$o0",
- "$SUM0(a) AS w0$o1"
- )
- ),
- term(
- "select",
- "c",
- "w0$o0 AS cnt1",
- "CASE(>(w0$o0, 0)",
- "CAST(w0$o1), null) AS cnt2"
- )
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeUnboundedNonPartitionedRangeOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt1, " +
- "sum(a) OVER (ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt2 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
- ),
- term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- @Test
- def testRowTimeUnboundedNonPartitionedRowsOver() = {
- val sql = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt1, " +
- "sum(a) OVER (ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt2 " +
- "from MyTable"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "c", "rowtime")
- ),
- term("orderBy", "rowtime"),
- term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
- term(
- "select",
- "a",
- "c",
- "rowtime",
- "COUNT(a) AS w0$o0",
- "$SUM0(a) AS w0$o1"
- )
- ),
- term(
- "select",
- "c",
- "w0$o0 AS cnt1",
- "CASE(>(w0$o0, 0)",
- "CAST(w0$o1), null) AS cnt2"
- )
- )
- streamUtil.verifySql(sql, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortITCase.scala
deleted file mode 100644
index 2340591..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortITCase.scala
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.sink.RichSinkFunction
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.scala.stream.sql.SortITCase.StringRowSelectorSink
-import org.apache.flink.table.api.scala.stream.sql.TimeTestUtil.EventTimeSourceFunction
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.types.Row
-
-import org.junit.Assert._
-import org.junit._
-
-import scala.collection.mutable
-
-class SortITCase extends StreamingWithStateTestBase {
-
- @Test
- def testEventTimeOrderBy(): Unit = {
- val data = Seq(
- Left((1500L, (1L, 15, "Hello"))),
- Left((1600L, (1L, 16, "Hello"))),
- Left((1000L, (1L, 1, "Hello"))),
- Left((2000L, (2L, 2, "Hello"))),
- Right(1000L),
- Left((2000L, (2L, 2, "Hello"))),
- Left((2000L, (2L, 3, "Hello"))),
- Left((3000L, (3L, 3, "Hello"))),
- Left((2000L, (3L, 1, "Hello"))),
- Right(2000L),
- Left((4000L, (4L, 4, "Hello"))),
- Right(3000L),
- Left((5000L, (5L, 5, "Hello"))),
- Right(5000L),
- Left((6000L, (6L, 65, "Hello"))),
- Left((6000L, (6L, 6, "Hello"))),
- Left((6000L, (6L, 67, "Hello"))),
- Left((6000L, (6L, -1, "Hello"))),
- Left((6000L, (6L, 6, "Hello"))),
- Right(7000L),
- Left((9000L, (6L, 9, "Hello"))),
- Left((8500L, (6L, 18, "Hello"))),
- Left((9000L, (6L, 7, "Hello"))),
- Right(10000L),
- Left((10000L, (7L, 7, "Hello World"))),
- Left((11000L, (7L, 77, "Hello World"))),
- Left((11000L, (7L, 17, "Hello World"))),
- Right(12000L),
- Left((14000L, (7L, 18, "Hello World"))),
- Right(14000L),
- Left((15000L, (8L, 8, "Hello World"))),
- Right(17000L),
- Left((20000L, (20L, 20, "Hello World"))),
- Right(19000L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env.addSource(new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT b FROM T1 ORDER BY rowtime, b ASC "
-
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StringRowSelectorSink(0)).setParallelism(1)
- env.execute()
-
- val expected = mutable.MutableList(
- "1", "15", "16",
- "1", "2", "2", "3",
- "3",
- "4",
- "5",
- "-1", "6", "6", "65", "67",
- "18", "7", "9",
- "7", "17", "77",
- "18",
- "8",
- "20")
- assertEquals(expected, SortITCase.testResults)
- }
-}
-
-object SortITCase {
-
- final class StringRowSelectorSink(private val field:Int) extends RichSinkFunction[Row]() {
- def invoke(value: Row) {
- testResults.synchronized {
- testResults += value.getField(field).toString
- }
- }
- }
-
- var testResults: mutable.MutableList[String] = mutable.MutableList.empty[String]
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortTest.scala
deleted file mode 100644
index 1d50fc1..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SortTest.scala
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.junit.Test
-
-class SortTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c,
- 'proctime.proctime, 'rowtime.rowtime)
-
- @Test
- def testSortProcessingTime() = {
-
- val sqlQuery = "SELECT a FROM MyTable ORDER BY proctime, c"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode("DataStreamSort",
- streamTableNode(0),
- term("orderBy", "proctime ASC", "c ASC")),
- term("select", "a", "TIME_MATERIALIZATION(proctime) AS proctime", "c"))
-
- streamUtil.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testSortRowTime() = {
-
- val sqlQuery = "SELECT a FROM MyTable ORDER BY rowtime, c"
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode("DataStreamSort",
- streamTableNode(0),
- term("orderBy", "rowtime ASC, c ASC")),
- term("select", "a", "TIME_MATERIALIZATION(rowtime) AS rowtime", "c"))
-
- streamUtil.verifySql(sqlQuery, expected)
- }
-
- // test should fail because time order is descending
- @Test(expected = classOf[TableException])
- def testSortProcessingTimeDesc() = {
-
- val sqlQuery = "SELECT a FROM MyTable ORDER BY proctime DESC, c"
- streamUtil.verifySql(sqlQuery, "")
- }
-
-
- // test should fail because time is not the primary order field
- @Test(expected = classOf[TableException])
- def testSortProcessingTimeSecondaryField() = {
-
- val sqlQuery = "SELECT a FROM MyTable ORDER BY c, proctime"
- streamUtil.verifySql(sqlQuery, "")
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/TimeTestUtil.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/TimeTestUtil.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/TimeTestUtil.scala
deleted file mode 100644
index b883870..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/TimeTestUtil.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.streaming.api.functions.source.SourceFunction
-import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
-import org.apache.flink.streaming.api.watermark.Watermark
-
-object TimeTestUtil {
-
- class EventTimeSourceFunction[T](
- dataWithTimestampList: Seq[Either[(Long, T), Long]]) extends SourceFunction[T] {
- override def run(ctx: SourceContext[T]): Unit = {
- dataWithTimestampList.foreach {
- case Left(t) => ctx.collectWithTimestamp(t._2, t._1)
- case Right(w) => ctx.emitWatermark(new Watermark(w))
- }
- }
-
- override def cancel(): Unit = ???
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/UserDefinedTableFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/UserDefinedTableFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/UserDefinedTableFunctionTest.scala
deleted file mode 100644
index 58eedd0..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/UserDefinedTableFunctionTest.scala
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.{HierarchyTableFunction, PojoTableFunc, TableFunc2}
-import org.apache.flink.table.utils._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class UserDefinedTableFunctionTest extends TableTestBase {
-
- @Test
- def testCrossJoin(): Unit = {
- val util = streamTestUtil()
- val func1 = new TableFunc1
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func1", func1)
-
- val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c)) AS T(s)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "func1($cor0.c)"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery, expected)
-
- // test overloading
-
- val sqlQuery2 = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c, '$')) AS T(s)"
-
- val expected2 = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "func1($cor0.c, '$')"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery2, expected2)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val util = streamTestUtil()
- val func1 = new TableFunc1
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func1", func1)
-
- val sqlQuery = "SELECT c, s FROM MyTable LEFT JOIN LATERAL TABLE(func1(c)) AS T(s) ON TRUE"
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "func1($cor0.c)"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "LEFT")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testCustomType(): Unit = {
- val util = streamTestUtil()
- val func2 = new TableFunc2
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func2", func2)
-
- val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "func2($cor0.c)"),
- term("function", func2.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
- "VARCHAR(2147483647) f0, INTEGER f1)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS name", "f1 AS len")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testHierarchyType(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = new HierarchyTableFunction
- util.addFunction("hierarchy", function)
-
- val sqlQuery = "SELECT c, T.* FROM MyTable, LATERAL TABLE(hierarchy(c)) AS T(name, adult, len)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "hierarchy($cor0.c)"),
- term("function", function.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
- " VARCHAR(2147483647) f0, BOOLEAN f1, INTEGER f2)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS name", "f1 AS adult", "f2 AS len")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testPojoType(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = new PojoTableFunc
- util.addFunction("pojo", function)
-
- val sqlQuery = "SELECT c, name, age FROM MyTable, LATERAL TABLE(pojo(c))"
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "pojo($cor0.c)"),
- term("function", function.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
- " INTEGER age, VARCHAR(2147483647) name)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "name", "age")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testFilter(): Unit = {
- val util = streamTestUtil()
- val func2 = new TableFunc2
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func2", func2)
-
- val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len) " +
- "WHERE len > 2"
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "func2($cor0.c)"),
- term("function", func2.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
- "VARCHAR(2147483647) f0, INTEGER f1)"),
- term("joinType", "INNER"),
- term("condition", ">($1, 2)")
- ),
- term("select", "c", "f0 AS name", "f1 AS len")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testScalarFunction(): Unit = {
- val util = streamTestUtil()
- val func1 = new TableFunc1
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- util.addFunction("func1", func1)
-
- val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(SUBSTRING(c, 2))) AS T(s)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", "func1(SUBSTRING($cor0.c, 2))"),
- term("function", func1.getClass.getCanonicalName),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "f0 AS s")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-}
[13/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SortITCase.scala
deleted file mode 100644
index 09d3c04..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SortITCase.scala
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.api.scala.{ExecutionEnvironment, _}
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.SortTestUtils._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-@RunWith(classOf[Parameterized])
-class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- private def getExecutionEnvironment = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- // set the parallelism explicitly to make sure the query is executed in
- // a distributed manner
- env.setParallelism(3)
- env
- }
-
- @Test
- def testOrderByDesc(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.desc)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- - x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByAsc(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.asc)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByMultipleFieldsDifferentDirections(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_2.asc, '_1.desc)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- (x.productElement(1).asInstanceOf[Long], - x.productElement(0).asInstanceOf[Int]) )
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- def rowOrdering = Ordering.by((r : Row) => {
- // ordering for this tuple will fall into the previous defined tupleOrdering,
- // so we just need to return the field by their defining sequence
- (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
- })
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(rowOrdering)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByOffset(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.asc).limit(3)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings, 3, 21)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByOffsetAndFetch(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.desc).limit(3, 5)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- - x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings, 3, 8)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByFetch(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.asc).limit(0, 5)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- implicit def rowOrdering = Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int])
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala
index 4d7f6cb..079b10a 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala
@@ -17,97 +17,15 @@
*/
package org.apache.flink.table.api.scala.batch.table
-import org.apache.flink.api.java.{DataSet => JDataSet, ExecutionEnvironment => JavaExecutionEnv}
+import org.apache.flink.api.scala._
import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.{DataSet, ExecutionEnvironment => ScalaExecutionEnv, _}
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.types.Row
import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{PojoTableFunc, TableFunc2, _}
-import org.apache.flink.table.api.{Table, TableEnvironment, Types}
+import org.apache.flink.table.utils._
import org.junit.Test
-import org.mockito.Mockito._
class UserDefinedTableFunctionTest extends TableTestBase {
@Test
- def testJavaScalaTableAPIEquality(): Unit = {
- // mock
- val ds = mock(classOf[DataSet[Row]])
- val jDs = mock(classOf[JDataSet[Row]])
- val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
- when(ds.javaSet).thenReturn(jDs)
- when(jDs.getType).thenReturn(typeInfo)
-
- // Scala environment
- val env = mock(classOf[ScalaExecutionEnv])
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val in1 = ds.toTable(tableEnv).as('a, 'b, 'c)
-
- // Java environment
- val javaEnv = mock(classOf[JavaExecutionEnv])
- val javaTableEnv = TableEnvironment.getTableEnvironment(javaEnv)
- val in2 = javaTableEnv.fromDataSet(jDs).as("a, b, c")
- javaTableEnv.registerTable("MyTable", in2)
-
- // test cross join
- val func1 = new TableFunc1
- javaTableEnv.registerFunction("func1", func1)
- var scalaTable = in1.join(func1('c) as 's).select('c, 's)
- var javaTable = in2.join(new Table(javaTableEnv, "func1(c).as(s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test left outer join
- scalaTable = in1.leftOuterJoin(func1('c) as 's).select('c, 's)
- javaTable = in2.leftOuterJoin(new Table(javaTableEnv, "as(func1(c), s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test overloading
- scalaTable = in1.join(func1('c, "$") as 's).select('c, 's)
- javaTable = in2.join(new Table(javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test custom result type
- val func2 = new TableFunc2
- javaTableEnv.registerFunction("func2", func2)
- scalaTable = in1.join(func2('c) as ('name, 'len)).select('c, 'name, 'len)
- javaTable = in2.join(new Table(javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
- verifyTableEquals(scalaTable, javaTable)
-
- // test hierarchy generic type
- val hierarchy = new HierarchyTableFunction
- javaTableEnv.registerFunction("hierarchy", hierarchy)
- scalaTable = in1.join(hierarchy('c) as ('name, 'adult, 'len))
- .select('c, 'name, 'len, 'adult)
- javaTable = in2.join(new Table(javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
- .select("c, name, len, adult")
- verifyTableEquals(scalaTable, javaTable)
-
- // test pojo type
- val pojo = new PojoTableFunc
- javaTableEnv.registerFunction("pojo", pojo)
- scalaTable = in1.join(pojo('c))
- .select('c, 'name, 'age)
- javaTable = in2.join(new Table(javaTableEnv, "pojo(c)"))
- .select("c, name, age")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with filter
- scalaTable = in1.join(func2('c) as ('name, 'len))
- .select('c, 'name, 'len).filter('len > 2)
- javaTable = in2.join(new Table(javaTableEnv, "func2(c) as (name, len)"))
- .select("c, name, len").filter("len > 2")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with scalar function
- scalaTable = in1.join(func1('c.substring(2)) as 's)
- .select('a, 'c, 's)
- javaTable = in2.join(new Table(javaTableEnv, "func1(substring(c, 2)) as (s)"))
- .select("a, c, s")
- verifyTableEquals(scalaTable, javaTable)
- }
-
- @Test
def testCrossJoin(): Unit = {
val util = batchTestUtil()
val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala
index eda958c..b085160 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala
@@ -19,24 +19,19 @@
package org.apache.flink.table.api.scala.batch.table.stringexpr
import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
+import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.scala.batch.utils.LogicalPlanFormatUtils
import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.utils.TableTestBase
import org.junit._
class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testAggregationTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
val t1 = t.select('_1.sum, '_1.sum0, '_1.min, '_1.max, '_1.count, '_1.avg)
val t2 = t.select("_1.sum, _1.sum0, _1.min, _1.max, _1.count, _1.avg")
@@ -46,13 +41,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testWorkingAggregationDataTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Byte, Short, Int, Long, Float, Double, String)]("Table7")
val t1 = t.select('_1.avg, '_2.avg, '_3.avg, '_4.avg, '_5.avg, '_6.avg, '_7.count)
val t2 = t.select("_1.avg, _2.avg, _3.avg, _4.avg, _5.avg, _6.avg, _7.count")
@@ -62,13 +52,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = env.fromElements(
- (1: Byte, 1: Short),
- (2: Byte, 2: Short)).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Byte, Short)]("Table2")
val t1 = t.select('_1.avg, '_1.sum, '_1.count, '_2.avg, '_2.sum)
val t2 = t.select("_1.avg, _1.sum, _1.count, _2.avg, _2.sum")
@@ -78,11 +63,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testAggregationWithArithmetic(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2")
val t1 = t.select(('_1 + 2).avg + 2, '_2.count + 5)
val t2 = t.select("(_1 + 2).avg + 2, _2.count + 5")
@@ -92,11 +74,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testAggregationWithTwoCount(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2")
val t1 = t.select('_1.count, '_2.count)
val t2 = t.select("_1.count, _2.count")
@@ -106,13 +85,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testAggregationAfterProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Byte, Short, Int, Long, Float, Double, String)]("Table7")
val t1 = t.select('_1, '_2, '_3)
.select('_1.avg, '_2.sum, '_3.count)
@@ -125,10 +99,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testDistinct(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val distinct = ds.select('b).distinct()
val distinct2 = ds.select("b").distinct()
@@ -138,10 +110,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testDistinctAfterAggregate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
val distinct = ds.groupBy('a, 'e).select('e).distinct()
val distinct2 = ds.groupBy("a, e").select("e").distinct()
@@ -154,11 +124,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupedAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val t1 = t.groupBy('b).select('b, 'a.sum)
val t2 = t.groupBy("b").select("b, a.sum")
@@ -168,11 +135,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupingKeyForwardIfNotUsed(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val t1 = t.groupBy('b).select('a.sum)
val t2 = t.groupBy("b").select("a.sum")
@@ -182,11 +146,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupNoAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val t1 = t
.groupBy('b)
@@ -205,11 +166,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupedAggregateWithConstant1(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val t1 = t.select('a, 4 as 'four, 'b)
.groupBy('four, 'a)
@@ -224,11 +182,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupedAggregateWithConstant2(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val t1 = t.select('b, 4 as 'four, 'a)
.groupBy('b, 'four)
@@ -242,11 +197,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupedAggregateWithExpression(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
val t1 = t.groupBy('e, 'b % 3)
.select('c.min, 'e, 'a.avg, 'd.count)
@@ -258,11 +210,8 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupedAggregateWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val t1 = t.groupBy('b)
.select('b, 'a.sum)
@@ -295,16 +244,13 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testAggregateWithUDAGG(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val myCnt = new CountAggFunction
- tEnv.registerFunction("myCnt", myCnt)
+ util.tableEnv.registerFunction("myCnt", myCnt)
val myWeightedAvg = new WeightedAvgWithMergeAndReset
- tEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
val t1 = t.select(myCnt('a) as 'aCnt, myWeightedAvg('b, 'a) as 'wAvg)
val t2 = t.select("myCnt(a) as aCnt, myWeightedAvg(b, a) as wAvg")
@@ -323,16 +269,14 @@ class AggregationsStringExpressionTest extends TableTestBase {
@Test
def testGroupedAggregateWithUDAGG(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
val myCnt = new CountAggFunction
- tEnv.registerFunction("myCnt", myCnt)
+ util.tableEnv.registerFunction("myCnt", myCnt)
val myWeightedAvg = new WeightedAvgWithMergeAndReset
- tEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
val t1 = t.groupBy('b)
.select('b, myCnt('a) + 9 as 'aCnt, myWeightedAvg('b, 'a) * 2 as 'wAvg, myWeightedAvg('a, 'a))
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala
index 381b8c8..9736ec1 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala
@@ -21,21 +21,20 @@ package org.apache.flink.table.api.scala.batch.table.stringexpr
import java.sql.{Date, Time, Timestamp}
import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.api.scala.util.CollectionDataSets.CustomType
+import org.apache.flink.table.api.Types
import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.scala.batch.utils.LogicalPlanFormatUtils
-import org.apache.flink.table.api.{TableEnvironment, Types}
import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.utils.TableTestBase
import org.junit._
-class CalcStringExpressionTest {
+class CalcStringExpressionTest extends TableTestBase {
@Test
def testSimpleSelectAllWithAs(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = t.select('a, 'b, 'c)
val t2 = t.select("a, b, c")
@@ -48,10 +47,8 @@ class CalcStringExpressionTest {
@Test
def testSimpleSelectWithNaming(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
val t1 = t
.select('_1 as 'a, '_2 as 'b, '_1 as 'c)
@@ -69,10 +66,8 @@ class CalcStringExpressionTest {
@Test
def testSimpleSelectRenameAll(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
val t1 = t
.select('_1 as 'a, '_2 as 'b, '_3 as 'c)
@@ -90,10 +85,8 @@ class CalcStringExpressionTest {
@Test
def testSelectStar(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = t.select('*)
val t2 = t.select("*")
@@ -106,10 +99,8 @@ class CalcStringExpressionTest {
@Test
def testAllRejectingFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = ds.filter( Literal(false) )
val t2 = ds.filter("faLsE")
@@ -122,10 +113,8 @@ class CalcStringExpressionTest {
@Test
def testAllPassingFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = ds.filter( Literal(true) )
val t2 = ds.filter("trUe")
@@ -138,10 +127,8 @@ class CalcStringExpressionTest {
@Test
def testFilterOnStringTupleField(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = ds.filter( 'c.like("%world%") )
val t2 = ds.filter("c.like('%world%')")
@@ -154,10 +141,8 @@ class CalcStringExpressionTest {
@Test
def testFilterOnIntegerTupleField(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = ds.filter( 'a % 2 === 0 )
val t2 = ds.filter( "a % 2 = 0 ")
@@ -170,10 +155,8 @@ class CalcStringExpressionTest {
@Test
def testNotEquals(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = ds.filter( 'a % 2 !== 0 )
val t2 = ds.filter("a % 2 <> 0")
@@ -186,10 +169,8 @@ class CalcStringExpressionTest {
@Test
def testDisjunctivePredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = ds.filter( 'a < 2 || 'a > 20)
val t2 = ds.filter("a < 2 || a > 20")
@@ -202,10 +183,8 @@ class CalcStringExpressionTest {
@Test
def testConsecutiveFilters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = ds.filter('a % 2 !== 0).filter('b % 2 === 0)
val t2 = ds.filter("a % 2 != 0").filter("b % 2 = 0")
@@ -218,10 +197,8 @@ class CalcStringExpressionTest {
@Test
def testFilterBasicType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.getStringDataSet(env).toTable(tEnv, 'a)
+ val util = batchTestUtil()
+ val ds = util.addTable[String]("Table3",'a)
val t1 = ds.filter( 'a.like("H%") )
val t2 = ds.filter( "a.like('H%')" )
@@ -234,11 +211,8 @@ class CalcStringExpressionTest {
@Test
def testFilterOnCustomType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.getCustomTypeDataSet(env)
- val t = ds.toTable(tEnv, 'myInt as 'i, 'myLong as 'l, 'myString as 's)
+ val util = batchTestUtil()
+ val t = util.addTable[CustomType]("Table3",'myInt as 'i, 'myLong as 'l, 'myString as 's)
val t1 = t.filter( 's.like("%a%") )
val t2 = t.filter("s.like('%a%')")
@@ -251,10 +225,8 @@ class CalcStringExpressionTest {
@Test
def testSimpleCalc(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
val t1 = t.select('_1, '_2, '_3)
.where('_1 < 7)
@@ -272,10 +244,8 @@ class CalcStringExpressionTest {
@Test
def testCalcWithTwoFilters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
val t1 = t.select('_1, '_2, '_3)
.where('_1 < 7 && '_2 === 3)
@@ -297,10 +267,8 @@ class CalcStringExpressionTest {
@Test
def testCalcWithAggregation(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3")
val t1 = t.select('_1, '_2, '_3)
.where('_1 < 15)
@@ -325,11 +293,9 @@ class CalcStringExpressionTest {
@Test
def testCalcJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.select('a, 'b).join(ds2).where('b === 'e).select('a, 'b, 'd, 'e, 'f)
.where('b > 1).select('a, 'd).where('d === 2)
@@ -344,17 +310,9 @@ class CalcStringExpressionTest {
@Test
def testAdvancedDataTypes(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = env
- .fromElements((
- BigDecimal("78.454654654654654").bigDecimal,
- BigDecimal("4E+9999").bigDecimal,
- Date.valueOf("1984-07-12"),
- Time.valueOf("14:34:24"),
- Timestamp.valueOf("1984-07-12 14:34:24")))
- .toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val util = batchTestUtil()
+ val t = util
+ .addTable[(BigDecimal, BigDecimal, Date, Time, Timestamp)]("Table5", 'a, 'b, 'c, 'd, 'e)
val t1 = t.select('a, 'b, 'c, 'd, 'e, BigDecimal("11.2"), BigDecimal("11.2").bigDecimal,
"1984-07-12".cast(Types.SQL_DATE), "14:34:24".cast(Types.SQL_TIME),
@@ -371,9 +329,8 @@ class CalcStringExpressionTest {
@Test
def testIntegerBiggerThan128(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val t = env.fromElements((300, 1L, "Hello")).toTable(tableEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
val t1 = t.filter('a === 300)
val t2 = t.filter("a = 300")
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala
index 8a2db41..8ca5745 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala
@@ -27,7 +27,7 @@ import org.junit._
class CastingStringExpressionTest {
@Test
- def testNumericAutocastInArithmetic() {
+ def testNumericAutoCastInArithmetic() {
val env = ExecutionEnvironment.getExecutionEnvironment
val tableEnv = TableEnvironment.getTableEnvironment(env)
@@ -47,7 +47,7 @@ class CastingStringExpressionTest {
@Test
@throws[Exception]
- def testNumericAutocastInComparison() {
+ def testNumericAutoCastInComparison() {
val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
val tableEnv = TableEnvironment.getTableEnvironment(env)
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala
index b2f683c..067441d 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala
@@ -19,22 +19,19 @@
package org.apache.flink.table.api.scala.batch.table.stringexpr
import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.scala.batch.utils.LogicalPlanFormatUtils
import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.utils.TableTestBase
import org.junit._
-class JoinStringExpressionTest {
+class JoinStringExpressionTest extends TableTestBase {
@Test
def testJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1Scala = ds1.join(ds2).where('b === 'e).select('c, 'g)
val t1Java = ds1.join(ds2).where("b === e").select("c, g")
@@ -47,12 +44,9 @@ class JoinStringExpressionTest {
@Test
def testJoinWithFilter(): Unit = {
-
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1Scala = ds1.join(ds2).where('b === 'e && 'b < 2).select('c, 'g)
val t1Java = ds1.join(ds2).where("b === e && b < 2").select("c, g")
@@ -65,11 +59,9 @@ class JoinStringExpressionTest {
@Test
def testJoinWithJoinFilter(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1Scala = ds1.join(ds2).where('b === 'e && 'a < 6 && 'h < 'b).select('c, 'g)
val t1Java = ds1.join(ds2).where("b === e && a < 6 && h < b").select("c, g")
@@ -82,11 +74,9 @@ class JoinStringExpressionTest {
@Test
def testJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1Scala = ds1.join(ds2).filter('a === 'd && 'b === 'h).select('c, 'g)
val t1Java = ds1.join(ds2).filter("a === d && b === h").select("c, g")
@@ -99,11 +89,9 @@ class JoinStringExpressionTest {
@Test
def testJoinWithAggregation(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1Scala = ds1.join(ds2).where('a === 'd).select('g.count)
val t1Java = ds1.join(ds2).where("a === d").select("g.count")
@@ -118,11 +106,9 @@ class JoinStringExpressionTest {
@Test
def testJoinWithGroupedAggregation(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.join(ds2)
.where('a === 'd)
@@ -143,12 +129,10 @@ class JoinStringExpressionTest {
@Test
def testJoinPushThroughJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
- val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'j, 'k, 'l)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds3 = util.addTable[(Int, Long, String)]("Table4",'j, 'k, 'l)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.join(ds2)
.where(Literal(true))
@@ -169,11 +153,9 @@ class JoinStringExpressionTest {
@Test
def testJoinWithDisjunctivePred(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.join(ds2).filter('a === 'd && ('b === 'e || 'b === 'e - 10)).select('c, 'g)
val t2 = ds1.join(ds2).filter("a = d && (b = e || b = e - 10)").select("c, g")
@@ -186,11 +168,9 @@ class JoinStringExpressionTest {
@Test
def testJoinWithExpressionPreds(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.join(ds2).filter('b === 'h + 1 && 'a - 1 === 'd + 2).select('c, 'g)
val t2 = ds1.join(ds2).filter("b = h + 1 && a - 1 = d + 2").select("c, g")
@@ -203,12 +183,9 @@ class JoinStringExpressionTest {
@Test
def testLeftJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.leftOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
val t2 = ds1.leftOuterJoin(ds2, "a = d && b = h").select("c, g")
@@ -221,12 +198,9 @@ class JoinStringExpressionTest {
@Test
def testRightJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.rightOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
val t2 = ds1.rightOuterJoin(ds2, "a = d && b = h").select("c, g")
@@ -239,12 +213,9 @@ class JoinStringExpressionTest {
@Test
def testFullOuterJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
val t1 = ds1.fullOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
val t2 = ds1.fullOuterJoin(ds2, "a = d && b = h").select("c, g")
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
new file mode 100644
index 0000000..8cf9979
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.types.Row
+import org.apache.flink.table.utils.{PojoTableFunc, TableFunc2, _}
+import org.apache.flink.table.api.{Table, Types}
+import org.junit.Test
+
+class UserDefinedTableFunctionStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testJoin(): Unit = {
+ val util = batchTestUtil()
+
+ val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
+ val sTab = util.addTable[(Int, Long, String)]("Table1", 'a, 'b, 'c)
+ val jTab = util.addJavaTable[Row](typeInfo, "Table2", "a, b, c")
+
+ // test cross join
+ val func1 = new TableFunc1
+ util.javaTableEnv.registerFunction("func1", func1)
+ var scalaTable = sTab.join(func1('c) as 's).select('c, 's)
+ var javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c).as(s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test left outer join
+ scalaTable = sTab.leftOuterJoin(func1('c) as 's).select('c, 's)
+ javaTable = jTab.leftOuterJoin(new Table(util.javaTableEnv, "as(func1(c), s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test overloading
+ scalaTable = sTab.join(func1('c, "$") as 's).select('c, 's)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test custom result type
+ val func2 = new TableFunc2
+ util.javaTableEnv.registerFunction("func2", func2)
+ scalaTable = sTab.join(func2('c) as('name, 'len)).select('c, 'name, 'len)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test hierarchy generic type
+ val hierarchy = new HierarchyTableFunction
+ util.javaTableEnv.registerFunction("hierarchy", hierarchy)
+ scalaTable = sTab.join(hierarchy('c) as('name, 'adult, 'len)).select('c, 'name, 'len, 'adult)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
+ .select("c, name, len, adult")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test pojo type
+ val pojo = new PojoTableFunc
+ util.javaTableEnv.registerFunction("pojo", pojo)
+ scalaTable = sTab.join(pojo('c)).select('c, 'name, 'age)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "pojo(c)")).select("c, name, age")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with filter
+ scalaTable = sTab.join(func2('c) as('name, 'len)).select('c, 'name, 'len).filter('len > 2)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func2(c) as (name, len)"))
+ .select("c, name, len").filter("len > 2")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with scalar function
+ scalaTable = sTab.join(func1('c.substring(2)) as 's).select('a, 'c, 's)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func1(substring(c, 2)) as (s)")).select("a, c, s")
+ verifyTableEquals(scalaTable, javaTable)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala
index 8e90fa8..25ecd96 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala
@@ -19,24 +19,24 @@
package org.apache.flink.table.api.scala.batch.table.validation
import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMergeAndReset}
import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
import org.junit._
-class AggregationsValidationTest {
+class AggregationsValidationTest extends TableTestBase {
/**
* OVER clause is necessary for [[OverAgg0]] window function.
*/
@Test(expected = classOf[ValidationException])
def testOverAggregation(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+
val overAgg = new OverAgg0
- input.select('c.count, overAgg('b, 'a))
+ t.select('c.count, overAgg('b, 'a))
}
@Test(expected = classOf[ValidationException])
@@ -52,199 +52,176 @@ class AggregationsValidationTest {
@Test(expected = classOf[ValidationException])
def testNoNestedAggregations(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(String, Int)]("Table2")
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- env.fromElements(("Hello", 1)).toTable(tEnv)
- // Must fail. Sum aggregation can not be chained.
- .select('_2.sum.sum)
+ // Must fail. Sum aggregation can not be chained.
+ t.select('_2.sum.sum)
}
@Test(expected = classOf[ValidationException])
def testGroupingOnNonExistentField(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- // must fail. '_foo not a valid field
- .groupBy('_foo)
- .select('a.avg)
+ // must fail. '_foo not a valid field
+ t.groupBy('_foo)
+ .select('a.avg)
}
@Test(expected = classOf[ValidationException])
def testGroupingInvalidSelection(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('a, 'b)
- // must fail. 'c is not a grouping key or aggregation
- .select('c)
+ t.groupBy('a, 'b)
+ // must fail. 'c is not a grouping key or aggregation
+ .select('c)
}
@Test(expected = classOf[ValidationException])
def testAggregationOnNonExistingField(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- // Must fail. Field 'foo does not exist.
- .select('foo.avg)
+ // Must fail. Field 'foo does not exist.
+ t.select('foo.avg)
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testInvalidUdAggArgs() {
- val env= ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val myWeightedAvg = new WeightedAvgWithMergeAndReset
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- // must fail. UDAGG does not accept String type
- .select(myWeightedAvg('c, 'a))
+ // must fail. UDAGG does not accept String type
+ t.select(myWeightedAvg('c, 'a))
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testGroupingInvalidUdAggArgs() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val myWeightedAvg = new WeightedAvgWithMergeAndReset
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- .groupBy('b)
- // must fail. UDAGG does not accept String type
- .select(myWeightedAvg('c, 'a))
+ t.groupBy('b)
+ // must fail. UDAGG does not accept String type
+ .select(myWeightedAvg('c, 'a))
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testGroupingNestedUdAgg() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val myWeightedAvg = new WeightedAvgWithMergeAndReset
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- .groupBy('c)
- // must fail. UDAGG does not accept String type
- .select(myWeightedAvg(myWeightedAvg('b, 'a), 'a))
+ t.groupBy('c)
+ // must fail. UDAGG does not accept String type
+ .select(myWeightedAvg(myWeightedAvg('b, 'a), 'a))
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testAggregationOnNonExistingFieldJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv)
- table.select("foo.avg")
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ t.select("foo.avg")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testNonWorkingAggregationDataTypesJava() {
- val env= ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements((1f, "Hello")).toTable(tableEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2",'b, 'c)
// Must fail. Cannot compute SUM aggregate on String field.
- table.select("f1.sum")
+ t.select("c.sum")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testNoNestedAggregationsJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements((1f, "Hello")).toTable(tableEnv)
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, String)]("Table2",'b, 'c)
// Must fail. Aggregation on aggregation not allowed.
- table.select("f0.sum.sum")
+ t.select("b.sum.sum")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testGroupingOnNonExistentFieldJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- // must fail. Field foo is not in input
- .groupBy("foo")
- .select("a.avg")
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ // must fail. Field foo is not in input
+ t.groupBy("foo")
+ .select("a.avg")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testGroupingInvalidSelectionJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- .groupBy("a, b")
- // must fail. Field c is not a grouping key or aggregation
- .select("c")
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ t.groupBy("a, b")
+ // must fail. Field c is not a grouping key or aggregation
+ .select("c")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testUnknownUdAggJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- // must fail. unknown is not known
- .select("unknown(c)")
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ // must fail. unknown is not known
+ t.select("unknown(c)")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testGroupingUnknownUdAggJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- .groupBy("a, b")
- // must fail. unknown is not known
- .select("unknown(c)")
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
+
+ t.groupBy("a, b")
+ // must fail. unknown is not known
+ .select("unknown(c)")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testInvalidUdAggArgsJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val myWeightedAvg = new WeightedAvgWithMergeAndReset
- tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- // must fail. UDAGG does not accept String type
- .select("myWeightedAvg(c, a)")
+ // must fail. UDAGG does not accept String type
+ t.select("myWeightedAvg(c, a)")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testGroupingInvalidUdAggArgsJava() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
val myWeightedAvg = new WeightedAvgWithMergeAndReset
- tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
+ util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
- val input = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
- input
- .groupBy("b")
- // must fail. UDAGG does not accept String type
- .select("myWeightedAvg(c, a)")
+ t.groupBy("b")
+ // must fail. UDAGG does not accept String type
+ .select("myWeightedAvg(c, a)")
}
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala
index 846585b..e2a5dac 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala
@@ -19,117 +19,105 @@
package org.apache.flink.table.api.scala.batch.table.validation
import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.{TableEnvironment, TableException, ValidationException}
import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
import org.apache.flink.types.Row
import org.junit.Assert._
import org.junit._
-class CalcValidationTest {
+class CalcValidationTest extends TableTestBase {
@Test(expected = classOf[ValidationException])
def testSelectInvalidFieldFields(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
// must fail. Field 'foo does not exist
.select('a, 'foo)
}
@Test(expected = classOf[ValidationException])
def testSelectAmbiguousRenaming(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
// must fail. 'a and 'b are both renamed to 'foo
.select('a + 1 as 'foo, 'b + 2 as 'foo).toDataSet[Row].print()
}
@Test(expected = classOf[ValidationException])
def testSelectAmbiguousRenaming2(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
// must fail. 'a and 'b are both renamed to 'a
.select('a, 'b as 'a).toDataSet[Row].print()
}
@Test(expected = classOf[ValidationException])
def testFilterInvalidFieldName(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
// must fail. Field 'foo does not exist
- ds.filter( 'foo === 2 )
+ t.filter( 'foo === 2 )
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testSelectInvalidField() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
// Must fail. Field foo does not exist
- ds.select("a + 1, foo + 2")
+ t.select("a + 1, foo + 2")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testSelectAmbiguousFieldNames() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
// Must fail. Field foo does not exist
- ds.select("a + 1 as foo, b + 2 as foo")
+ t.select("a + 1 as foo, b + 2 as foo")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testFilterInvalidField() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = CollectionDataSets.get3TupleDataSet(env).toTable(tableEnv, 'a, 'b, 'c)
+ val util = batchTestUtil()
+ val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
// Must fail. Field foo does not exist.
- table.filter("foo = 17")
+ t.filter("foo = 17")
}
@Test
def testAliasStarException(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
+ val util = batchTestUtil()
try {
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, '*, 'b, 'c)
+ util.addTable[(Int, Long, String)]("Table1", '*, 'b, 'c)
fail("TableException expected")
} catch {
case _: TableException => //ignore
}
try {
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1 as '*, '_2 as 'b, '_1 as 'c)
+ util.addTable[(Int, Long, String)]("Table2")
+ .select('_1 as '*, '_2 as 'b, '_1 as 'c)
fail("ValidationException expected")
} catch {
case _: ValidationException => //ignore
}
try {
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('*, 'b, 'c)
+ util.addTable[(Int, Long, String)]("Table3").as('*, 'b, 'c)
fail("ValidationException expected")
} catch {
case _: ValidationException => //ignore
}
-try {
- CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('*, 'b)
+ try {
+ util.addTable[(Int, Long, String)]("Table4", 'a, 'b, 'c).select('*, 'b)
fail("ValidationException expected")
} catch {
case _: ValidationException => //ignore
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala
new file mode 100644
index 0000000..0ac205a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.table.validation
+
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.junit.Test
+
+class CompositeFlatteningValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testDuplicateFlattening(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
+
+ table.select('a.flatten(), 'a.flatten())
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala
new file mode 100644
index 0000000..b8e2b97
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowValidationTest extends TableTestBase {
+
+ //===============================================================================================
+ // Common test
+ //===============================================================================================
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testOverAggregation(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+ val overAgg = new OverAgg0
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('string,'w)
+ .select(overAgg('long, 'int))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupByWithoutWindowAlias(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidRowTimeRef(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
+ .groupBy('w2)
+ .select('string)
+ }
+
+ //===============================================================================================
+ // Tumbling Windows
+ //===============================================================================================
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidProcessingTimeDefinition(): Unit = {
+ val util = batchTestUtil()
+ // proctime is not allowed
+ util.addTable[(Long, Int, String)]('long.proctime, 'int, 'string)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidProcessingTimeDefinition2(): Unit = {
+ val util = batchTestUtil()
+ // proctime is not allowed
+ util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidEventTimeDefinition(): Unit = {
+ val util = batchTestUtil()
+ // definition must not extend schema
+ util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Tumble over 2.minutes on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testAllTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Tumble over 2.minutes on 'rowtime as 'w)
+ .groupBy('w)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ //===============================================================================================
+ // Sliding Windows
+ //===============================================================================================
+
+ @Test(expected = classOf[ValidationException])
+ def testSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Slide over 2.minutes every 1.minute on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testAllSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Slide over 2.minutes every 1.minute on 'long as 'w)
+ .groupBy('w)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Session withGap 2.minutes on 'rowtime as 'w)
+ .groupBy('w, 'long)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testAllSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ val myWeightedAvg = new WeightedAvgWithMerge
+
+ table
+ .window(Session withGap 2.minutes on 'rowtime as 'w)
+ .groupBy('w)
+ // invalid function arguments
+ .select(myWeightedAvg('int, 'string))
+ }
+
+}
[38/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala
deleted file mode 100644
index a174c8b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.table.FieldProjectionTest._
-import org.apache.flink.table.expressions.Upper
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{TableTestBase, _}
-import org.junit.Test
-
-/**
- * Tests for all the situations when we can do fields projection. Like selecting few fields
- * from a large field count source.
- */
-class FieldProjectionTest extends TableTestBase {
-
- @Test
- def testSimpleSelect(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable = sourceTable.select('a, 'b)
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectAllFields(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable1 = sourceTable.select('*)
- val resultTable2 = sourceTable.select('a, 'b, 'c, 'd)
-
- val expected = batchTableNode(0)
-
- util.verifyTable(resultTable1, expected)
- util.verifyTable(resultTable2, expected)
- }
-
- @Test
- def testSelectAggregation(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable = sourceTable.select('a.sum, 'b.max)
-
- val expected = unaryNode(
- "DataSetAggregate",
- binaryNode(
- "DataSetUnion",
- values(
- "DataSetValues",
- tuples(List(null, null)),
- term("values", "a", "b")
- ),
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b")
- ),
- term("union", "a", "b")
- ),
- term("select", "SUM(a) AS TMP_0", "MAX(b) AS TMP_1")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectFunction(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
-
- util.tableEnv.registerFunction("hashCode", MyHashCode)
-
- val resultTable = sourceTable.select("hashCode(c), b")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", s"${MyHashCode.functionIdentifier}(c) AS _c0", "b")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectFromGroupedTable(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable = sourceTable.groupBy('a, 'c).select('a)
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "c")
- ),
- term("distinct", "a", "c")
- ),
- term("select", "a")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectAllFieldsFromGroupedTable(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable = sourceTable.groupBy('a, 'c).select('a, 'c)
-
- val expected = unaryNode(
- "DataSetDistinct",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "c")
- ),
- term("distinct", "a", "c")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectAggregationFromGroupedTable(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable = sourceTable.groupBy('c).select('a.sum)
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "c")
- ),
- term("groupBy", "c"),
- term("select", "c", "SUM(a) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectFromGroupedTableWithNonTrivialKey(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable = sourceTable.groupBy(Upper('c) as 'k).select('a.sum)
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "c", "UPPER(c) AS k")
- ),
- term("groupBy", "k"),
- term("select", "k", "SUM(a) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectFromGroupedTableWithFunctionKey(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- val resultTable = sourceTable.groupBy(MyHashCode('c) as 'k).select('a.sum)
-
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "c", s"${MyHashCode.functionIdentifier}(c) AS k")
- ),
- term("groupBy", "k"),
- term("select", "k", "SUM(a) AS TMP_0")
- ),
- term("select", "TMP_0")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectFromAggregatedPojoTable(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[WC]("MyTable", 'word, 'frequency)
- val resultTable = sourceTable
- .groupBy('word)
- .select('word, 'frequency.sum as 'frequency)
- .filter('frequency === 2)
- val expected =
- unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "word"),
- term("select", "word", "SUM(frequency) AS TMP_0")
- ),
- term("select", "word, TMP_0 AS frequency"),
- term("where", "=(TMP_0, 2)")
- )
-
- util.verifyTable(resultTable, expected)
- }
-
-}
-
-object FieldProjectionTest {
-
- object MyHashCode extends ScalarFunction {
- def eval(s: String): Int = s.hashCode()
- }
-
- case class WC(word: String, frequency: Long)
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala
deleted file mode 100644
index 84a6738..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMerge
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.WindowReference
-import org.apache.flink.table.plan.logical._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class GroupWindowTest extends TableTestBase {
-
- //===============================================================================================
- // Common test
- //===============================================================================================
-
- @Test
- def testEventTimeTumblingGroupWindowOverCount(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window", TumblingGroupWindow(WindowReference("w"), 'long, 2.rows)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverTimeWithUdAgg(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, myWeightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverTime(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeTumblingGroupWindowOverTime(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "int", "long")
- ),
- term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeTumblingGroupWindowOverCount(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "int", "long")
- ),
- term("window", TumblingGroupWindow(WindowReference("w"), 'long, 2.rows)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- //===============================================================================================
- // Sliding Windows
- //===============================================================================================
-
- @Test
- def testEventTimeSlidingGroupWindowOverTime(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window",
- SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverCount(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window",
- SlidingGroupWindow(WindowReference("w"), 'long, 2.rows, 1.rows)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeWithUdAgg(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, myWeightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window",
- SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "int", "long")
- ),
- term("window",
- SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "int", "long")
- ),
- term("window",
- SlidingGroupWindow(WindowReference("w"), 'long, 2.rows, 1.rows)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- //===============================================================================================
- // Session Windows
- //===============================================================================================
-
- @Test
- def testEventTimeSessionGroupWindowOverTime(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSessionGroupWindowOverTimeWithUdAgg(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, myWeightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataSetWindowAggregate",
- batchTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala
deleted file mode 100644
index 079b10a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/UserDefinedTableFunctionTest.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils._
-import org.junit.Test
-
-class UserDefinedTableFunctionTest extends TableTestBase {
-
- @Test
- def testCrossJoin(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("func1", new TableFunc1)
-
- val result1 = table.join(function('c) as 's).select('c, 's)
-
- val expected1 = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "s")
- )
-
- util.verifyTable(result1, expected1)
-
- // test overloading
-
- val result2 = table.join(function('c, "$") as 's).select('c, 's)
-
- val expected2 = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2, '$$')"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "s")
- )
-
- util.verifyTable(result2, expected2)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("func1", new TableFunc1)
-
- val result = table.leftOuterJoin(function('c) as 's).select('c, 's)
-
- val expected = unaryNode(
- "DataSetCalc",
- unaryNode(
- "DataSetCorrelate",
- batchTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
- term("joinType", "LEFT")
- ),
- term("select", "c", "s")
- )
-
- util.verifyTable(result, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala
deleted file mode 100644
index b085160..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/AggregationsStringExpressionTest.scala
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.LogicalPlanFormatUtils
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.table.utils.TableTestBase
-import org.junit._
-
-class AggregationsStringExpressionTest extends TableTestBase {
-
- @Test
- def testAggregationTypes(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3")
-
- val t1 = t.select('_1.sum, '_1.sum0, '_1.min, '_1.max, '_1.count, '_1.avg)
- val t2 = t.select("_1.sum, _1.sum0, _1.min, _1.max, _1.count, _1.avg")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testWorkingAggregationDataTypes(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Byte, Short, Int, Long, Float, Double, String)]("Table7")
-
- val t1 = t.select('_1.avg, '_2.avg, '_3.avg, '_4.avg, '_5.avg, '_6.avg, '_7.count)
- val t2 = t.select("_1.avg, _2.avg, _3.avg, _4.avg, _5.avg, _6.avg, _7.count")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testProjection(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Byte, Short)]("Table2")
-
- val t1 = t.select('_1.avg, '_1.sum, '_1.count, '_2.avg, '_2.sum)
- val t2 = t.select("_1.avg, _1.sum, _1.count, _2.avg, _2.sum")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testAggregationWithArithmetic(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Long, String)]("Table2")
-
- val t1 = t.select(('_1 + 2).avg + 2, '_2.count + 5)
- val t2 = t.select("(_1 + 2).avg + 2, _2.count + 5")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testAggregationWithTwoCount(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Long, String)]("Table2")
-
- val t1 = t.select('_1.count, '_2.count)
- val t2 = t.select("_1.count, _2.count")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testAggregationAfterProjection(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Byte, Short, Int, Long, Float, Double, String)]("Table7")
-
- val t1 = t.select('_1, '_2, '_3)
- .select('_1.avg, '_2.sum, '_3.count)
-
- val t2 = t.select("_1, _2, _3")
- .select("_1.avg, _2.sum, _3.count")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testDistinct(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val distinct = ds.select('b).distinct()
- val distinct2 = ds.select("b").distinct()
-
- verifyTableEquals(distinct, distinct2)
- }
-
- @Test
- def testDistinctAfterAggregate(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
-
- val distinct = ds.groupBy('a, 'e).select('e).distinct()
- val distinct2 = ds.groupBy("a, e").select("e").distinct()
-
- val lPlan1 = distinct.logicalPlan
- val lPlan2 = distinct2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testGroupedAggregate(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val t1 = t.groupBy('b).select('b, 'a.sum)
- val t2 = t.groupBy("b").select("b, a.sum")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testGroupingKeyForwardIfNotUsed(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val t1 = t.groupBy('b).select('a.sum)
- val t2 = t.groupBy("b").select("a.sum")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testGroupNoAggregation(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val t1 = t
- .groupBy('b)
- .select('a.sum as 'd, 'b)
- .groupBy('b, 'd)
- .select('b)
-
- val t2 = t
- .groupBy("b")
- .select("a.sum as d, b")
- .groupBy("b, d")
- .select("b")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testGroupedAggregateWithConstant1(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val t1 = t.select('a, 4 as 'four, 'b)
- .groupBy('four, 'a)
- .select('four, 'b.sum)
-
- val t2 = t.select("a, 4 as four, b")
- .groupBy("four, a")
- .select("four, b.sum")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testGroupedAggregateWithConstant2(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val t1 = t.select('b, 4 as 'four, 'a)
- .groupBy('b, 'four)
- .select('four, 'a.sum)
- val t2 = t.select("b, 4 as four, a")
- .groupBy("b, four")
- .select("four, a.sum")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testGroupedAggregateWithExpression(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
-
- val t1 = t.groupBy('e, 'b % 3)
- .select('c.min, 'e, 'a.avg, 'd.count)
- val t2 = t.groupBy("e, b % 3")
- .select("c.min, e, a.avg, d.count")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testGroupedAggregateWithFilter(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val t1 = t.groupBy('b)
- .select('b, 'a.sum)
- .where('b === 2)
- val t2 = t.groupBy("b")
- .select("b, a.sum")
- .where("b = 2")
-
- verifyTableEquals(t1, t2)
- }
-
- @Test
- def testAnalyticAggregation(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, Float, Double)]('_1, '_2, '_3, '_4)
-
- val resScala = t.select(
- '_1.stddevPop, '_2.stddevPop, '_3.stddevPop, '_4.stddevPop,
- '_1.stddevSamp, '_2.stddevSamp, '_3.stddevSamp, '_4.stddevSamp,
- '_1.varPop, '_2.varPop, '_3.varPop, '_4.varPop,
- '_1.varSamp, '_2.varSamp, '_3.varSamp, '_4.varSamp)
- val resJava = t.select("""
- _1.stddevPop, _2.stddevPop, _3.stddevPop, _4.stddevPop,
- _1.stddevSamp, _2.stddevSamp, _3.stddevSamp, _4.stddevSamp,
- _1.varPop, _2.varPop, _3.varPop, _4.varPop,
- _1.varSamp, _2.varSamp, _3.varSamp, _4.varSamp""")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testAggregateWithUDAGG(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val myCnt = new CountAggFunction
- util.tableEnv.registerFunction("myCnt", myCnt)
- val myWeightedAvg = new WeightedAvgWithMergeAndReset
- util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
-
- val t1 = t.select(myCnt('a) as 'aCnt, myWeightedAvg('b, 'a) as 'wAvg)
- val t2 = t.select("myCnt(a) as aCnt, myWeightedAvg(b, a) as wAvg")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- val x = LogicalPlanFormatUtils.formatTempTableId(lPlan1.toString)
- val y = LogicalPlanFormatUtils.formatTempTableId(lPlan2.toString)
-
- Assert.assertEquals(
- "Logical Plans do not match",
- LogicalPlanFormatUtils.formatTempTableId(lPlan1.toString),
- LogicalPlanFormatUtils.formatTempTableId(lPlan2.toString))
- }
-
- @Test
- def testGroupedAggregateWithUDAGG(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
-
- val myCnt = new CountAggFunction
- util.tableEnv.registerFunction("myCnt", myCnt)
- val myWeightedAvg = new WeightedAvgWithMergeAndReset
- util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
-
- val t1 = t.groupBy('b)
- .select('b, myCnt('a) + 9 as 'aCnt, myWeightedAvg('b, 'a) * 2 as 'wAvg, myWeightedAvg('a, 'a))
- val t2 = t.groupBy("b")
- .select("b, myCnt(a) + 9 as aCnt, myWeightedAvg(b, a) * 2 as wAvg, myWeightedAvg(a, a)")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals(
- "Logical Plans do not match",
- LogicalPlanFormatUtils.formatTempTableId(lPlan1.toString),
- LogicalPlanFormatUtils.formatTempTableId(lPlan2.toString))
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala
deleted file mode 100644
index 9736ec1..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CalcStringExpressionTest.scala
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.stringexpr
-
-import java.sql.{Date, Time, Timestamp}
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets.CustomType
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.LogicalPlanFormatUtils
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.utils.TableTestBase
-import org.junit._
-
-class CalcStringExpressionTest extends TableTestBase {
-
- @Test
- def testSimpleSelectAllWithAs(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = t.select('a, 'b, 'c)
- val t2 = t.select("a, b, c")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testSimpleSelectWithNaming(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3")
-
- val t1 = t
- .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
- .select('a, 'b)
-
- val t2 = t
- .select("_1 as a, _2 as b, _1 as c")
- .select("a, b")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testSimpleSelectRenameAll(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3")
-
- val t1 = t
- .select('_1 as 'a, '_2 as 'b, '_3 as 'c)
- .select('a, 'b)
-
- val t2 = t
- .select("_1 as a, _2 as b, _3 as c")
- .select("a, b")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testSelectStar(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = t.select('*)
- val t2 = t.select("*")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = ds.filter( Literal(false) )
- val t2 = ds.filter("faLsE")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = ds.filter( Literal(true) )
- val t2 = ds.filter("trUe")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testFilterOnStringTupleField(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = ds.filter( 'c.like("%world%") )
- val t2 = ds.filter("c.like('%world%')")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testFilterOnIntegerTupleField(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = ds.filter( 'a % 2 === 0 )
- val t2 = ds.filter( "a % 2 = 0 ")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testNotEquals(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = ds.filter( 'a % 2 !== 0 )
- val t2 = ds.filter("a % 2 <> 0")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testDisjunctivePredicate(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = ds.filter( 'a < 2 || 'a > 20)
- val t2 = ds.filter("a < 2 || a > 20")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testConsecutiveFilters(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = ds.filter('a % 2 !== 0).filter('b % 2 === 0)
- val t2 = ds.filter("a % 2 != 0").filter("b % 2 = 0")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testFilterBasicType(): Unit = {
- val util = batchTestUtil()
- val ds = util.addTable[String]("Table3",'a)
-
- val t1 = ds.filter( 'a.like("H%") )
- val t2 = ds.filter( "a.like('H%')" )
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testFilterOnCustomType(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[CustomType]("Table3",'myInt as 'i, 'myLong as 'l, 'myString as 's)
-
- val t1 = t.filter( 's.like("%a%") )
- val t2 = t.filter("s.like('%a%')")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testSimpleCalc(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3")
-
- val t1 = t.select('_1, '_2, '_3)
- .where('_1 < 7)
- .select('_1, '_3)
-
- val t2 = t.select("_1, _2, _3")
- .where("_1 < 7")
- .select("_1, _3")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testCalcWithTwoFilters(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3")
-
- val t1 = t.select('_1, '_2, '_3)
- .where('_1 < 7 && '_2 === 3)
- .select('_1, '_3)
- .where('_1 === 4)
- .select('_1)
-
- val t2 = t.select("_1, _2, _3")
- .where("_1 < 7 && _2 = 3")
- .select("_1, _3")
- .where("_1 === 4")
- .select("_1")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testCalcWithAggregation(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3")
-
- val t1 = t.select('_1, '_2, '_3)
- .where('_1 < 15)
- .groupBy('_2)
- .select('_1.min, '_2.count as 'cnt)
- .where('cnt > 3)
-
-
- val t2 = t.select("_1, _2, _3")
- .where("_1 < 15")
- .groupBy("_2")
- .select("_1.min, _2.count as cnt")
- .where("cnt > 3")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match",
- LogicalPlanFormatUtils.formatTempTableId(lPlan1.toString),
- LogicalPlanFormatUtils.formatTempTableId(lPlan2.toString))
- }
-
- @Test
- def testCalcJoin(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.select('a, 'b).join(ds2).where('b === 'e).select('a, 'b, 'd, 'e, 'f)
- .where('b > 1).select('a, 'd).where('d === 2)
- val t2 = ds1.select("a, b").join(ds2).where("b = e").select("a, b, d, e, f")
- .where("b > 1").select("a, d").where("d = 2")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testAdvancedDataTypes(): Unit = {
- val util = batchTestUtil()
- val t = util
- .addTable[(BigDecimal, BigDecimal, Date, Time, Timestamp)]("Table5", 'a, 'b, 'c, 'd, 'e)
-
- val t1 = t.select('a, 'b, 'c, 'd, 'e, BigDecimal("11.2"), BigDecimal("11.2").bigDecimal,
- "1984-07-12".cast(Types.SQL_DATE), "14:34:24".cast(Types.SQL_TIME),
- "1984-07-12 14:34:24".cast(Types.SQL_TIMESTAMP))
- val t2 = t.select("a, b, c, d, e, 11.2, 11.2," +
- "'1984-07-12'.toDate, '14:34:24'.toTime," +
- "'1984-07-12 14:34:24'.toTimestamp")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1.toString, lPlan2.toString)
- }
-
- @Test
- def testIntegerBiggerThan128(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val t1 = t.filter('a === 300)
- val t2 = t.filter("a = 300")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala
deleted file mode 100644
index 8ca5745..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/CastingStringExpressionTest.scala
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.Types._
-import org.apache.flink.table.api.scala._
-import org.junit._
-
-class CastingStringExpressionTest {
-
- @Test
- def testNumericAutoCastInArithmetic() {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements(
- (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d, 1L, 1001.1)).toTable(tableEnv)
- val t1 = table.select('_1 + 1, '_2 + 1, '_3 + 1L, '_4 + 1.0f,
- '_5 + 1.0d, '_6 + 1, '_7 + 1.0d, '_8 + '_1)
- val t2 = table.select("_1 + 1, _2 +" +
- " 1, _3 + 1L, _4 + 1.0f, _5 + 1.0d, _6 + 1, _7 + 1.0d, _8 + _1")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- @throws[Exception]
- def testNumericAutoCastInComparison() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements(
- (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d),
- (2.toByte, 2.toShort, 2, 2L, 2.0f, 2.0d))
- .toTable(tableEnv, 'a, 'b, 'c, 'd, 'e, 'f)
- val t1 = table.filter('a > 1 && 'b > 1 && 'c > 1L &&
- 'd > 1.0f && 'e > 1.0d && 'f > 1)
- val t2 = table
- .filter("a > 1 && b > 1 && c > 1L && d > 1.0f && e > 1.0d && f > 1")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- @throws[Exception]
- def testCasting() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements((1, 0.0, 1L, true)).toTable(tableEnv)
- val t1 = table .select(
- // * -> String
- '_1.cast(STRING), '_2.cast(STRING), '_3.cast(STRING), '_4.cast(STRING),
- // NUMERIC TYPE -> Boolean
- '_1.cast(BOOLEAN), '_2.cast(BOOLEAN), '_3.cast(BOOLEAN),
- // NUMERIC TYPE -> NUMERIC TYPE
- '_1.cast(DOUBLE), '_2.cast(INT), '_3.cast(SHORT),
- // Boolean -> NUMERIC TYPE
- '_4.cast(DOUBLE), // identity casting
- '_1.cast(INT), '_2.cast(DOUBLE), '_3.cast(LONG), '_4.cast(BOOLEAN))
- val t2 = table.select(
- // * -> String
- "_1.cast(STRING), _2.cast(STRING), _3.cast(STRING), _4.cast(STRING)," +
- // NUMERIC TYPE -> Boolean
- "_1.cast(BOOLEAN), _2.cast(BOOLEAN), _3.cast(BOOLEAN)," +
- // NUMERIC TYPE -> NUMERIC TYPE
- "_1.cast(DOUBLE), _2.cast(INT), _3.cast(SHORT)," +
- // Boolean -> NUMERIC TYPE
- "_4.cast(DOUBLE)," +
- // identity casting
- "_1.cast(INT), _2.cast(DOUBLE), _3.cast(LONG), _4.cast(BOOLEAN)")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- @throws[Exception]
- def testCastFromString() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements(("1", "true", "2.0")).toTable(tableEnv)
- val t1 = table .select('_1.cast(BYTE), '_1.cast(SHORT), '_1.cast(INT), '_1.cast(LONG),
- '_3.cast(DOUBLE), '_3.cast(FLOAT), '_2.cast(BOOLEAN))
- val t2 = table.select(
- "_1.cast(BYTE), _1.cast(SHORT), _1.cast(INT), _1.cast(LONG), " +
- "_3.cast(DOUBLE), _3.cast(FLOAT), _2.cast(BOOLEAN)")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-}
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala
deleted file mode 100644
index 067441d..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/JoinStringExpressionTest.scala
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.LogicalPlanFormatUtils
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.utils.TableTestBase
-import org.junit._
-
-class JoinStringExpressionTest extends TableTestBase {
-
- @Test
- def testJoin(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1Scala = ds1.join(ds2).where('b === 'e).select('c, 'g)
- val t1Java = ds1.join(ds2).where("b === e").select("c, g")
-
- val lPlan1 = t1Scala.logicalPlan
- val lPlan2 = t1Java.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testJoinWithFilter(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1Scala = ds1.join(ds2).where('b === 'e && 'b < 2).select('c, 'g)
- val t1Java = ds1.join(ds2).where("b === e && b < 2").select("c, g")
-
- val lPlan1 = t1Scala.logicalPlan
- val lPlan2 = t1Java.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testJoinWithJoinFilter(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1Scala = ds1.join(ds2).where('b === 'e && 'a < 6 && 'h < 'b).select('c, 'g)
- val t1Java = ds1.join(ds2).where("b === e && a < 6 && h < b").select("c, g")
-
- val lPlan1 = t1Scala.logicalPlan
- val lPlan2 = t1Java.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testJoinWithMultipleKeys(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1Scala = ds1.join(ds2).filter('a === 'd && 'b === 'h).select('c, 'g)
- val t1Java = ds1.join(ds2).filter("a === d && b === h").select("c, g")
-
- val lPlan1 = t1Scala.logicalPlan
- val lPlan2 = t1Java.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testJoinWithAggregation(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1Scala = ds1.join(ds2).where('a === 'd).select('g.count)
- val t1Java = ds1.join(ds2).where("a === d").select("g.count")
-
- val lPlan1 = t1Scala.logicalPlan
- val lPlan2 = t1Java.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match",
- LogicalPlanFormatUtils.formatTempTableId(lPlan1.toString),
- LogicalPlanFormatUtils.formatTempTableId(lPlan2.toString))
- }
-
- @Test
- def testJoinWithGroupedAggregation(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.join(ds2)
- .where('a === 'd)
- .groupBy('a, 'd)
- .select('b.sum, 'g.count)
- val t2 = ds1.join(ds2)
- .where("a = d")
- .groupBy("a, d")
- .select("b.sum, g.count")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match",
- LogicalPlanFormatUtils.formatTempTableId(lPlan1.toString),
- LogicalPlanFormatUtils.formatTempTableId(lPlan2.toString))
- }
-
- @Test
- def testJoinPushThroughJoin(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds3 = util.addTable[(Int, Long, String)]("Table4",'j, 'k, 'l)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.join(ds2)
- .where(Literal(true))
- .join(ds3)
- .where('a === 'd && 'e === 'k)
- .select('a, 'f, 'l)
- val t2 = ds1.join(ds2)
- .where("true")
- .join(ds3)
- .where("a === d && e === k")
- .select("a, f, l")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testJoinWithDisjunctivePred(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.join(ds2).filter('a === 'd && ('b === 'e || 'b === 'e - 10)).select('c, 'g)
- val t2 = ds1.join(ds2).filter("a = d && (b = e || b = e - 10)").select("c, g")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testJoinWithExpressionPreds(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.join(ds2).filter('b === 'h + 1 && 'a - 1 === 'd + 2).select('c, 'g)
- val t2 = ds1.join(ds2).filter("b = h + 1 && a - 1 = d + 2").select("c, g")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testLeftJoinWithMultipleKeys(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.leftOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
- val t2 = ds1.leftOuterJoin(ds2, "a = d && b = h").select("c, g")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testRightJoinWithMultipleKeys(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.rightOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
- val t2 = ds1.rightOuterJoin(ds2, "a = d && b = h").select("c, g")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
- @Test
- def testFullOuterJoinWithMultipleKeys(): Unit = {
- val util = batchTestUtil()
- val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
-
- val t1 = ds1.fullOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
- val t2 = ds1.fullOuterJoin(ds2, "a = d && b = h").select("c, g")
-
- val lPlan1 = t1.logicalPlan
- val lPlan2 = t2.logicalPlan
-
- Assert.assertEquals("Logical Plans do not match", lPlan1, lPlan2)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
deleted file mode 100644
index 8cf9979..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.types.Row
-import org.apache.flink.table.utils.{PojoTableFunc, TableFunc2, _}
-import org.apache.flink.table.api.{Table, Types}
-import org.junit.Test
-
-class UserDefinedTableFunctionStringExpressionTest extends TableTestBase {
-
- @Test
- def testJoin(): Unit = {
- val util = batchTestUtil()
-
- val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
- val sTab = util.addTable[(Int, Long, String)]("Table1", 'a, 'b, 'c)
- val jTab = util.addJavaTable[Row](typeInfo, "Table2", "a, b, c")
-
- // test cross join
- val func1 = new TableFunc1
- util.javaTableEnv.registerFunction("func1", func1)
- var scalaTable = sTab.join(func1('c) as 's).select('c, 's)
- var javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c).as(s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test left outer join
- scalaTable = sTab.leftOuterJoin(func1('c) as 's).select('c, 's)
- javaTable = jTab.leftOuterJoin(new Table(util.javaTableEnv, "as(func1(c), s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test overloading
- scalaTable = sTab.join(func1('c, "$") as 's).select('c, 's)
- javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test custom result type
- val func2 = new TableFunc2
- util.javaTableEnv.registerFunction("func2", func2)
- scalaTable = sTab.join(func2('c) as('name, 'len)).select('c, 'name, 'len)
- javaTable = jTab.join(
- new Table(util.javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
- verifyTableEquals(scalaTable, javaTable)
-
- // test hierarchy generic type
- val hierarchy = new HierarchyTableFunction
- util.javaTableEnv.registerFunction("hierarchy", hierarchy)
- scalaTable = sTab.join(hierarchy('c) as('name, 'adult, 'len)).select('c, 'name, 'len, 'adult)
- javaTable = jTab.join(new Table(util.javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
- .select("c, name, len, adult")
- verifyTableEquals(scalaTable, javaTable)
-
- // test pojo type
- val pojo = new PojoTableFunc
- util.javaTableEnv.registerFunction("pojo", pojo)
- scalaTable = sTab.join(pojo('c)).select('c, 'name, 'age)
- javaTable = jTab.join(new Table(util.javaTableEnv, "pojo(c)")).select("c, name, age")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with filter
- scalaTable = sTab.join(func2('c) as('name, 'len)).select('c, 'name, 'len).filter('len > 2)
- javaTable = jTab.join(new Table(util.javaTableEnv, "func2(c) as (name, len)"))
- .select("c, name, len").filter("len > 2")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with scalar function
- scalaTable = sTab.join(func1('c.substring(2)) as 's).select('a, 'c, 's)
- javaTable = jTab.join(
- new Table(util.javaTableEnv, "func1(substring(c, 2)) as (s)")).select("a, c, s")
- verifyTableEquals(scalaTable, javaTable)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala
deleted file mode 100644
index 25ecd96..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/AggregationsValidationTest.scala
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMergeAndReset}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit._
-
-class AggregationsValidationTest extends TableTestBase {
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- val overAgg = new OverAgg0
- t.select('c.count, overAgg('b, 'a))
- }
-
- @Test(expected = classOf[ValidationException])
- def testNonWorkingAggregationDataTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- env.fromElements(("Hello", 1)).toTable(tEnv)
- // Must fail. Field '_1 is not a numeric type.
- .select('_1.sum)
- }
-
- @Test(expected = classOf[ValidationException])
- def testNoNestedAggregations(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(String, Int)]("Table2")
-
- // Must fail. Sum aggregation can not be chained.
- t.select('_2.sum.sum)
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupingOnNonExistentField(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- // must fail. '_foo not a valid field
- t.groupBy('_foo)
- .select('a.avg)
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupingInvalidSelection(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- t.groupBy('a, 'b)
- // must fail. 'c is not a grouping key or aggregation
- .select('c)
- }
-
- @Test(expected = classOf[ValidationException])
- def testAggregationOnNonExistingField(): Unit = {
-
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- // Must fail. Field 'foo does not exist.
- t.select('foo.avg)
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testInvalidUdAggArgs() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val myWeightedAvg = new WeightedAvgWithMergeAndReset
-
- // must fail. UDAGG does not accept String type
- t.select(myWeightedAvg('c, 'a))
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testGroupingInvalidUdAggArgs() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val myWeightedAvg = new WeightedAvgWithMergeAndReset
-
- t.groupBy('b)
- // must fail. UDAGG does not accept String type
- .select(myWeightedAvg('c, 'a))
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testGroupingNestedUdAgg() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val myWeightedAvg = new WeightedAvgWithMergeAndReset
-
- t.groupBy('c)
- // must fail. UDAGG does not accept String type
- .select(myWeightedAvg(myWeightedAvg('b, 'a), 'a))
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testAggregationOnNonExistingFieldJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- t.select("foo.avg")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testNonWorkingAggregationDataTypesJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Long, String)]("Table2",'b, 'c)
- // Must fail. Cannot compute SUM aggregate on String field.
- t.select("c.sum")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testNoNestedAggregationsJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Long, String)]("Table2",'b, 'c)
- // Must fail. Aggregation on aggregation not allowed.
- t.select("b.sum.sum")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testGroupingOnNonExistentFieldJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- // must fail. Field foo is not in input
- t.groupBy("foo")
- .select("a.avg")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testGroupingInvalidSelectionJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- t.groupBy("a, b")
- // must fail. Field c is not a grouping key or aggregation
- .select("c")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testUnknownUdAggJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- // must fail. unknown is not known
- t.select("unknown(c)")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testGroupingUnknownUdAggJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- t.groupBy("a, b")
- // must fail. unknown is not known
- .select("unknown(c)")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testInvalidUdAggArgsJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val myWeightedAvg = new WeightedAvgWithMergeAndReset
- util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
-
- // must fail. UDAGG does not accept String type
- t.select("myWeightedAvg(c, a)")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testGroupingInvalidUdAggArgsJava() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
-
- val myWeightedAvg = new WeightedAvgWithMergeAndReset
- util.tableEnv.registerFunction("myWeightedAvg", myWeightedAvg)
-
- t.groupBy("b")
- // must fail. UDAGG does not accept String type
- .select("myWeightedAvg(c, a)")
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala
deleted file mode 100644
index e2a5dac..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CalcValidationTest.scala
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableException, ValidationException}
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit._
-
-class CalcValidationTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testSelectInvalidFieldFields(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- // must fail. Field 'foo does not exist
- .select('a, 'foo)
- }
-
- @Test(expected = classOf[ValidationException])
- def testSelectAmbiguousRenaming(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- // must fail. 'a and 'b are both renamed to 'foo
- .select('a + 1 as 'foo, 'b + 2 as 'foo).toDataSet[Row].print()
- }
-
- @Test(expected = classOf[ValidationException])
- def testSelectAmbiguousRenaming2(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
- // must fail. 'a and 'b are both renamed to 'a
- .select('a, 'b as 'a).toDataSet[Row].print()
- }
-
- @Test(expected = classOf[ValidationException])
- def testFilterInvalidFieldName(): Unit = {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- // must fail. Field 'foo does not exist
- t.filter( 'foo === 2 )
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testSelectInvalidField() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- // Must fail. Field foo does not exist
- t.select("a + 1, foo + 2")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testSelectAmbiguousFieldNames() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- // Must fail. Field foo does not exist
- t.select("a + 1 as foo, b + 2 as foo")
- }
-
- @Test(expected = classOf[ValidationException])
- @throws[Exception]
- def testFilterInvalidField() {
- val util = batchTestUtil()
- val t = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
-
- // Must fail. Field foo does not exist.
- t.filter("foo = 17")
- }
-
- @Test
- def testAliasStarException(): Unit = {
- val util = batchTestUtil()
-
- try {
- util.addTable[(Int, Long, String)]("Table1", '*, 'b, 'c)
- fail("TableException expected")
- } catch {
- case _: TableException => //ignore
- }
-
- try {
- util.addTable[(Int, Long, String)]("Table2")
- .select('_1 as '*, '_2 as 'b, '_1 as 'c)
- fail("ValidationException expected")
- } catch {
- case _: ValidationException => //ignore
- }
-
- try {
- util.addTable[(Int, Long, String)]("Table3").as('*, 'b, 'c)
- fail("ValidationException expected")
- } catch {
- case _: ValidationException => //ignore
- }
- try {
- util.addTable[(Int, Long, String)]("Table4", 'a, 'b, 'c).select('*, 'b)
- fail("ValidationException expected")
- } catch {
- case _: ValidationException => //ignore
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala
deleted file mode 100644
index 0ac205a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/CompositeFlatteningValidationTest.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table.validation
-
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.junit.Test
-
-class CompositeFlatteningValidationTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testDuplicateFlattening(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
-
- table.select('a.flatten(), 'a.flatten())
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala
deleted file mode 100644
index b8e2b97..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/GroupWindowValidationTest.scala
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.batch.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class GroupWindowValidationTest extends TableTestBase {
-
- //===============================================================================================
- // Common test
- //===============================================================================================
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
- val overAgg = new OverAgg0
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('string,'w)
- .select(overAgg('long, 'int))
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupByWithoutWindowAlias(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidRowTimeRef(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
- .groupBy('w2)
- .select('string)
- }
-
- //===============================================================================================
- // Tumbling Windows
- //===============================================================================================
-
- @Test(expected = classOf[ValidationException])
- def testInvalidProcessingTimeDefinition(): Unit = {
- val util = batchTestUtil()
- // proctime is not allowed
- util.addTable[(Long, Int, String)]('long.proctime, 'int, 'string)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidProcessingTimeDefinition2(): Unit = {
- val util = batchTestUtil()
- // proctime is not allowed
- util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidEventTimeDefinition(): Unit = {
- val util = batchTestUtil()
- // definition must not extend schema
- util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
- }
-
- @Test(expected = classOf[ValidationException])
- def testTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Tumble over 2.minutes on 'rowtime as 'w)
- .groupBy('w, 'long)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
- @Test(expected = classOf[ValidationException])
- def testAllTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Tumble over 2.minutes on 'rowtime as 'w)
- .groupBy('w)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
- //===============================================================================================
- // Sliding Windows
- //===============================================================================================
-
- @Test(expected = classOf[ValidationException])
- def testSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Slide over 2.minutes every 1.minute on 'rowtime as 'w)
- .groupBy('w, 'long)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
- @Test(expected = classOf[ValidationException])
- def testAllSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Slide over 2.minutes every 1.minute on 'long as 'w)
- .groupBy('w)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
- @Test(expected = classOf[ValidationException])
- def testSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Session withGap 2.minutes on 'rowtime as 'w)
- .groupBy('w, 'long)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
- @Test(expected = classOf[ValidationException])
- def testAllSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Session withGap 2.minutes on 'rowtime as 'w)
- .groupBy('w)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
-}
[28/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AvgFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AvgFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AvgFunctionTest.scala
new file mode 100644
index 0000000..0671b40
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/AvgFunctionTest.scala
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in average aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class AvgAggFunctionTestBase[T: Numeric, ACC] extends AggFunctionTestBase[T, ACC] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def minVal: T
+
+ def maxVal: T
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ minVal,
+ minVal,
+ null.asInstanceOf[T],
+ minVal,
+ minVal,
+ null.asInstanceOf[T],
+ minVal,
+ minVal,
+ minVal
+ ),
+ Seq(
+ maxVal,
+ maxVal,
+ null.asInstanceOf[T],
+ maxVal,
+ maxVal,
+ null.asInstanceOf[T],
+ maxVal,
+ maxVal,
+ maxVal
+ ),
+ Seq(
+ minVal,
+ maxVal,
+ null.asInstanceOf[T],
+ numeric.fromInt(0),
+ numeric.negate(maxVal),
+ numeric.negate(minVal),
+ null.asInstanceOf[T]
+ ),
+ Seq(
+ numeric.fromInt(1),
+ numeric.fromInt(2),
+ null.asInstanceOf[T],
+ numeric.fromInt(3),
+ numeric.fromInt(4),
+ numeric.fromInt(5),
+ null.asInstanceOf[T]
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ minVal,
+ maxVal,
+ numeric.fromInt(0),
+ numeric.fromInt(3),
+ null.asInstanceOf[T]
+ )
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class ByteAvgAggFunctionTest extends AvgAggFunctionTestBase[Byte, IntegralAvgAccumulator] {
+
+ override def minVal = (Byte.MinValue + 1).toByte
+
+ override def maxVal = (Byte.MaxValue - 1).toByte
+
+ override def aggregator = new ByteAvgAggFunction()
+}
+
+class ShortAvgAggFunctionTest extends AvgAggFunctionTestBase[Short, IntegralAvgAccumulator] {
+
+ override def minVal = (Short.MinValue + 1).toShort
+
+ override def maxVal = (Short.MaxValue - 1).toShort
+
+ override def aggregator = new ShortAvgAggFunction()
+}
+
+class IntAvgAggFunctionTest extends AvgAggFunctionTestBase[Int, IntegralAvgAccumulator] {
+
+ override def minVal = Int.MinValue + 1
+
+ override def maxVal = Int.MaxValue - 1
+
+ override def aggregator = new IntAvgAggFunction()
+}
+
+class LongAvgAggFunctionTest extends AvgAggFunctionTestBase[Long, BigIntegralAvgAccumulator] {
+
+ override def minVal = Long.MinValue + 1
+
+ override def maxVal = Long.MaxValue - 1
+
+ override def aggregator = new LongAvgAggFunction()
+}
+
+class FloatAvgAggFunctionTest extends AvgAggFunctionTestBase[Float, FloatingAvgAccumulator] {
+
+ override def minVal = Float.MinValue
+
+ override def maxVal = Float.MaxValue
+
+ override def aggregator = new FloatAvgAggFunction()
+}
+
+class DoubleAvgAggFunctionTest extends AvgAggFunctionTestBase[Double, FloatingAvgAccumulator] {
+
+ override def minVal = Float.MinValue
+
+ override def maxVal = Float.MaxValue
+
+ override def aggregator = new DoubleAvgAggFunction()
+}
+
+class DecimalAvgAggFunctionTest extends AggFunctionTestBase[BigDecimal, DecimalAvgAccumulator] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("987654321000000"),
+ new BigDecimal("-0.000000000012345"),
+ null,
+ new BigDecimal("0.000000000012345"),
+ new BigDecimal("-987654321000000"),
+ null,
+ new BigDecimal("0")
+ ),
+ Seq(
+ new BigDecimal("987654321000000"),
+ new BigDecimal("-0.000000000012345"),
+ null,
+ new BigDecimal("0.000000000012345"),
+ new BigDecimal("-987654321000000"),
+ null,
+ new BigDecimal("5")
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ BigDecimal.ZERO,
+ BigDecimal.ONE,
+ null
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, DecimalAvgAccumulator] =
+ new DecimalAvgAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/CountAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/CountAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/CountAggFunctionTest.scala
new file mode 100644
index 0000000..f9dd474
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/CountAggFunctionTest.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions.{CountAccumulator, CountAggFunction}
+
+/**
+ * Test case for built-in count aggregate function
+ */
+class CountAggFunctionTest extends AggFunctionTestBase[Long, CountAccumulator] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq("a", "b", null, "c", null, "d", "e", null, "f"),
+ Seq(null, null, null, null, null, null)
+ )
+
+ override def expectedResults: Seq[Long] = Seq(6L, 0L)
+
+ override def aggregator: AggregateFunction[Long, CountAccumulator] = new CountAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxAggFunctionTest.scala
new file mode 100644
index 0000000..8a46ec5
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxAggFunctionTest.scala
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in max aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class MaxAggFunctionTest[T: Numeric] extends AggFunctionTestBase[T, MaxAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def minVal: T
+
+ def maxVal: T
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ maxVal,
+ numeric.fromInt(-99),
+ numeric.fromInt(3),
+ numeric.fromInt(56),
+ numeric.fromInt(0),
+ minVal,
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T]
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ maxVal,
+ null.asInstanceOf[T]
+ )
+}
+
+class ByteMaxAggFunctionTest extends MaxAggFunctionTest[Byte] {
+
+ override def minVal = (Byte.MinValue + 1).toByte
+
+ override def maxVal = (Byte.MaxValue - 1).toByte
+
+ override def aggregator: AggregateFunction[Byte, MaxAccumulator[Byte]] =
+ new ByteMaxAggFunction()
+}
+
+class ShortMaxAggFunctionTest extends MaxAggFunctionTest[Short] {
+
+ override def minVal = (Short.MinValue + 1).toShort
+
+ override def maxVal = (Short.MaxValue - 1).toShort
+
+ override def aggregator: AggregateFunction[Short, MaxAccumulator[Short]] =
+ new ShortMaxAggFunction()
+}
+
+class IntMaxAggFunctionTest extends MaxAggFunctionTest[Int] {
+
+ override def minVal = Int.MinValue + 1
+
+ override def maxVal = Int.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Int, MaxAccumulator[Int]] =
+ new IntMaxAggFunction()
+}
+
+class LongMaxAggFunctionTest extends MaxAggFunctionTest[Long] {
+
+ override def minVal = Long.MinValue + 1
+
+ override def maxVal = Long.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Long, MaxAccumulator[Long]] =
+ new LongMaxAggFunction()
+}
+
+class FloatMaxAggFunctionTest extends MaxAggFunctionTest[Float] {
+
+ override def minVal = Float.MinValue / 2
+
+ override def maxVal = Float.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Float, MaxAccumulator[Float]] =
+ new FloatMaxAggFunction()
+}
+
+class DoubleMaxAggFunctionTest extends MaxAggFunctionTest[Double] {
+
+ override def minVal = Double.MinValue / 2
+
+ override def maxVal = Double.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Double, MaxAccumulator[Double]] =
+ new DoubleMaxAggFunction()
+}
+
+class BooleanMaxAggFunctionTest extends AggFunctionTestBase[Boolean, MaxAccumulator[Boolean]] {
+
+ override def inputValueSets: Seq[Seq[Boolean]] = Seq(
+ Seq(
+ false,
+ false,
+ false
+ ),
+ Seq(
+ true,
+ true,
+ true
+ ),
+ Seq(
+ true,
+ false,
+ null.asInstanceOf[Boolean],
+ true,
+ false,
+ true,
+ null.asInstanceOf[Boolean]
+ ),
+ Seq(
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean]
+ )
+ )
+
+ override def expectedResults: Seq[Boolean] = Seq(
+ false,
+ true,
+ true,
+ null.asInstanceOf[Boolean]
+ )
+
+ override def aggregator: AggregateFunction[Boolean, MaxAccumulator[Boolean]] =
+ new BooleanMaxAggFunction()
+}
+
+class DecimalMaxAggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, MaxAccumulator[BigDecimal]] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("1000.000001"),
+ new BigDecimal("-1"),
+ new BigDecimal("-999.998999"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-999.999"),
+ null,
+ new BigDecimal("999.999")
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("1000.000001"),
+ null
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, MaxAccumulator[BigDecimal]] =
+ new DecimalMaxAggFunction()
+}
+
+class StringMaxAggFunctionTest extends AggFunctionTestBase[String, MaxAccumulator[String]] {
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new String("a"),
+ new String("b"),
+ new String("c"),
+ null.asInstanceOf[String],
+ new String("d")
+ ),
+ Seq(
+ null.asInstanceOf[String],
+ null.asInstanceOf[String],
+ null.asInstanceOf[String]
+ ),
+ Seq(
+ new String("1House"),
+ new String("Household"),
+ new String("house"),
+ new String("household")
+ )
+ )
+
+ override def expectedResults: Seq[String] = Seq(
+ new String("d"),
+ null.asInstanceOf[String],
+ new String("household")
+ )
+
+ override def aggregator: AggregateFunction[String, MaxAccumulator[String]] =
+ new StringMaxAggFunction()
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxWithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxWithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxWithRetractAggFunctionTest.scala
new file mode 100644
index 0000000..246d964
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MaxWithRetractAggFunctionTest.scala
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in max with retraction aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class MaxWithRetractAggFunctionTest[T: Numeric]
+ extends AggFunctionTestBase[T, MaxWithRetractAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def minVal: T
+
+ def maxVal: T
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ maxVal,
+ numeric.fromInt(-99),
+ numeric.fromInt(3),
+ numeric.fromInt(56),
+ numeric.fromInt(0),
+ minVal,
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T]
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ maxVal,
+ null.asInstanceOf[T]
+ )
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class ByteMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Byte] {
+
+ override def minVal = (Byte.MinValue + 1).toByte
+
+ override def maxVal = (Byte.MaxValue - 1).toByte
+
+ override def aggregator: AggregateFunction[Byte, MaxWithRetractAccumulator[Byte]] =
+ new ByteMaxWithRetractAggFunction()
+}
+
+class ShortMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Short] {
+
+ override def minVal = (Short.MinValue + 1).toShort
+
+ override def maxVal = (Short.MaxValue - 1).toShort
+
+ override def aggregator: AggregateFunction[Short, MaxWithRetractAccumulator[Short]] =
+ new ShortMaxWithRetractAggFunction()
+}
+
+class IntMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Int] {
+
+ override def minVal = Int.MinValue + 1
+
+ override def maxVal = Int.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Int, MaxWithRetractAccumulator[Int]] =
+ new IntMaxWithRetractAggFunction()
+}
+
+class LongMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Long] {
+
+ override def minVal = Long.MinValue + 1
+
+ override def maxVal = Long.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Long, MaxWithRetractAccumulator[Long]] =
+ new LongMaxWithRetractAggFunction()
+}
+
+class FloatMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Float] {
+
+ override def minVal = Float.MinValue / 2
+
+ override def maxVal = Float.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Float, MaxWithRetractAccumulator[Float]] =
+ new FloatMaxWithRetractAggFunction()
+}
+
+class DoubleMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Double] {
+
+ override def minVal = Double.MinValue / 2
+
+ override def maxVal = Double.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Double, MaxWithRetractAccumulator[Double]] =
+ new DoubleMaxWithRetractAggFunction()
+}
+
+class BooleanMaxWithRetractAggFunctionTest
+ extends AggFunctionTestBase[Boolean, MaxWithRetractAccumulator[Boolean]] {
+
+ override def inputValueSets: Seq[Seq[Boolean]] = Seq(
+ Seq(
+ false,
+ false,
+ false
+ ),
+ Seq(
+ true,
+ true,
+ true
+ ),
+ Seq(
+ true,
+ false,
+ null.asInstanceOf[Boolean],
+ true,
+ false,
+ true,
+ null.asInstanceOf[Boolean]
+ ),
+ Seq(
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean]
+ )
+ )
+
+ override def expectedResults: Seq[Boolean] = Seq(
+ false,
+ true,
+ true,
+ null.asInstanceOf[Boolean]
+ )
+
+ override def aggregator: AggregateFunction[Boolean, MaxWithRetractAccumulator[Boolean]] =
+ new BooleanMaxWithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class DecimalMaxWithRetractAggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, MaxWithRetractAccumulator[BigDecimal]] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("1000.000001"),
+ new BigDecimal("-1"),
+ new BigDecimal("-999.998999"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-999.999"),
+ null,
+ new BigDecimal("999.999")
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("1000.000001"),
+ null
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, MaxWithRetractAccumulator[BigDecimal]] =
+ new DecimalMaxWithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class StringMaxWithRetractAggFunctionTest
+ extends AggFunctionTestBase[String, MaxWithRetractAccumulator[String]] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ "abc",
+ "def",
+ "ghi",
+ null,
+ "jkl",
+ null,
+ "zzz"
+ ),
+ Seq(
+ null,
+ null
+ ),
+ Seq(
+ "x",
+ null,
+ "e"
+ )
+ )
+
+ override def expectedResults: Seq[String] = Seq(
+ "zzz",
+ null,
+ "x"
+ )
+
+ override def aggregator: AggregateFunction[String, MaxWithRetractAccumulator[String]] =
+ new StringMaxWithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinAggFunctionTest.scala
new file mode 100644
index 0000000..80fcace
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinAggFunctionTest.scala
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in min aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class MinAggFunctionTest[T: Numeric] extends AggFunctionTestBase[T, MinAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def minVal: T
+
+ def maxVal: T
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ maxVal,
+ numeric.fromInt(-99),
+ numeric.fromInt(3),
+ numeric.fromInt(56),
+ numeric.fromInt(0),
+ minVal,
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T]
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ minVal,
+ null.asInstanceOf[T]
+ )
+}
+
+class ByteMinAggFunctionTest extends MinAggFunctionTest[Byte] {
+
+ override def minVal = (Byte.MinValue + 1).toByte
+
+ override def maxVal = (Byte.MaxValue - 1).toByte
+
+ override def aggregator: AggregateFunction[Byte, MinAccumulator[Byte]] =
+ new ByteMinAggFunction()
+}
+
+class ShortMinAggFunctionTest extends MinAggFunctionTest[Short] {
+
+ override def minVal = (Short.MinValue + 1).toShort
+
+ override def maxVal = (Short.MaxValue - 1).toShort
+
+ override def aggregator: AggregateFunction[Short, MinAccumulator[Short]] =
+ new ShortMinAggFunction()
+}
+
+class IntMinAggFunctionTest extends MinAggFunctionTest[Int] {
+
+ override def minVal = Int.MinValue + 1
+
+ override def maxVal = Int.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Int, MinAccumulator[Int]] =
+ new IntMinAggFunction()
+}
+
+class LongMinAggFunctionTest extends MinAggFunctionTest[Long] {
+
+ override def minVal = Long.MinValue + 1
+
+ override def maxVal = Long.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Long, MinAccumulator[Long]] =
+ new LongMinAggFunction()
+}
+
+class FloatMinAggFunctionTest extends MinAggFunctionTest[Float] {
+
+ override def minVal = Float.MinValue / 2
+
+ override def maxVal = Float.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Float, MinAccumulator[Float]] =
+ new FloatMinAggFunction()
+}
+
+class DoubleMinAggFunctionTest extends MinAggFunctionTest[Double] {
+
+ override def minVal = Double.MinValue / 2
+
+ override def maxVal = Double.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Double, MinAccumulator[Double]] =
+ new DoubleMinAggFunction()
+}
+
+class BooleanMinAggFunctionTest extends AggFunctionTestBase[Boolean, MinAccumulator[Boolean]] {
+
+ override def inputValueSets: Seq[Seq[Boolean]] = Seq(
+ Seq(
+ false,
+ false,
+ false
+ ),
+ Seq(
+ true,
+ true,
+ true
+ ),
+ Seq(
+ true,
+ false,
+ null.asInstanceOf[Boolean],
+ true,
+ false,
+ true,
+ null.asInstanceOf[Boolean]
+ ),
+ Seq(
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean]
+ )
+ )
+
+ override def expectedResults: Seq[Boolean] = Seq(
+ false,
+ true,
+ false,
+ null.asInstanceOf[Boolean]
+ )
+
+ override def aggregator: AggregateFunction[Boolean, MinAccumulator[Boolean]] =
+ new BooleanMinAggFunction()
+}
+
+class DecimalMinAggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, MinAccumulator[BigDecimal]] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("1000"),
+ new BigDecimal("-1"),
+ new BigDecimal("-999.998999"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-999.999"),
+ null,
+ new BigDecimal("999.999")
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("-999.999"),
+ null
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, MinAccumulator[BigDecimal]] =
+ new DecimalMinAggFunction()
+}
+
+class StringMinAggFunctionTest
+ extends AggFunctionTestBase[String, MinAccumulator[String]] {
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new String("a"),
+ new String("b"),
+ new String("c"),
+ null.asInstanceOf[String],
+ new String("d")
+ ),
+ Seq(
+ null.asInstanceOf[String],
+ null.asInstanceOf[String],
+ null.asInstanceOf[String]
+ ),
+ Seq(
+ new String("1House"),
+ new String("Household"),
+ new String("house"),
+ new String("household")
+ )
+ )
+
+ override def expectedResults: Seq[String] = Seq(
+ new String("a"),
+ null.asInstanceOf[String],
+ new String("1House")
+ )
+
+ override def aggregator: AggregateFunction[String, MinAccumulator[String]] =
+ new StringMinAggFunction()
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinWithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinWithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinWithRetractAggFunctionTest.scala
new file mode 100644
index 0000000..c4273f6
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/MinWithRetractAggFunctionTest.scala
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in Min with retraction aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class MinWithRetractAggFunctionTest[T: Numeric]
+ extends AggFunctionTestBase[T, MinWithRetractAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def minVal: T
+
+ def maxVal: T
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ maxVal,
+ numeric.fromInt(-99),
+ numeric.fromInt(3),
+ numeric.fromInt(56),
+ numeric.fromInt(0),
+ minVal,
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T]
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ minVal,
+ null.asInstanceOf[T]
+ )
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class ByteMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Byte] {
+
+ override def minVal = (Byte.MinValue + 1).toByte
+
+ override def maxVal = (Byte.MaxValue - 1).toByte
+
+ override def aggregator: AggregateFunction[Byte, MinWithRetractAccumulator[Byte]] =
+ new ByteMinWithRetractAggFunction()
+}
+
+class ShortMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Short] {
+
+ override def minVal = (Short.MinValue + 1).toShort
+
+ override def maxVal = (Short.MaxValue - 1).toShort
+
+ override def aggregator: AggregateFunction[Short, MinWithRetractAccumulator[Short]] =
+ new ShortMinWithRetractAggFunction()
+}
+
+class IntMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Int] {
+
+ override def minVal = Int.MinValue + 1
+
+ override def maxVal = Int.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Int, MinWithRetractAccumulator[Int]] =
+ new IntMinWithRetractAggFunction()
+}
+
+class LongMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Long] {
+
+ override def minVal = Long.MinValue + 1
+
+ override def maxVal = Long.MaxValue - 1
+
+ override def aggregator: AggregateFunction[Long, MinWithRetractAccumulator[Long]] =
+ new LongMinWithRetractAggFunction()
+}
+
+class FloatMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Float] {
+
+ override def minVal = Float.MinValue / 2
+
+ override def maxVal = Float.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Float, MinWithRetractAccumulator[Float]] =
+ new FloatMinWithRetractAggFunction()
+}
+
+class DoubleMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Double] {
+
+ override def minVal = Double.MinValue / 2
+
+ override def maxVal = Double.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Double, MinWithRetractAccumulator[Double]] =
+ new DoubleMinWithRetractAggFunction()
+}
+
+class BooleanMinWithRetractAggFunctionTest
+ extends AggFunctionTestBase[Boolean, MinWithRetractAccumulator[Boolean]] {
+
+ override def inputValueSets: Seq[Seq[Boolean]] = Seq(
+ Seq(
+ false,
+ false,
+ false
+ ),
+ Seq(
+ true,
+ true,
+ true
+ ),
+ Seq(
+ true,
+ false,
+ null.asInstanceOf[Boolean],
+ true,
+ false,
+ true,
+ null.asInstanceOf[Boolean]
+ ),
+ Seq(
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean],
+ null.asInstanceOf[Boolean]
+ )
+ )
+
+ override def expectedResults: Seq[Boolean] = Seq(
+ false,
+ true,
+ false,
+ null.asInstanceOf[Boolean]
+ )
+
+ override def aggregator: AggregateFunction[Boolean, MinWithRetractAccumulator[Boolean]] =
+ new BooleanMinWithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class DecimalMinWithRetractAggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, MinWithRetractAccumulator[BigDecimal]] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("1000"),
+ new BigDecimal("-1"),
+ new BigDecimal("-999.998999"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-999.999"),
+ null,
+ new BigDecimal("999.999")
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("-999.999"),
+ null
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, MinWithRetractAccumulator[BigDecimal]] =
+ new DecimalMinWithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class StringMinWithRetractAggFunctionTest
+ extends AggFunctionTestBase[String, MinWithRetractAccumulator[String]] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ "abc",
+ "def",
+ "ghi",
+ null,
+ "jkl",
+ null,
+ "zzz"
+ ),
+ Seq(
+ null,
+ null
+ ),
+ Seq(
+ "x",
+ null,
+ "e"
+ )
+ )
+
+ override def expectedResults: Seq[String] = Seq(
+ "abc",
+ null,
+ "e"
+ )
+
+ override def aggregator: AggregateFunction[String, MinWithRetractAccumulator[String]] =
+ new StringMinWithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0AggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0AggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0AggFunctionTest.scala
new file mode 100644
index 0000000..45c5aea
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0AggFunctionTest.scala
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in sum0 aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class Sum0AggFunctionTestBase[T: Numeric]
+ extends AggFunctionTestBase[T, SumAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def maxVal: T
+
+ private val minVal = numeric.negate(maxVal)
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ minVal,
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ numeric.fromInt(2),
+ numeric.fromInt(3),
+ numeric.fromInt(4),
+ numeric.fromInt(5),
+ numeric.fromInt(-10),
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T],
+ maxVal
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ numeric.fromInt(2),
+ 0.asInstanceOf[T]
+ )
+}
+
+class ByteSum0AggFunctionTest extends Sum0AggFunctionTestBase[Byte] {
+
+ override def maxVal = (Byte.MaxValue / 2).toByte
+
+ override def aggregator: AggregateFunction[Byte, SumAccumulator[Byte]] =
+ new ByteSum0AggFunction
+}
+
+class ShortSum0AggFunctionTest extends Sum0AggFunctionTestBase[Short] {
+
+ override def maxVal = (Short.MaxValue / 2).toShort
+
+ override def aggregator: AggregateFunction[Short, SumAccumulator[Short]] =
+ new ShortSum0AggFunction
+}
+
+class IntSum0AggFunctionTest extends Sum0AggFunctionTestBase[Int] {
+
+ override def maxVal = Int.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Int, SumAccumulator[Int]] =
+ new IntSum0AggFunction
+}
+
+class LongSum0AggFunctionTest extends Sum0AggFunctionTestBase[Long] {
+
+ override def maxVal = Long.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Long, SumAccumulator[Long]] =
+ new LongSum0AggFunction
+}
+
+class FloatSum0AggFunctionTest extends Sum0AggFunctionTestBase[Float] {
+
+ override def maxVal = 12345.6789f
+
+ override def aggregator: AggregateFunction[Float, SumAccumulator[Float]] =
+ new FloatSum0AggFunction
+}
+
+class DoubleSum0AggFunctionTest extends Sum0AggFunctionTestBase[Double] {
+
+ override def maxVal = 12345.6789d
+
+ override def aggregator: AggregateFunction[Double, SumAccumulator[Double]] =
+ new DoubleSum0AggFunction
+}
+
+
+class DecimalSum0AggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, DecimalSumAccumulator] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("2"),
+ new BigDecimal("3"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-1000"),
+ new BigDecimal("0.000000000002"),
+ new BigDecimal("1000"),
+ new BigDecimal("-0.000000000001"),
+ new BigDecimal("999.999"),
+ null,
+ new BigDecimal("4"),
+ new BigDecimal("-999.999"),
+ null
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("10.000000000001"),
+ BigDecimal.ZERO
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, DecimalSumAccumulator] =
+ new DecimalSum0AggFunction()
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0WithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0WithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0WithRetractAggFunctionTest.scala
new file mode 100644
index 0000000..7779614
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/Sum0WithRetractAggFunctionTest.scala
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in sum0 with retract aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class Sum0WithRetractAggFunctionTestBase[T: Numeric]
+ extends AggFunctionTestBase[T, SumWithRetractAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def maxVal: T
+
+ private val minVal = numeric.negate(maxVal)
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ minVal,
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ numeric.fromInt(2),
+ numeric.fromInt(3),
+ numeric.fromInt(4),
+ numeric.fromInt(5),
+ numeric.fromInt(-10),
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T],
+ maxVal
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ numeric.fromInt(2),
+ 0.asInstanceOf[T]
+ )
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class ByteSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Byte] {
+
+ override def maxVal = (Byte.MaxValue / 2).toByte
+
+ override def aggregator: AggregateFunction[Byte, SumWithRetractAccumulator[Byte]] =
+ new ByteSum0WithRetractAggFunction
+}
+
+class ShortSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Short] {
+
+ override def maxVal = (Short.MaxValue / 2).toShort
+
+ override def aggregator: AggregateFunction[Short, SumWithRetractAccumulator[Short]] =
+ new ShortSum0WithRetractAggFunction
+}
+
+class IntSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Int] {
+
+ override def maxVal = Int.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Int, SumWithRetractAccumulator[Int]] =
+ new IntSum0WithRetractAggFunction
+}
+
+class LongSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Long] {
+
+ override def maxVal = Long.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Long, SumWithRetractAccumulator[Long]] =
+ new LongSum0WithRetractAggFunction
+}
+
+class FloatSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Float] {
+
+ override def maxVal = 12345.6789f
+
+ override def aggregator: AggregateFunction[Float, SumWithRetractAccumulator[Float]] =
+ new FloatSum0WithRetractAggFunction
+}
+
+class DoubleSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Double] {
+
+ override def maxVal = 12345.6789d
+
+ override def aggregator: AggregateFunction[Double, SumWithRetractAccumulator[Double]] =
+ new DoubleSum0WithRetractAggFunction
+}
+
+
+class DecimalSum0WithRetractAggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, DecimalSumWithRetractAccumulator] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("2"),
+ new BigDecimal("3"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-1000"),
+ new BigDecimal("0.000000000002"),
+ new BigDecimal("1000"),
+ new BigDecimal("-0.000000000001"),
+ new BigDecimal("999.999"),
+ null,
+ new BigDecimal("4"),
+ new BigDecimal("-999.999"),
+ null
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("10.000000000001"),
+ BigDecimal.ZERO
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, DecimalSumWithRetractAccumulator] =
+ new DecimalSum0WithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumAggFunctionTest.scala
new file mode 100644
index 0000000..a1f31ad
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumAggFunctionTest.scala
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in sum aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class SumAggFunctionTestBase[T: Numeric]
+ extends AggFunctionTestBase[T, SumAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def maxVal: T
+
+ private val minVal = numeric.negate(maxVal)
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ minVal,
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ numeric.fromInt(2),
+ numeric.fromInt(3),
+ numeric.fromInt(4),
+ numeric.fromInt(5),
+ numeric.fromInt(-10),
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T],
+ maxVal
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ numeric.fromInt(2),
+ null.asInstanceOf[T]
+ )
+}
+
+class ByteSumAggFunctionTest extends SumAggFunctionTestBase[Byte] {
+
+ override def maxVal = (Byte.MaxValue / 2).toByte
+
+ override def aggregator: AggregateFunction[Byte, SumAccumulator[Byte]] =
+ new ByteSumAggFunction
+}
+
+class ShortSumAggFunctionTest extends SumAggFunctionTestBase[Short] {
+
+ override def maxVal = (Short.MaxValue / 2).toShort
+
+ override def aggregator: AggregateFunction[Short, SumAccumulator[Short]] =
+ new ShortSumAggFunction
+}
+
+class IntSumAggFunctionTest extends SumAggFunctionTestBase[Int] {
+
+ override def maxVal = Int.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Int, SumAccumulator[Int]] =
+ new IntSumAggFunction
+}
+
+class LongSumAggFunctionTest extends SumAggFunctionTestBase[Long] {
+
+ override def maxVal = Long.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Long, SumAccumulator[Long]] =
+ new LongSumAggFunction
+}
+
+class FloatSumAggFunctionTest extends SumAggFunctionTestBase[Float] {
+
+ override def maxVal = 12345.6789f
+
+ override def aggregator: AggregateFunction[Float, SumAccumulator[Float]] =
+ new FloatSumAggFunction
+}
+
+class DoubleSumAggFunctionTest extends SumAggFunctionTestBase[Double] {
+
+ override def maxVal = 12345.6789d
+
+ override def aggregator: AggregateFunction[Double, SumAccumulator[Double]] =
+ new DoubleSumAggFunction
+}
+
+
+class DecimalSumAggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, DecimalSumAccumulator] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("2"),
+ new BigDecimal("3"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-1000"),
+ new BigDecimal("0.000000000002"),
+ new BigDecimal("1000"),
+ new BigDecimal("-0.000000000001"),
+ new BigDecimal("999.999"),
+ null,
+ new BigDecimal("4"),
+ new BigDecimal("-999.999"),
+ null
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("10.000000000001"),
+ null
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, DecimalSumAccumulator] =
+ new DecimalSumAggFunction()
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumWithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumWithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumWithRetractAggFunctionTest.scala
new file mode 100644
index 0000000..7a992d7
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggfunctions/SumWithRetractAggFunctionTest.scala
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.aggfunctions
+
+import java.math.BigDecimal
+
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.functions.aggfunctions._
+
+/**
+ * Test case for built-in sum with retract aggregate function
+ *
+ * @tparam T the type for the aggregation result
+ */
+abstract class SumWithRetractAggFunctionTestBase[T: Numeric]
+ extends AggFunctionTestBase[T, SumWithRetractAccumulator[T]] {
+
+ private val numeric: Numeric[T] = implicitly[Numeric[T]]
+
+ def maxVal: T
+
+ private val minVal = numeric.negate(maxVal)
+
+ override def inputValueSets: Seq[Seq[T]] = Seq(
+ Seq(
+ minVal,
+ numeric.fromInt(1),
+ null.asInstanceOf[T],
+ numeric.fromInt(2),
+ numeric.fromInt(3),
+ numeric.fromInt(4),
+ numeric.fromInt(5),
+ numeric.fromInt(-10),
+ numeric.fromInt(-20),
+ numeric.fromInt(17),
+ null.asInstanceOf[T],
+ maxVal
+ ),
+ Seq(
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T],
+ null.asInstanceOf[T]
+ )
+ )
+
+ override def expectedResults: Seq[T] = Seq(
+ numeric.fromInt(2),
+ null.asInstanceOf[T]
+ )
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+class ByteSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Byte] {
+
+ override def maxVal = (Byte.MaxValue / 2).toByte
+
+ override def aggregator: AggregateFunction[Byte, SumWithRetractAccumulator[Byte]] =
+ new ByteSumWithRetractAggFunction
+}
+
+class ShortSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Short] {
+
+ override def maxVal = (Short.MaxValue / 2).toShort
+
+ override def aggregator: AggregateFunction[Short, SumWithRetractAccumulator[Short]] =
+ new ShortSumWithRetractAggFunction
+}
+
+class IntSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Int] {
+
+ override def maxVal = Int.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Int, SumWithRetractAccumulator[Int]] =
+ new IntSumWithRetractAggFunction
+}
+
+class LongSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Long] {
+
+ override def maxVal = Long.MaxValue / 2
+
+ override def aggregator: AggregateFunction[Long, SumWithRetractAccumulator[Long]] =
+ new LongSumWithRetractAggFunction
+}
+
+class FloatSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Float] {
+
+ override def maxVal = 12345.6789f
+
+ override def aggregator: AggregateFunction[Float, SumWithRetractAccumulator[Float]] =
+ new FloatSumWithRetractAggFunction
+}
+
+class DoubleSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Double] {
+
+ override def maxVal = 12345.6789d
+
+ override def aggregator: AggregateFunction[Double, SumWithRetractAccumulator[Double]] =
+ new DoubleSumWithRetractAggFunction
+}
+
+
+class DecimalSumWithRetractAggFunctionTest
+ extends AggFunctionTestBase[BigDecimal, DecimalSumWithRetractAccumulator] {
+
+ override def inputValueSets: Seq[Seq[_]] = Seq(
+ Seq(
+ new BigDecimal("1"),
+ new BigDecimal("2"),
+ new BigDecimal("3"),
+ null,
+ new BigDecimal("0"),
+ new BigDecimal("-1000"),
+ new BigDecimal("0.000000000002"),
+ new BigDecimal("1000"),
+ new BigDecimal("-0.000000000001"),
+ new BigDecimal("999.999"),
+ null,
+ new BigDecimal("4"),
+ new BigDecimal("-999.999"),
+ null
+ ),
+ Seq(
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+ )
+
+ override def expectedResults: Seq[BigDecimal] = Seq(
+ new BigDecimal("10.000000000001"),
+ null
+ )
+
+ override def aggregator: AggregateFunction[BigDecimal, DecimalSumWithRetractAccumulator] =
+ new DecimalSumWithRetractAggFunction()
+
+ override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggregate/TimeSortProcessFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggregate/TimeSortProcessFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggregate/TimeSortProcessFunctionTest.scala
deleted file mode 100644
index df4e1aa..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/aggregate/TimeSortProcessFunctionTest.scala
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.runtime.aggregate
-
-import java.util.concurrent.ConcurrentLinkedQueue
-import java.lang.{Integer => JInt, Long => JLong}
-
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo._
-import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
-import org.apache.flink.api.java.functions.KeySelector
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.streaming.api.operators.KeyedProcessOperator
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.streaming.runtime.streamrecord.StreamRecord
-import org.apache.flink.streaming.util.{KeyedOneInputStreamOperatorTestHarness, TestHarnessUtil}
-import org.apache.flink.types.Row
-import org.junit.Test
-import org.apache.flink.table.runtime.aggregate.TimeSortProcessFunctionTest._
-import org.apache.flink.api.java.typeutils.runtime.RowComparator
-import org.apache.flink.api.common.typeutils.TypeSerializer
-import org.apache.flink.api.common.typeutils.TypeComparator
-import org.apache.flink.table.runtime.types.{CRow, CRowTypeInfo}
-import org.apache.flink.streaming.api.TimeCharacteristic
-
-class TimeSortProcessFunctionTest {
-
-
- @Test
- def testSortProcTimeHarnessPartitioned(): Unit = {
-
- val rT = new RowTypeInfo(Array[TypeInformation[_]](
- INT_TYPE_INFO,
- LONG_TYPE_INFO,
- INT_TYPE_INFO,
- STRING_TYPE_INFO,
- LONG_TYPE_INFO),
- Array("a", "b", "c", "d", "e"))
-
- val indexes = Array(1, 2)
-
- val fieldComps = Array[TypeComparator[AnyRef]](
- LONG_TYPE_INFO.createComparator(true, null).asInstanceOf[TypeComparator[AnyRef]],
- INT_TYPE_INFO.createComparator(false, null).asInstanceOf[TypeComparator[AnyRef]] )
- val booleanOrders = Array(true, false)
-
-
- val rowComp = new RowComparator(
- rT.getTotalFields,
- indexes,
- fieldComps,
- new Array[TypeSerializer[AnyRef]](0), //used only for serialized comparisons
- booleanOrders)
-
- val collectionRowComparator = new CollectionRowComparator(rowComp)
-
- val inputCRowType = CRowTypeInfo(rT)
-
- val processFunction = new KeyedProcessOperator[Integer,CRow,CRow](
- new ProcTimeSortProcessFunction(
- inputCRowType,
- collectionRowComparator))
-
- val testHarness = new KeyedOneInputStreamOperatorTestHarness[Integer,CRow,CRow](
- processFunction,
- new TupleRowSelector(0),
- BasicTypeInfo.INT_TYPE_INFO)
-
- testHarness.open()
-
- testHarness.setProcessingTime(3)
-
- // timestamp is ignored in processing time
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong), true), 1001))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2002))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2003))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2004))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2006))
-
- //move the timestamp to ensure the execution
- testHarness.setProcessingTime(1005)
-
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 1L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2007))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 3L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2007))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 2L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2007))
-
- testHarness.setProcessingTime(1008)
-
- val result = testHarness.getOutput
-
- val expectedOutput = new ConcurrentLinkedQueue[Object]()
-
- // all elements at the same proc timestamp have the same value
- // elements should be sorted ascending on field 1 and descending on field 2
- // (10,0) (11,1) (12,2) (12,1) (12,0)
- // (1,0) (2,0)
-
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong),true), 4))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong),true), 4))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 2: JInt, "aaa", 11L: JLong),true), 4))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong),true), 4))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 0: JInt, "aaa", 11L: JLong),true), 4))
-
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 1L: JLong, 0: JInt, "aaa", 11L: JLong),true), 1006))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 2L: JLong, 0: JInt, "aaa", 11L: JLong),true), 1006))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 3L: JLong, 0: JInt, "aaa", 11L: JLong),true), 1006))
-
- TestHarnessUtil.assertOutputEquals("Output was not correctly sorted.", expectedOutput, result)
-
- testHarness.close()
- }
-
- @Test
- def testSortRowTimeHarnessPartitioned(): Unit = {
-
- val rT = new RowTypeInfo(Array[TypeInformation[_]](
- INT_TYPE_INFO,
- LONG_TYPE_INFO,
- INT_TYPE_INFO,
- STRING_TYPE_INFO,
- LONG_TYPE_INFO),
- Array("a", "b", "c", "d", "e"))
-
- val indexes = Array(1, 2)
-
- val fieldComps = Array[TypeComparator[AnyRef]](
- LONG_TYPE_INFO.createComparator(true, null).asInstanceOf[TypeComparator[AnyRef]],
- INT_TYPE_INFO.createComparator(false, null).asInstanceOf[TypeComparator[AnyRef]] )
- val booleanOrders = Array(true, false)
-
- val rowComp = new RowComparator(
- rT.getTotalFields,
- indexes,
- fieldComps,
- new Array[TypeSerializer[AnyRef]](0), //used only for serialized comparisons
- booleanOrders)
-
- val collectionRowComparator = new CollectionRowComparator(rowComp)
-
- val inputCRowType = CRowTypeInfo(rT)
-
- val processFunction = new KeyedProcessOperator[Integer,CRow,CRow](
- new RowTimeSortProcessFunction(
- inputCRowType,
- Some(collectionRowComparator)))
-
- val testHarness = new KeyedOneInputStreamOperatorTestHarness[Integer, CRow, CRow](
- processFunction,
- new TupleRowSelector(0),
- BasicTypeInfo.INT_TYPE_INFO)
-
- testHarness.open()
-
- testHarness.setTimeCharacteristic(TimeCharacteristic.EventTime)
- testHarness.processWatermark(3)
-
- // timestamp is ignored in processing time
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong), true), 1001))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2002))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 13L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2002))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong), true), 2002))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 14L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2002))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong), true), 2004))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2006))
-
- // move watermark forward
- testHarness.processWatermark(2007)
-
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 20L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2008))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 14L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2002)) // too late
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong), true), 2019)) // too early
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 20L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2008))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2010))
- testHarness.processElement(new StreamRecord(new CRow(
- Row.of(1: JInt, 19L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2008))
-
- // move watermark forward
- testHarness.processWatermark(2012)
-
- val result = testHarness.getOutput
-
- val expectedOutput = new ConcurrentLinkedQueue[Object]()
-
- // all elements at the same proc timestamp have the same value
- // elements should be sorted ascending on field 1 and descending on field 2
- // (10,0) (11,1) (12,2) (12,1) (12,0)
- expectedOutput.add(new Watermark(3))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 11L: JLong, 1: JInt, "aaa", 11L: JLong),true), 1001))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong),true), 2002))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 1: JInt, "aaa", 11L: JLong),true), 2002))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 13L: JLong, 2: JInt, "aaa", 11L: JLong),true), 2002))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 14L: JLong, 0: JInt, "aaa", 11L: JLong),true), 2002))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 12L: JLong, 3: JInt, "aaa", 11L: JLong),true), 2004))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong),true), 2006))
- expectedOutput.add(new Watermark(2007))
-
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 19L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2008))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 20L: JLong, 2: JInt, "aaa", 11L: JLong), true), 2008))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 20L: JLong, 1: JInt, "aaa", 11L: JLong), true), 2008))
- expectedOutput.add(new StreamRecord(new CRow(
- Row.of(1: JInt, 10L: JLong, 0: JInt, "aaa", 11L: JLong), true), 2010))
-
- expectedOutput.add(new Watermark(2012))
-
- TestHarnessUtil.assertOutputEquals("Output was not correctly sorted.", expectedOutput, result)
-
- testHarness.close()
-
- }
-}
-
-object TimeSortProcessFunctionTest {
-
- /**
- * Simple test class that returns a specified field as the selector function
- */
- class TupleRowSelector(private val selectorField: Int) extends KeySelector[CRow, Integer] {
-
- override def getKey(value: CRow): Integer = {
- value.row.getField(selectorField).asInstanceOf[Integer]
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/AggregateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/AggregateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/AggregateITCase.scala
new file mode 100644
index 0000000..39b8371
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/AggregateITCase.scala
@@ -0,0 +1,394 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMergeAndReset
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class AggregateITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testAggregationTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1), min(_1), max(_1), count(_1), avg(_1) FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231,1,21,21,11"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1) FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDataSetAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1) FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationDataTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), avg(b), avg(c), avg(d), avg(e), avg(f), count(g), " +
+ "min(g), min('Ciao'), max(g), max('Ciao'), sum(CAST(f AS DECIMAL)) FROM MyTable"
+
+ val ds = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'f, 'g)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,1,1,1.5,1.5,2,Ciao,Ciao,Hello,Ciao,3.0"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), sum(a), count(a), avg(b), sum(b) " +
+ "FROM MyTable"
+
+ val ds = env.fromElements((1: Byte, 1: Short), (2: Byte, 2: Short)).toTable(tEnv, 'a, 'b)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,3,2,1,3"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableAggregationWithArithmetic(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a + 2) + 2, count(b) + 5 " +
+ "FROM MyTable"
+
+ val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv, 'a, 'b)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "5.5,7"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationWithTwoCount(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT count(_1), count(_2) FROM MyTable"
+
+ val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "2,2"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+
+ @Test
+ def testAggregationAfterProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM " +
+ "(SELECT _1 as a, _2 as b, _3 as c FROM MyTable)"
+
+ val ds = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,3,2"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDistinctAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1) as a, count(distinct _3) as b FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231,21"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedDistinctAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT _2, avg(distinct _1) as a, count(_3) as b FROM MyTable GROUP BY _2"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected =
+ "6,18,6\n5,13,5\n4,8,4\n3,5,3\n2,2,2\n1,1,1"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupingSetAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery =
+ "SELECT _2, _3, avg(_1) as a, GROUP_ID() as g FROM MyTable GROUP BY GROUPING SETS (_2, _3)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+
+ val expected =
+ "6,null,18,1\n5,null,13,1\n4,null,8,1\n3,null,5,1\n2,null,2,1\n1,null,1,1\n" +
+ "null,Luke Skywalker,6,2\nnull,I am fine.,5,2\nnull,Hi,1,2\n" +
+ "null,Hello world, how are you?,4,2\nnull,Hello world,3,2\nnull,Hello,2,2\n" +
+ "null,Comment#9,15,2\nnull,Comment#8,14,2\nnull,Comment#7,13,2\n" +
+ "null,Comment#6,12,2\nnull,Comment#5,11,2\nnull,Comment#4,10,2\n" +
+ "null,Comment#3,9,2\nnull,Comment#2,8,2\nnull,Comment#15,21,2\n" +
+ "null,Comment#14,20,2\nnull,Comment#13,19,2\nnull,Comment#12,18,2\n" +
+ "null,Comment#11,17,2\nnull,Comment#10,16,2\nnull,Comment#1,7,2"
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testAggregateEmptyDataSets(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), sum(a), count(b) " +
+ "FROM MyTable where a = 4 group by a"
+
+ val sqlQuery2 = "SELECT avg(a), sum(a), count(b) " +
+ "FROM MyTable where a = 4"
+
+ val sqlQuery3 = "SELECT avg(a), sum(a), count(b) " +
+ "FROM MyTable"
+
+ val ds = env.fromElements(
+ (1: Byte, 1: Short),
+ (2: Byte, 2: Short))
+ .toTable(tEnv, 'a, 'b)
+
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+ val result2 = tEnv.sql(sqlQuery2)
+ val result3 = tEnv.sql(sqlQuery3)
+
+ val results = result.toDataSet[Row].collect()
+ val expected = Seq.empty
+ val results2 = result2.toDataSet[Row].collect()
+ val expected2 = "null,null,0"
+ val results3 = result3.toDataSet[Row].collect()
+ val expected3 = "1,3,2"
+
+ assert(results.equals(expected),
+ "Empty result is expected for grouped set, but actual: " + results)
+ TestBaseUtils.compareResultAsText(results2.asJava, expected2)
+ TestBaseUtils.compareResultAsText(results3.asJava, expected3)
+ }
+
+ @Test
+ def testTumbleWindowAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.registerFunction("countFun", new CountAggFunction)
+ tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
+
+ val sqlQuery =
+ "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
+ "FROM T " +
+ "GROUP BY b, TUMBLE(ts, INTERVAL '3' SECOND)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ // create timestamps
+ .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
+ tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ val expected = Seq(
+ "1,1,1,1,1",
+ "2,2,1,2,2", "2,3,1,2,3",
+ "3,9,2,3,4", "3,6,1,3,6",
+ "4,15,2,4,7", "4,19,2,4,9",
+ "5,11,1,5,11", "5,39,3,5,13", "5,15,1,5,15",
+ "6,33,2,6,16", "6,57,3,6,19", "6,21,1,6,21"
+ ).mkString("\n")
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testHopWindowAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.registerFunction("countFun", new CountAggFunction)
+ tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
+
+ env.setParallelism(1)
+
+ val sqlQuery =
+ "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
+ "FROM T " +
+ "GROUP BY b, HOP(ts, INTERVAL '2' SECOND, INTERVAL '4' SECOND)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ // create timestamps
+ .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
+ tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ val expected = Seq(
+ "1,1,1,1,1","1,1,1,1,1",
+ "2,5,2,2,2","2,5,2,2,2",
+ "3,9,2,3,4", "3,15,3,3,5", "3,6,1,3,6",
+ "4,7,1,4,7", "4,24,3,4,8", "4,27,3,4,9", "4,10,1,4,10",
+ "5,11,1,5,11", "5,36,3,5,12", "5,54,4,5,13", "5,29,2,5,14",
+ "6,33,2,6,16", "6,70,4,6,17", "6,78,4,6,19", "6,41,2,6,20"
+ ).mkString("\n")
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testSessionWindowAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.registerFunction("countFun", new CountAggFunction)
+ tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
+
+ env.setParallelism(1)
+
+ val sqlQuery =
+ "SELECT MIN(a), MAX(a), SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), " +
+ "wAvgWithMergeAndReset(a, a)" +
+ "FROM T " +
+ "GROUP BY SESSION(ts, INTERVAL '4' SECOND)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ // create timestamps
+ .filter(x => (x._2 % 2) == 0)
+ .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
+ tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ val expected = Seq(
+ "2,10,39,6,3,7",
+ "16,21,111,6,6,18"
+ ).mkString("\n")
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+}
[07/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
index 91e06c5..558e5b3 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
@@ -18,19 +18,11 @@
package org.apache.flink.table.expressions
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.{TupleTypeInfo, TypeExtractor}
-import org.apache.flink.api.scala.createTypeInformation
-import org.apache.flink.types.Row
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.table.api.{Types, ValidationException}
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.CompositeAccessTest.{MyCaseClass, MyCaseClass2, MyPojo}
-import org.apache.flink.table.expressions.utils.ExpressionTestBase
+import org.apache.flink.table.expressions.utils.CompositeAccessTestBase
import org.junit.Test
-
-class CompositeAccessTest extends ExpressionTestBase {
+class CompositeAccessTest extends CompositeAccessTestBase {
@Test
def testGetField(): Unit = {
@@ -129,85 +121,6 @@ class CompositeAccessTest extends ExpressionTestBase {
testTableApi('f5.flatten(), "f5.flatten()", "13")
}
- @Test(expected = classOf[ValidationException])
- def testWrongSqlFieldFull(): Unit = {
- testSqlApi("testTable.f5.test", "13")
- }
-
- @Test(expected = classOf[ValidationException])
- def testWrongSqlField(): Unit = {
- testSqlApi("f5.test", "13")
- }
-
- @Test(expected = classOf[ValidationException])
- def testWrongIntKeyField(): Unit = {
- testTableApi('f0.get(555), "'fail'", "fail")
- }
-
- @Test(expected = classOf[ValidationException])
- def testWrongIntKeyField2(): Unit = {
- testTableApi("fail", "f0.get(555)", "fail")
- }
-
- @Test(expected = classOf[ValidationException])
- def testWrongStringKeyField(): Unit = {
- testTableApi('f0.get("fghj"), "'fail'", "fail")
- }
-
- @Test(expected = classOf[ValidationException])
- def testWrongStringKeyField2(): Unit = {
- testTableApi("fail", "f0.get('fghj')", "fail")
- }
-
- // ----------------------------------------------------------------------------------------------
-
- def testData = {
- val testData = new Row(8)
- testData.setField(0, MyCaseClass(42, "Bob", booleanField = true))
- testData.setField(1, MyCaseClass2(MyCaseClass(25, "Timo", booleanField = false)))
- testData.setField(2, ("a", "b"))
- testData.setField(3, new org.apache.flink.api.java.tuple.Tuple2[String, String]("a", "b"))
- testData.setField(4, new MyPojo())
- testData.setField(5, 13)
- testData.setField(6, MyCaseClass2(null))
- testData.setField(7, Tuple1(true))
- testData
- }
-
- def typeInfo = {
- new RowTypeInfo(
- createTypeInformation[MyCaseClass],
- createTypeInformation[MyCaseClass2],
- createTypeInformation[(String, String)],
- new TupleTypeInfo(Types.STRING, Types.STRING),
- TypeExtractor.createTypeInfo(classOf[MyPojo]),
- Types.INT,
- createTypeInformation[MyCaseClass2],
- createTypeInformation[Tuple1[Boolean]]
- ).asInstanceOf[TypeInformation[Any]]
- }
-
}
-object CompositeAccessTest {
- case class MyCaseClass(intField: Int, stringField: String, booleanField: Boolean)
-
- case class MyCaseClass2(objectField: MyCaseClass)
- class MyPojo {
- private var myInt: Int = 0
- private var myString: String = "Hello"
-
- def getMyInt = myInt
-
- def setMyInt(value: Int) = {
- myInt = value
- }
-
- def getMyString = myString
-
- def setMyString(value: String) = {
- myString = myString
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
index ca80737..7b09733 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
@@ -18,21 +18,10 @@
package org.apache.flink.table.expressions
-import java.util.{HashMap => JHashMap}
-
-import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
-import org.apache.flink.api.java.typeutils.{MapTypeInfo, RowTypeInfo}
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.expressions.utils.ExpressionTestBase
-import org.apache.flink.types.Row
+import org.apache.flink.table.expressions.utils.MapTypeTestBase
import org.junit.Test
-class MapTypeTest extends ExpressionTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testWrongKeyType(): Unit = {
- testSqlApi("f4[12]", "FAIL")
- }
+class MapTypeTest extends MapTypeTestBase {
@Test
def testItem(): Unit = {
@@ -43,30 +32,4 @@ class MapTypeTest extends ExpressionTestBase {
testSqlApi("f3[12]", "a")
}
- // ----------------------------------------------------------------------------------------------
-
- override def testData: Any = {
- val testData = new Row(4)
- testData.setField(0, null)
- testData.setField(1, new JHashMap[String, Int]())
- val map = new JHashMap[String, Int]()
- map.put("a", 12)
- map.put("b", 13)
- testData.setField(2, map)
- val map2 = new JHashMap[Int, String]()
- map2.put(12, "a")
- map2.put(13, "b")
- testData.setField(3, map2)
- testData
- }
-
- override def typeInfo: TypeInformation[Any] = {
- new RowTypeInfo(
- new MapTypeInfo(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO),
- new MapTypeInfo(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO),
- new MapTypeInfo(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO),
- new MapTypeInfo(BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO)
- ).asInstanceOf[TypeInformation[Any]]
- }
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/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 be28134..ef021b7 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
@@ -18,17 +18,12 @@
package org.apache.flink.table.expressions
-import java.sql.{Date, Time, Timestamp}
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.table.api.Types
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{Types, ValidationException}
-import org.apache.flink.table.expressions.utils.ExpressionTestBase
-import org.apache.flink.types.Row
+import org.apache.flink.table.expressions.utils.ScalarFunctionsTestBase
import org.junit.Test
-class ScalarFunctionsTest extends ExpressionTestBase {
+class ScalarFunctionsTest extends ScalarFunctionsTestBase {
// ----------------------------------------------------------------------------------------------
// String functions
@@ -99,18 +94,6 @@ class ScalarFunctionsTest extends ExpressionTestBase {
"his is a test String.")
}
- @Test(expected = classOf[ValidationException])
- def testInvalidSubstring1(): Unit = {
- // Must fail. Parameter of substring must be an Integer not a Double.
- testTableApi("test".substring(2.0.toExpr), "FAIL", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidSubstring2(): Unit = {
- // Must fail. Parameter of substring must be an Integer not a String.
- testTableApi("test".substring("test".toExpr), "FAIL", "FAIL")
- }
-
@Test
def testTrim(): Unit = {
testAllApis(
@@ -1581,84 +1564,4 @@ class ScalarFunctionsTest extends ExpressionTestBase {
"f21 IS NOT FALSE",
"true")
}
-
- // ----------------------------------------------------------------------------------------------
-
- def testData = {
- val testData = new Row(34)
- testData.setField(0, "This is a test String.")
- testData.setField(1, true)
- testData.setField(2, 42.toByte)
- testData.setField(3, 43.toShort)
- testData.setField(4, 44.toLong)
- testData.setField(5, 4.5.toFloat)
- testData.setField(6, 4.6)
- testData.setField(7, 3)
- testData.setField(8, " This is a test String. ")
- testData.setField(9, -42.toByte)
- testData.setField(10, -43.toShort)
- testData.setField(11, -44.toLong)
- testData.setField(12, -4.5.toFloat)
- testData.setField(13, -4.6)
- testData.setField(14, -3)
- testData.setField(15, BigDecimal("-1231.1231231321321321111").bigDecimal)
- testData.setField(16, Date.valueOf("1996-11-10"))
- testData.setField(17, Time.valueOf("06:55:44"))
- testData.setField(18, Timestamp.valueOf("1996-11-10 06:55:44.333"))
- testData.setField(19, 1467012213000L) // +16979 07:23:33.000
- testData.setField(20, 25) // +2-01
- testData.setField(21, null)
- testData.setField(22, BigDecimal("2").bigDecimal)
- testData.setField(23, "%This is a test String.")
- testData.setField(24, "*_This is a test String.")
- testData.setField(25, 0.42.toByte)
- testData.setField(26, 0.toShort)
- testData.setField(27, 0.toLong)
- testData.setField(28, 0.45.toFloat)
- testData.setField(29, 0.46)
- testData.setField(30, 1)
- testData.setField(31, BigDecimal("-0.1231231321321321111").bigDecimal)
- testData.setField(32, -1)
- testData.setField(33, null)
- testData
- }
-
- def typeInfo = {
- new RowTypeInfo(
- Types.STRING,
- Types.BOOLEAN,
- Types.BYTE,
- Types.SHORT,
- Types.LONG,
- Types.FLOAT,
- Types.DOUBLE,
- Types.INT,
- Types.STRING,
- Types.BYTE,
- Types.SHORT,
- Types.LONG,
- Types.FLOAT,
- Types.DOUBLE,
- Types.INT,
- Types.DECIMAL,
- Types.SQL_DATE,
- Types.SQL_TIME,
- Types.SQL_TIMESTAMP,
- Types.INTERVAL_MILLIS,
- Types.INTERVAL_MONTHS,
- Types.BOOLEAN,
- Types.DECIMAL,
- Types.STRING,
- Types.STRING,
- Types.BYTE,
- Types.SHORT,
- Types.LONG,
- Types.FLOAT,
- Types.DOUBLE,
- Types.INT,
- Types.DECIMAL,
- Types.INT,
- Types.STRING).asInstanceOf[TypeInformation[Any]]
-
- }
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
index 0639835..30f8a4c 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
@@ -18,16 +18,12 @@
package org.apache.flink.table.expressions
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.{Types, ValidationException}
+import org.apache.flink.table.api.Types
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.{ExpressionTestBase, ShouldNotExecuteFunc}
-import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.table.expressions.utils.{ScalarOperatorsTestBase, ShouldNotExecuteFunc}
import org.junit.Test
-class ScalarOperatorsTest extends ExpressionTestBase {
+class ScalarOperatorsTest extends ScalarOperatorsTestBase {
@Test
def testCasting(): Unit = {
@@ -216,66 +212,4 @@ class ScalarOperatorsTest extends ExpressionTestBase {
testTableApi(12.isNull, "12.isNull", "false")
}
- @Test(expected = classOf[ValidationException])
- def testIfInvalidTypesScala(): Unit = {
- testTableApi(('f6 && true).?(5, "false"), "FAIL", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testIfInvalidTypesJava(): Unit = {
- testTableApi("FAIL", "(f8 && true).?(5, 'false')", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidStringComparison1(): Unit = {
- testTableApi("w" === 4, "FAIL", "FAIL")
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidStringComparison2(): Unit = {
- testTableApi("w" > 4.toExpr, "FAIL", "FAIL")
- }
-
- // ----------------------------------------------------------------------------------------------
-
- def testData = {
- val testData = new Row(13)
- testData.setField(0, 1: Byte)
- testData.setField(1, 1: Short)
- testData.setField(2, 1)
- testData.setField(3, 1L)
- testData.setField(4, 1.0f)
- testData.setField(5, 1.0d)
- testData.setField(6, true)
- testData.setField(7, 0.0d)
- testData.setField(8, 5)
- testData.setField(9, 10)
- testData.setField(10, "String")
- testData.setField(11, false)
- testData.setField(12, null)
- testData
- }
-
- def typeInfo = {
- new RowTypeInfo(
- Types.BYTE,
- Types.SHORT,
- Types.INT,
- Types.LONG,
- Types.FLOAT,
- Types.DOUBLE,
- Types.BOOLEAN,
- Types.DOUBLE,
- Types.INT,
- Types.INT,
- Types.STRING,
- Types.BOOLEAN,
- Types.BOOLEAN
- ).asInstanceOf[TypeInformation[Any]]
- }
-
- override def functions: Map[String, ScalarFunction] = Map(
- "shouldNotExecuteFunc" -> ShouldNotExecuteFunc
- )
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala
new file mode 100644
index 0000000..c132335
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.expressions.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ )
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "*" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testNestedTablesReduction(): Unit = {
+ val util = batchTestUtil()
+
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
+
+ util.tableEnv.registerTable("NewTable", newTable)
+
+ val sqlQuery = "SELECT a FROM NewTable"
+
+ // 1+1 should be normalized to 2
+ val expected = unaryNode("DataSetCalc", batchTableNode(0), term("select", "+(2, a) AS a"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala
new file mode 100644
index 0000000..595063a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.expressions.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala
new file mode 100644
index 0000000..0a22d8c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.expressions.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ )
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "*" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testNestedTablesReduction(): Unit = {
+ val util = streamTestUtil()
+
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
+
+ util.tableEnv.registerTable("NewTable", newTable)
+
+ val sqlQuery = "SELECT a FROM NewTable"
+
+ // 1+1 should be normalized to 2
+ val expected = unaryNode("DataStreamCalc", streamTableNode(0), term("select", "+(2, a) AS a"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala
new file mode 100644
index 0000000..a62bcd3
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.expressions.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testNestedTablesReduction(): Unit = {
+ val util = streamTestUtil()
+
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
+
+ util.tableEnv.registerTable("NewTable", newTable)
+
+ val sqlQuery = "SELECT a FROM NewTable"
+
+ // 1+1 should be normalized to 2
+ val expected = unaryNode("DataStreamCalc", streamTableNode(0), term("select", "+(2, a) AS a"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ArrayTypeTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ArrayTypeTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ArrayTypeTestBase.scala
new file mode 100644
index 0000000..1ca3d7c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ArrayTypeTestBase.scala
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import java.sql.Date
+
+import org.apache.flink.api.common.typeinfo.{BasicArrayTypeInfo, PrimitiveArrayTypeInfo, TypeInformation}
+import org.apache.flink.api.java.typeutils.{ObjectArrayTypeInfo, RowTypeInfo}
+import org.apache.flink.table.api.Types
+import org.apache.flink.types.Row
+
+class ArrayTypeTestBase extends ExpressionTestBase {
+
+ case class MyCaseClass(string: String, int: Int)
+
+ override def testData: Any = {
+ val testData = new Row(12)
+ testData.setField(0, null)
+ testData.setField(1, 42)
+ testData.setField(2, Array(1, 2, 3))
+ testData.setField(3, Array(Date.valueOf("1984-03-12"), Date.valueOf("1984-02-10")))
+ testData.setField(4, null)
+ testData.setField(5, Array(Array(1, 2, 3), null))
+ testData.setField(6, Array[Integer](1, null, null, 4))
+ testData.setField(7, Array(1, 2, 3, 4))
+ testData.setField(8, Array(4.0))
+ testData.setField(9, Array[Integer](1))
+ testData.setField(10, Array[Integer]())
+ testData.setField(11, Array[Integer](1))
+ testData
+ }
+
+ override def typeInfo: TypeInformation[Any] = {
+ new RowTypeInfo(
+ Types.INT,
+ Types.INT,
+ PrimitiveArrayTypeInfo.INT_PRIMITIVE_ARRAY_TYPE_INFO,
+ ObjectArrayTypeInfo.getInfoFor(Types.SQL_DATE),
+ ObjectArrayTypeInfo.getInfoFor(ObjectArrayTypeInfo.getInfoFor(Types.INT)),
+ ObjectArrayTypeInfo.getInfoFor(PrimitiveArrayTypeInfo.INT_PRIMITIVE_ARRAY_TYPE_INFO),
+ ObjectArrayTypeInfo.getInfoFor(Types.INT),
+ PrimitiveArrayTypeInfo.INT_PRIMITIVE_ARRAY_TYPE_INFO,
+ PrimitiveArrayTypeInfo.DOUBLE_PRIMITIVE_ARRAY_TYPE_INFO,
+ ObjectArrayTypeInfo.getInfoFor(Types.INT),
+ ObjectArrayTypeInfo.getInfoFor(Types.INT),
+ BasicArrayTypeInfo.INT_ARRAY_TYPE_INFO
+ ).asInstanceOf[TypeInformation[Any]]
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala
new file mode 100644
index 0000000..7243f1d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.{RowTypeInfo, TupleTypeInfo, TypeExtractor}
+import org.apache.flink.api.scala.createTypeInformation
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.expressions.utils.CompositeAccessTestBase.{MyCaseClass, MyCaseClass2, MyPojo}
+import org.apache.flink.types.Row
+
+class CompositeAccessTestBase extends ExpressionTestBase {
+
+ def testData = {
+ val testData = new Row(8)
+ testData.setField(0, MyCaseClass(42, "Bob", booleanField = true))
+ testData.setField(1, MyCaseClass2(MyCaseClass(25, "Timo", booleanField = false)))
+ testData.setField(2, ("a", "b"))
+ testData.setField(3, new org.apache.flink.api.java.tuple.Tuple2[String, String]("a", "b"))
+ testData.setField(4, new MyPojo())
+ testData.setField(5, 13)
+ testData.setField(6, MyCaseClass2(null))
+ testData.setField(7, Tuple1(true))
+ testData
+ }
+
+ def typeInfo = {
+ new RowTypeInfo(
+ createTypeInformation[MyCaseClass],
+ createTypeInformation[MyCaseClass2],
+ createTypeInformation[(String, String)],
+ new TupleTypeInfo(Types.STRING, Types.STRING),
+ TypeExtractor.createTypeInfo(classOf[MyPojo]),
+ Types.INT,
+ createTypeInformation[MyCaseClass2],
+ createTypeInformation[Tuple1[Boolean]]
+ ).asInstanceOf[TypeInformation[Any]]
+ }
+
+}
+
+object CompositeAccessTestBase {
+ case class MyCaseClass(intField: Int, stringField: String, booleanField: Boolean)
+
+ case class MyCaseClass2(objectField: MyCaseClass)
+
+ class MyPojo {
+ private var myInt: Int = 0
+ private var myString: String = "Hello"
+
+ def getMyInt = myInt
+
+ def setMyInt(value: Int) = {
+ myInt = value
+ }
+
+ def getMyString = myString
+
+ def setMyString(value: String) = {
+ myString = myString
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala
new file mode 100644
index 0000000..eacf052
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import java.util.{HashMap => JHashMap}
+
+import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
+import org.apache.flink.api.java.typeutils.{MapTypeInfo, RowTypeInfo}
+import org.apache.flink.types.Row
+
+class MapTypeTestBase extends ExpressionTestBase {
+
+ override def testData: Any = {
+ val testData = new Row(4)
+ testData.setField(0, null)
+ testData.setField(1, new JHashMap[String, Int]())
+ val map = new JHashMap[String, Int]()
+ map.put("a", 12)
+ map.put("b", 13)
+ testData.setField(2, map)
+ val map2 = new JHashMap[Int, String]()
+ map2.put(12, "a")
+ map2.put(13, "b")
+ testData.setField(3, map2)
+ testData
+ }
+
+ override def typeInfo: TypeInformation[Any] = {
+ new RowTypeInfo(
+ new MapTypeInfo(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO),
+ new MapTypeInfo(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO),
+ new MapTypeInfo(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO),
+ new MapTypeInfo(BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO)
+ ).asInstanceOf[TypeInformation[Any]]
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala
new file mode 100644
index 0000000..c526a01
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import java.sql.{Date, Time, Timestamp}
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.table.api.Types
+import org.apache.flink.types.Row
+
+class ScalarFunctionsTestBase extends ExpressionTestBase {
+
+ def testData = {
+ val testData = new Row(33)
+ testData.setField(0, "This is a test String.")
+ testData.setField(1, true)
+ testData.setField(2, 42.toByte)
+ testData.setField(3, 43.toShort)
+ testData.setField(4, 44.toLong)
+ testData.setField(5, 4.5.toFloat)
+ testData.setField(6, 4.6)
+ testData.setField(7, 3)
+ testData.setField(8, " This is a test String. ")
+ testData.setField(9, -42.toByte)
+ testData.setField(10, -43.toShort)
+ testData.setField(11, -44.toLong)
+ testData.setField(12, -4.5.toFloat)
+ testData.setField(13, -4.6)
+ testData.setField(14, -3)
+ testData.setField(15, BigDecimal("-1231.1231231321321321111").bigDecimal)
+ testData.setField(16, Date.valueOf("1996-11-10"))
+ testData.setField(17, Time.valueOf("06:55:44"))
+ testData.setField(18, Timestamp.valueOf("1996-11-10 06:55:44.333"))
+ testData.setField(19, 1467012213000L) // +16979 07:23:33.000
+ testData.setField(20, 25) // +2-01
+ testData.setField(21, null)
+ testData.setField(22, BigDecimal("2").bigDecimal)
+ testData.setField(23, "%This is a test String.")
+ testData.setField(24, "*_This is a test String.")
+ testData.setField(25, 0.42.toByte)
+ testData.setField(26, 0.toShort)
+ testData.setField(27, 0.toLong)
+ testData.setField(28, 0.45.toFloat)
+ testData.setField(29, 0.46)
+ testData.setField(30, 1)
+ testData.setField(31, BigDecimal("-0.1231231321321321111").bigDecimal)
+ testData.setField(32, -1)
+ testData
+ }
+
+ def typeInfo = {
+ new RowTypeInfo(
+ Types.STRING,
+ Types.BOOLEAN,
+ Types.BYTE,
+ Types.SHORT,
+ Types.LONG,
+ Types.FLOAT,
+ Types.DOUBLE,
+ Types.INT,
+ Types.STRING,
+ Types.BYTE,
+ Types.SHORT,
+ Types.LONG,
+ Types.FLOAT,
+ Types.DOUBLE,
+ Types.INT,
+ Types.DECIMAL,
+ Types.SQL_DATE,
+ Types.SQL_TIME,
+ Types.SQL_TIMESTAMP,
+ Types.INTERVAL_MILLIS,
+ Types.INTERVAL_MONTHS,
+ Types.BOOLEAN,
+ Types.DECIMAL,
+ Types.STRING,
+ Types.STRING,
+ Types.BYTE,
+ Types.SHORT,
+ Types.LONG,
+ Types.FLOAT,
+ Types.DOUBLE,
+ Types.INT,
+ Types.DECIMAL,
+ Types.INT).asInstanceOf[TypeInformation[Any]]
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala
new file mode 100644
index 0000000..0a77d29
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.types.Row
+
+class ScalarOperatorsTestBase extends ExpressionTestBase {
+
+ def testData = {
+ val testData = new Row(13)
+ testData.setField(0, 1: Byte)
+ testData.setField(1, 1: Short)
+ testData.setField(2, 1)
+ testData.setField(3, 1L)
+ testData.setField(4, 1.0f)
+ testData.setField(5, 1.0d)
+ testData.setField(6, true)
+ testData.setField(7, 0.0d)
+ testData.setField(8, 5)
+ testData.setField(9, 10)
+ testData.setField(10, "String")
+ testData.setField(11, false)
+ testData.setField(12, null)
+ testData
+ }
+
+ def typeInfo = {
+ new RowTypeInfo(
+ Types.BYTE,
+ Types.SHORT,
+ Types.INT,
+ Types.LONG,
+ Types.FLOAT,
+ Types.DOUBLE,
+ Types.BOOLEAN,
+ Types.DOUBLE,
+ Types.INT,
+ Types.INT,
+ Types.STRING,
+ Types.BOOLEAN,
+ Types.BOOLEAN
+ ).asInstanceOf[TypeInformation[Any]]
+ }
+
+ override def functions: Map[String, ScalarFunction] = Map(
+ "shouldNotExecuteFunc" -> ShouldNotExecuteFunc
+ )
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ArrayTypeValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ArrayTypeValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ArrayTypeValidationTest.scala
new file mode 100644
index 0000000..3606d13
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ArrayTypeValidationTest.scala
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.validation
+
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils.ArrayTypeTestBase
+import org.junit.Test
+
+class ArrayTypeValidationTest extends ArrayTypeTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testObviousInvalidIndexTableApi(): Unit = {
+ testTableApi('f2.at(0), "FAIL", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testEmptyArraySql(): Unit = {
+ testSqlApi("ARRAY[]", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testEmptyArrayTableApi(): Unit = {
+ testTableApi("FAIL", "array()", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testNullArraySql(): Unit = {
+ testSqlApi("ARRAY[NULL]", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testDifferentTypesArraySql(): Unit = {
+ testSqlApi("ARRAY[1, TRUE]", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testDifferentTypesArrayTableApi(): Unit = {
+ testTableApi("FAIL", "array(1, true)", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnsupportedComparison(): Unit = {
+ testAllApis(
+ 'f2 <= 'f5.at(1),
+ "f2 <= f5.at(1)",
+ "f2 <= f5[1]",
+ "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testElementNonArray(): Unit = {
+ testTableApi(
+ 'f0.element(),
+ "FAIL",
+ "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testElementNonArraySql(): Unit = {
+ testSqlApi(
+ "ELEMENT(f0)",
+ "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testCardinalityOnNonArray(): Unit = {
+ testTableApi('f0.cardinality(), "FAIL", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testCardinalityOnNonArraySql(): Unit = {
+ testSqlApi("CARDINALITY(f0)", "FAIL")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala
new file mode 100644
index 0000000..5542533
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.validation
+
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils.CompositeAccessTestBase
+import org.junit.Test
+
+class CompositeAccessValidationTest extends CompositeAccessTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testWrongSqlFieldFull(): Unit = {
+ testSqlApi("testTable.f5.test", "13")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testWrongSqlField(): Unit = {
+ testSqlApi("f5.test", "13")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testWrongIntKeyField(): Unit = {
+ testTableApi('f0.get(555), "'fail'", "fail")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testWrongIntKeyField2(): Unit = {
+ testTableApi("fail", "f0.get(555)", "fail")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testWrongStringKeyField(): Unit = {
+ testTableApi('f0.get("fghj"), "'fail'", "fail")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testWrongStringKeyField2(): Unit = {
+ testTableApi("fail", "f0.get('fghj')", "fail")
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/MapTypeValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/MapTypeValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/MapTypeValidationTest.scala
new file mode 100644
index 0000000..3f8306d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/MapTypeValidationTest.scala
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.validation
+
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.expressions.utils.MapTypeTestBase
+import org.junit.Test
+
+class MapTypeValidationTest extends MapTypeTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testWrongKeyType(): Unit = {
+ testSqlApi("f4[12]", "FAIL")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala
new file mode 100644
index 0000000..819dbbce
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.validation
+
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils.ScalarFunctionsTestBase
+import org.junit.Test
+
+class ScalarFunctionsValidationTest extends ScalarFunctionsTestBase {
+
+ // ----------------------------------------------------------------------------------------------
+ // String functions
+ // ----------------------------------------------------------------------------------------------
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSubstring1(): Unit = {
+ // Must fail. Parameter of substring must be an Integer not a Double.
+ testTableApi("test".substring(2.0.toExpr), "FAIL", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSubstring2(): Unit = {
+ // Must fail. Parameter of substring must be an Integer not a String.
+ testTableApi("test".substring("test".toExpr), "FAIL", "FAIL")
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala
new file mode 100644
index 0000000..68c0b3f
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.validation
+
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils.ScalarOperatorsTestBase
+import org.junit.Test
+
+class ScalarOperatorsValidationTest extends ScalarOperatorsTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testIfInvalidTypesScala(): Unit = {
+ testTableApi(('f6 && true).?(5, "false"), "FAIL", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testIfInvalidTypesJava(): Unit = {
+ testTableApi("FAIL", "(f8 && true).?(5, 'false')", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidStringComparison1(): Unit = {
+ testTableApi("w" === 4, "FAIL", "FAIL")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidStringComparison2(): Unit = {
+ testTableApi("w" > 4.toExpr, "FAIL", "FAIL")
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala
index 5bd7e77..c307de5 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/NormalizationRulesTest.scala
@@ -38,7 +38,7 @@ class NormalizationRulesTest extends TableTestBase {
.replaceLogicalOptRuleSet(RuleSets.ofList())
.replacePhysicalOptRuleSet(RuleSets.ofList())
.build()
- util.tEnv.getConfig.setCalciteConfig(cc)
+ util.tableEnv.getConfig.setCalciteConfig(cc)
util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
@@ -72,7 +72,7 @@ class NormalizationRulesTest extends TableTestBase {
.replaceLogicalOptRuleSet(RuleSets.ofList())
.replacePhysicalOptRuleSet(RuleSets.ofList())
.build()
- util.tEnv.getConfig.setCalciteConfig(cc)
+ util.tableEnv.getConfig.setCalciteConfig(cc)
util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala
index 861f70e..75d2f22 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/rules/RetractionRulesTest.scala
@@ -287,12 +287,12 @@ class RetractionRulesTest extends TableTestBase {
class StreamTableTestForRetractionUtil extends StreamTableTestUtil {
def verifySqlTrait(query: String, expected: String): Unit = {
- verifyTableTrait(tEnv.sql(query), expected)
+ verifyTableTrait(tableEnv.sql(query), expected)
}
def verifyTableTrait(resultTable: Table, expected: String): Unit = {
val relNode = resultTable.getRelNode
- val optimized = tEnv.optimize(relNode, updatesAsRetraction = false)
+ val optimized = tableEnv.optimize(relNode, updatesAsRetraction = false)
val actual = TraitUtil.toString(optimized)
assertEquals(
expected.split("\n").map(_.trim).mkString("\n"),
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetCalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetCalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetCalcITCase.scala
deleted file mode 100644
index dc6ab1c..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetCalcITCase.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.expressions.utils.{RichFunc1, RichFunc2, RichFunc3}
-import org.apache.flink.table.utils._
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class DataSetCalcITCase(
- mode: TestExecutionMode,
- configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- @Test
- def testUserDefinedScalarFunctionWithParameter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
-
- val ds = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT c FROM t1 where RichFunc2(c)='ABC#Hello'"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedScalarFunctionWithDistributedCache(): Unit = {
- val words = "Hello\nWord"
- val filePath = UserDefinedFunctionTestUtils.writeCacheFile("test_words", words)
- val env = ExecutionEnvironment.getExecutionEnvironment
- env.registerCachedFile(filePath, "words")
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc3", new RichFunc3)
-
- val ds = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT c FROM t1 where RichFunc3(c)=true"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMultipleUserDefinedScalarFunctions(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc1", new RichFunc1)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
-
- val ds = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT c FROM t1 where " +
- "RichFunc2(c)='Abc#Hello' or RichFunc1(a)=3 and b=2"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello\nHello world"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetUserDefinedFunctionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetUserDefinedFunctionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetUserDefinedFunctionITCase.scala
deleted file mode 100644
index b69dd49..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetUserDefinedFunctionITCase.scala
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.runtime.dataset
-
-import java.sql.{Date, Timestamp}
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.java.utils.UserDefinedTableFunctions.JavaTableFunc0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.expressions.utils.{Func1, Func13, Func18, RichFunc2}
-import org.apache.flink.table.utils._
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-@RunWith(classOf[Parameterized])
-class DataSetUserDefinedFunctionITCase(
- mode: TestExecutionMode,
- configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- @Test
- def testCrossJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val func1 = new TableFunc1
- val result = in.join(func1('c) as 's).select('c, 's).toDataSet[Row]
- val results = result.collect()
- val expected = "Jack#22,Jack\n" + "Jack#22,22\n" + "John#19,John\n" + "John#19,19\n" +
- "Anna#44,Anna\n" + "Anna#44,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
-
- // with overloading
- val result2 = in.join(func1('c, "$") as 's).select('c, 's).toDataSet[Row]
- val results2 = result2.collect()
- val expected2 = "Jack#22,$Jack\n" + "Jack#22,$22\n" + "John#19,$John\n" +
- "John#19,$19\n" + "Anna#44,$Anna\n" + "Anna#44,$44\n"
- TestBaseUtils.compareResultAsText(results2.asJava, expected2)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val func2 = new TableFunc2
- val result = in.leftOuterJoin(func2('c) as ('s, 'l)).select('c, 's, 'l).toDataSet[Row]
- val results = result.collect()
- val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
- "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n" + "nosharp,null,null"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testWithFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = in
- .join(func0('c) as ('name, 'age))
- .select('c, 'name, 'age)
- .filter('age > 20)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCustomReturnType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func2 = new TableFunc2
-
- val result = in
- .join(func2('c) as ('name, 'len))
- .select('c, 'name, 'len)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
- "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testHierarchyType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val hierarchy = new HierarchyTableFunction
- val result = in
- .join(hierarchy('c) as ('name, 'adult, 'len))
- .select('c, 'name, 'adult, 'len)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,true,22\n" + "John#19,John,false,19\n" +
- "Anna#44,Anna,true,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testPojoType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val pojo = new PojoTableFunc()
- val result = in
- .join(pojo('c))
- .where('age > 20)
- .select('c, 'name, 'age)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func1 = new TableFunc1
-
- val result = in
- .join(func1('c.substring(2)) as 's)
- .select('c, 's)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,ack\n" + "Jack#22,22\n" + "John#19,ohn\n" + "John#19,19\n" +
- "Anna#44,nna\n" + "Anna#44,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunctionInCondition(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = in
- .join(func0('c))
- .where(Func18('name, "J") && (Func1('a) < 3) && Func1('age) > 20)
- .select('c, 'name, 'age)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,22"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLongAndTemporalTypes(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func0 = new JavaTableFunc0
-
- val result = in
- .where('a === 1)
- .select(Date.valueOf("1990-10-14") as 'x,
- 1000L as 'y,
- Timestamp.valueOf("1990-10-14 12:10:10") as 'z)
- .join(func0('x, 'y, 'z) as 's)
- .select('s)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "1000\n" + "655906210000\n" + "7591\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithParameter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val richTableFunc1 = new RichTableFunc1
- tEnv.registerFunction("RichTableFunc1", richTableFunc1)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> "#"))
-
- val result = testData(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(richTableFunc1('c) as 's)
- .select('a, 's)
-
- val expected = "1,Jack\n" + "1,22\n" + "2,John\n" + "2,19\n" + "3,Anna\n" + "3,44"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunctionWithParameters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val richTableFunc1 = new RichTableFunc1
- tEnv.registerFunction("RichTableFunc1", richTableFunc1)
- val richFunc2 = new RichFunc2
- tEnv.registerFunction("RichFunc2", richFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(
- env,
- Map("word_separator" -> "#", "string.value" -> "test"))
-
- val result = CollectionDataSets.getSmall3TupleDataSet(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(richTableFunc1(richFunc2('c)) as 's)
- .select('a, 's)
-
- val expected = "1,Hi\n1,test\n2,Hello\n2,test\n3,Hello world\n3,test"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableFunctionConstructorWithParams(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func30 = new TableFunc3(null)
- val func31 = new TableFunc3("OneConf_")
- val func32 = new TableFunc3("TwoConf_")
-
- val result = in
- .join(func30('c) as('d, 'e))
- .select('c, 'd, 'e)
- .join(func31('c) as ('f, 'g))
- .select('c, 'd, 'e, 'f, 'g)
- .join(func32('c) as ('h, 'i))
- .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
- .toDataSet[Row]
-
- val results = result.collect()
-
- val expected = "Anna#44,Anna,OneConf_Anna,TwoConf_Anna,44,44,44\n" +
- "Jack#22,Jack,OneConf_Jack,TwoConf_Jack,22,22,22\n" +
- "John#19,John,OneConf_John,TwoConf_John,19,19,19\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testScalarFunctionConstructorWithParams(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val func0 = new Func13("default")
- val func1 = new Func13("Sunny")
- val func2 = new Func13("kevin2")
-
- val result = in.select(func0('c), func1('c),func2('c))
-
- val results = result.collect()
-
- val expected = "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44\n" +
- "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22\n" +
- "default-John#19,Sunny-John#19,kevin2-John#19\n" +
- "default-nosharp,Sunny-nosharp,kevin2-nosharp"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableFunctionWithVariableArguments(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val varArgsFunc0 = new VarArgsFunc0
- tableEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
-
- val result = testData(env)
- .toTable(tableEnv, 'a, 'b, 'c)
- .select('c)
- .join(varArgsFunc0("1", "2", 'c))
-
- val expected = "Anna#44,1\n" +
- "Anna#44,2\n" +
- "Anna#44,Anna#44\n" +
- "Jack#22,1\n" +
- "Jack#22,2\n" +
- "Jack#22,Jack#22\n" +
- "John#19,1\n" +
- "John#19,2\n" +
- "John#19,John#19\n" +
- "nosharp,1\n" +
- "nosharp,2\n" +
- "nosharp,nosharp"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
-
- // Test for empty cases
- val result0 = testData(env)
- .toTable(tableEnv, 'a, 'b, 'c)
- .select('c)
- .join(varArgsFunc0())
- val results0 = result0.toDataSet[Row].collect()
- assertTrue(results0.isEmpty)
- }
-
- private def testData(
- env: ExecutionEnvironment)
- : DataSet[(Int, Long, String)] = {
-
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Jack#22"))
- data.+=((2, 2L, "John#19"))
- data.+=((3, 2L, "Anna#44"))
- data.+=((4, 3L, "nosharp"))
- env.fromCollection(data)
- }
-}
[30/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/CountAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/CountAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/CountAggFunctionTest.scala
deleted file mode 100644
index 6830b8f..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/CountAggFunctionTest.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.functions.aggfunctions
-
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in count aggregate function
- */
-class CountAggFunctionTest extends AggFunctionTestBase[Long, CountAccumulator] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq("a", "b", null, "c", null, "d", "e", null, "f"),
- Seq(null, null, null, null, null, null)
- )
-
- override def expectedResults: Seq[Long] = Seq(6L, 0L)
-
- override def aggregator: AggregateFunction[Long, CountAccumulator] = new CountAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxAggFunctionTest.scala
deleted file mode 100644
index 54c2a7d..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxAggFunctionTest.scala
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in max aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class MaxAggFunctionTest[T: Numeric] extends AggFunctionTestBase[T, MaxAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def minVal: T
-
- def maxVal: T
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- numeric.fromInt(1),
- null.asInstanceOf[T],
- maxVal,
- numeric.fromInt(-99),
- numeric.fromInt(3),
- numeric.fromInt(56),
- numeric.fromInt(0),
- minVal,
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T]
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- maxVal,
- null.asInstanceOf[T]
- )
-}
-
-class ByteMaxAggFunctionTest extends MaxAggFunctionTest[Byte] {
-
- override def minVal = (Byte.MinValue + 1).toByte
-
- override def maxVal = (Byte.MaxValue - 1).toByte
-
- override def aggregator: AggregateFunction[Byte, MaxAccumulator[Byte]] =
- new ByteMaxAggFunction()
-}
-
-class ShortMaxAggFunctionTest extends MaxAggFunctionTest[Short] {
-
- override def minVal = (Short.MinValue + 1).toShort
-
- override def maxVal = (Short.MaxValue - 1).toShort
-
- override def aggregator: AggregateFunction[Short, MaxAccumulator[Short]] =
- new ShortMaxAggFunction()
-}
-
-class IntMaxAggFunctionTest extends MaxAggFunctionTest[Int] {
-
- override def minVal = Int.MinValue + 1
-
- override def maxVal = Int.MaxValue - 1
-
- override def aggregator: AggregateFunction[Int, MaxAccumulator[Int]] =
- new IntMaxAggFunction()
-}
-
-class LongMaxAggFunctionTest extends MaxAggFunctionTest[Long] {
-
- override def minVal = Long.MinValue + 1
-
- override def maxVal = Long.MaxValue - 1
-
- override def aggregator: AggregateFunction[Long, MaxAccumulator[Long]] =
- new LongMaxAggFunction()
-}
-
-class FloatMaxAggFunctionTest extends MaxAggFunctionTest[Float] {
-
- override def minVal = Float.MinValue / 2
-
- override def maxVal = Float.MaxValue / 2
-
- override def aggregator: AggregateFunction[Float, MaxAccumulator[Float]] =
- new FloatMaxAggFunction()
-}
-
-class DoubleMaxAggFunctionTest extends MaxAggFunctionTest[Double] {
-
- override def minVal = Double.MinValue / 2
-
- override def maxVal = Double.MaxValue / 2
-
- override def aggregator: AggregateFunction[Double, MaxAccumulator[Double]] =
- new DoubleMaxAggFunction()
-}
-
-class BooleanMaxAggFunctionTest extends AggFunctionTestBase[Boolean, MaxAccumulator[Boolean]] {
-
- override def inputValueSets: Seq[Seq[Boolean]] = Seq(
- Seq(
- false,
- false,
- false
- ),
- Seq(
- true,
- true,
- true
- ),
- Seq(
- true,
- false,
- null.asInstanceOf[Boolean],
- true,
- false,
- true,
- null.asInstanceOf[Boolean]
- ),
- Seq(
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean]
- )
- )
-
- override def expectedResults: Seq[Boolean] = Seq(
- false,
- true,
- true,
- null.asInstanceOf[Boolean]
- )
-
- override def aggregator: AggregateFunction[Boolean, MaxAccumulator[Boolean]] =
- new BooleanMaxAggFunction()
-}
-
-class DecimalMaxAggFunctionTest
- extends AggFunctionTestBase[BigDecimal, MaxAccumulator[BigDecimal]] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("1000.000001"),
- new BigDecimal("-1"),
- new BigDecimal("-999.998999"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-999.999"),
- null,
- new BigDecimal("999.999")
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("1000.000001"),
- null
- )
-
- override def aggregator: AggregateFunction[BigDecimal, MaxAccumulator[BigDecimal]] =
- new DecimalMaxAggFunction()
-}
-
-class StringMaxAggFunctionTest extends AggFunctionTestBase[String, MaxAccumulator[String]] {
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new String("a"),
- new String("b"),
- new String("c"),
- null.asInstanceOf[String],
- new String("d")
- ),
- Seq(
- null.asInstanceOf[String],
- null.asInstanceOf[String],
- null.asInstanceOf[String]
- ),
- Seq(
- new String("1House"),
- new String("Household"),
- new String("house"),
- new String("household")
- )
- )
-
- override def expectedResults: Seq[String] = Seq(
- new String("d"),
- null.asInstanceOf[String],
- new String("household")
- )
-
- override def aggregator: AggregateFunction[String, MaxAccumulator[String]] =
- new StringMaxAggFunction()
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxWithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxWithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxWithRetractAggFunctionTest.scala
deleted file mode 100644
index c11ae41..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MaxWithRetractAggFunctionTest.scala
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in max with retraction aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class MaxWithRetractAggFunctionTest[T: Numeric]
- extends AggFunctionTestBase[T, MaxWithRetractAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def minVal: T
-
- def maxVal: T
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- numeric.fromInt(1),
- null.asInstanceOf[T],
- maxVal,
- numeric.fromInt(-99),
- numeric.fromInt(3),
- numeric.fromInt(56),
- numeric.fromInt(0),
- minVal,
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T]
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- maxVal,
- null.asInstanceOf[T]
- )
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class ByteMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Byte] {
-
- override def minVal = (Byte.MinValue + 1).toByte
-
- override def maxVal = (Byte.MaxValue - 1).toByte
-
- override def aggregator: AggregateFunction[Byte, MaxWithRetractAccumulator[Byte]] =
- new ByteMaxWithRetractAggFunction()
-}
-
-class ShortMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Short] {
-
- override def minVal = (Short.MinValue + 1).toShort
-
- override def maxVal = (Short.MaxValue - 1).toShort
-
- override def aggregator: AggregateFunction[Short, MaxWithRetractAccumulator[Short]] =
- new ShortMaxWithRetractAggFunction()
-}
-
-class IntMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Int] {
-
- override def minVal = Int.MinValue + 1
-
- override def maxVal = Int.MaxValue - 1
-
- override def aggregator: AggregateFunction[Int, MaxWithRetractAccumulator[Int]] =
- new IntMaxWithRetractAggFunction()
-}
-
-class LongMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Long] {
-
- override def minVal = Long.MinValue + 1
-
- override def maxVal = Long.MaxValue - 1
-
- override def aggregator: AggregateFunction[Long, MaxWithRetractAccumulator[Long]] =
- new LongMaxWithRetractAggFunction()
-}
-
-class FloatMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Float] {
-
- override def minVal = Float.MinValue / 2
-
- override def maxVal = Float.MaxValue / 2
-
- override def aggregator: AggregateFunction[Float, MaxWithRetractAccumulator[Float]] =
- new FloatMaxWithRetractAggFunction()
-}
-
-class DoubleMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTest[Double] {
-
- override def minVal = Double.MinValue / 2
-
- override def maxVal = Double.MaxValue / 2
-
- override def aggregator: AggregateFunction[Double, MaxWithRetractAccumulator[Double]] =
- new DoubleMaxWithRetractAggFunction()
-}
-
-class BooleanMaxWithRetractAggFunctionTest
- extends AggFunctionTestBase[Boolean, MaxWithRetractAccumulator[Boolean]] {
-
- override def inputValueSets: Seq[Seq[Boolean]] = Seq(
- Seq(
- false,
- false,
- false
- ),
- Seq(
- true,
- true,
- true
- ),
- Seq(
- true,
- false,
- null.asInstanceOf[Boolean],
- true,
- false,
- true,
- null.asInstanceOf[Boolean]
- ),
- Seq(
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean]
- )
- )
-
- override def expectedResults: Seq[Boolean] = Seq(
- false,
- true,
- true,
- null.asInstanceOf[Boolean]
- )
-
- override def aggregator: AggregateFunction[Boolean, MaxWithRetractAccumulator[Boolean]] =
- new BooleanMaxWithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class DecimalMaxWithRetractAggFunctionTest
- extends AggFunctionTestBase[BigDecimal, MaxWithRetractAccumulator[BigDecimal]] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("1000.000001"),
- new BigDecimal("-1"),
- new BigDecimal("-999.998999"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-999.999"),
- null,
- new BigDecimal("999.999")
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("1000.000001"),
- null
- )
-
- override def aggregator: AggregateFunction[BigDecimal, MaxWithRetractAccumulator[BigDecimal]] =
- new DecimalMaxWithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class StringMaxWithRetractAggFunctionTest
- extends AggFunctionTestBase[String, MaxWithRetractAccumulator[String]] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- "abc",
- "def",
- "ghi",
- null,
- "jkl",
- null,
- "zzz"
- ),
- Seq(
- null,
- null
- ),
- Seq(
- "x",
- null,
- "e"
- )
- )
-
- override def expectedResults: Seq[String] = Seq(
- "zzz",
- null,
- "x"
- )
-
- override def aggregator: AggregateFunction[String, MaxWithRetractAccumulator[String]] =
- new StringMaxWithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinAggFunctionTest.scala
deleted file mode 100644
index 6f41bd2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinAggFunctionTest.scala
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in min aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class MinAggFunctionTest[T: Numeric] extends AggFunctionTestBase[T, MinAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def minVal: T
-
- def maxVal: T
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- numeric.fromInt(1),
- null.asInstanceOf[T],
- maxVal,
- numeric.fromInt(-99),
- numeric.fromInt(3),
- numeric.fromInt(56),
- numeric.fromInt(0),
- minVal,
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T]
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- minVal,
- null.asInstanceOf[T]
- )
-}
-
-class ByteMinAggFunctionTest extends MinAggFunctionTest[Byte] {
-
- override def minVal = (Byte.MinValue + 1).toByte
-
- override def maxVal = (Byte.MaxValue - 1).toByte
-
- override def aggregator: AggregateFunction[Byte, MinAccumulator[Byte]] =
- new ByteMinAggFunction()
-}
-
-class ShortMinAggFunctionTest extends MinAggFunctionTest[Short] {
-
- override def minVal = (Short.MinValue + 1).toShort
-
- override def maxVal = (Short.MaxValue - 1).toShort
-
- override def aggregator: AggregateFunction[Short, MinAccumulator[Short]] =
- new ShortMinAggFunction()
-}
-
-class IntMinAggFunctionTest extends MinAggFunctionTest[Int] {
-
- override def minVal = Int.MinValue + 1
-
- override def maxVal = Int.MaxValue - 1
-
- override def aggregator: AggregateFunction[Int, MinAccumulator[Int]] =
- new IntMinAggFunction()
-}
-
-class LongMinAggFunctionTest extends MinAggFunctionTest[Long] {
-
- override def minVal = Long.MinValue + 1
-
- override def maxVal = Long.MaxValue - 1
-
- override def aggregator: AggregateFunction[Long, MinAccumulator[Long]] =
- new LongMinAggFunction()
-}
-
-class FloatMinAggFunctionTest extends MinAggFunctionTest[Float] {
-
- override def minVal = Float.MinValue / 2
-
- override def maxVal = Float.MaxValue / 2
-
- override def aggregator: AggregateFunction[Float, MinAccumulator[Float]] =
- new FloatMinAggFunction()
-}
-
-class DoubleMinAggFunctionTest extends MinAggFunctionTest[Double] {
-
- override def minVal = Double.MinValue / 2
-
- override def maxVal = Double.MaxValue / 2
-
- override def aggregator: AggregateFunction[Double, MinAccumulator[Double]] =
- new DoubleMinAggFunction()
-}
-
-class BooleanMinAggFunctionTest extends AggFunctionTestBase[Boolean, MinAccumulator[Boolean]] {
-
- override def inputValueSets: Seq[Seq[Boolean]] = Seq(
- Seq(
- false,
- false,
- false
- ),
- Seq(
- true,
- true,
- true
- ),
- Seq(
- true,
- false,
- null.asInstanceOf[Boolean],
- true,
- false,
- true,
- null.asInstanceOf[Boolean]
- ),
- Seq(
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean]
- )
- )
-
- override def expectedResults: Seq[Boolean] = Seq(
- false,
- true,
- false,
- null.asInstanceOf[Boolean]
- )
-
- override def aggregator: AggregateFunction[Boolean, MinAccumulator[Boolean]] =
- new BooleanMinAggFunction()
-}
-
-class DecimalMinAggFunctionTest
- extends AggFunctionTestBase[BigDecimal, MinAccumulator[BigDecimal]] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("1000"),
- new BigDecimal("-1"),
- new BigDecimal("-999.998999"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-999.999"),
- null,
- new BigDecimal("999.999")
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("-999.999"),
- null
- )
-
- override def aggregator: AggregateFunction[BigDecimal, MinAccumulator[BigDecimal]] =
- new DecimalMinAggFunction()
-}
-
-class StringMinAggFunctionTest
- extends AggFunctionTestBase[String, MinAccumulator[String]] {
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new String("a"),
- new String("b"),
- new String("c"),
- null.asInstanceOf[String],
- new String("d")
- ),
- Seq(
- null.asInstanceOf[String],
- null.asInstanceOf[String],
- null.asInstanceOf[String]
- ),
- Seq(
- new String("1House"),
- new String("Household"),
- new String("house"),
- new String("household")
- )
- )
-
- override def expectedResults: Seq[String] = Seq(
- new String("a"),
- null.asInstanceOf[String],
- new String("1House")
- )
-
- override def aggregator: AggregateFunction[String, MinAccumulator[String]] =
- new StringMinAggFunction()
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinWithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinWithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinWithRetractAggFunctionTest.scala
deleted file mode 100644
index e13e69b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/MinWithRetractAggFunctionTest.scala
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in Min with retraction aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class MinWithRetractAggFunctionTest[T: Numeric]
- extends AggFunctionTestBase[T, MinWithRetractAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def minVal: T
-
- def maxVal: T
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- numeric.fromInt(1),
- null.asInstanceOf[T],
- maxVal,
- numeric.fromInt(-99),
- numeric.fromInt(3),
- numeric.fromInt(56),
- numeric.fromInt(0),
- minVal,
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T]
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- minVal,
- null.asInstanceOf[T]
- )
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class ByteMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Byte] {
-
- override def minVal = (Byte.MinValue + 1).toByte
-
- override def maxVal = (Byte.MaxValue - 1).toByte
-
- override def aggregator: AggregateFunction[Byte, MinWithRetractAccumulator[Byte]] =
- new ByteMinWithRetractAggFunction()
-}
-
-class ShortMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Short] {
-
- override def minVal = (Short.MinValue + 1).toShort
-
- override def maxVal = (Short.MaxValue - 1).toShort
-
- override def aggregator: AggregateFunction[Short, MinWithRetractAccumulator[Short]] =
- new ShortMinWithRetractAggFunction()
-}
-
-class IntMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Int] {
-
- override def minVal = Int.MinValue + 1
-
- override def maxVal = Int.MaxValue - 1
-
- override def aggregator: AggregateFunction[Int, MinWithRetractAccumulator[Int]] =
- new IntMinWithRetractAggFunction()
-}
-
-class LongMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Long] {
-
- override def minVal = Long.MinValue + 1
-
- override def maxVal = Long.MaxValue - 1
-
- override def aggregator: AggregateFunction[Long, MinWithRetractAccumulator[Long]] =
- new LongMinWithRetractAggFunction()
-}
-
-class FloatMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Float] {
-
- override def minVal = Float.MinValue / 2
-
- override def maxVal = Float.MaxValue / 2
-
- override def aggregator: AggregateFunction[Float, MinWithRetractAccumulator[Float]] =
- new FloatMinWithRetractAggFunction()
-}
-
-class DoubleMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTest[Double] {
-
- override def minVal = Double.MinValue / 2
-
- override def maxVal = Double.MaxValue / 2
-
- override def aggregator: AggregateFunction[Double, MinWithRetractAccumulator[Double]] =
- new DoubleMinWithRetractAggFunction()
-}
-
-class BooleanMinWithRetractAggFunctionTest
- extends AggFunctionTestBase[Boolean, MinWithRetractAccumulator[Boolean]] {
-
- override def inputValueSets: Seq[Seq[Boolean]] = Seq(
- Seq(
- false,
- false,
- false
- ),
- Seq(
- true,
- true,
- true
- ),
- Seq(
- true,
- false,
- null.asInstanceOf[Boolean],
- true,
- false,
- true,
- null.asInstanceOf[Boolean]
- ),
- Seq(
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean],
- null.asInstanceOf[Boolean]
- )
- )
-
- override def expectedResults: Seq[Boolean] = Seq(
- false,
- true,
- false,
- null.asInstanceOf[Boolean]
- )
-
- override def aggregator: AggregateFunction[Boolean, MinWithRetractAccumulator[Boolean]] =
- new BooleanMinWithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class DecimalMinWithRetractAggFunctionTest
- extends AggFunctionTestBase[BigDecimal, MinWithRetractAccumulator[BigDecimal]] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("1000"),
- new BigDecimal("-1"),
- new BigDecimal("-999.998999"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-999.999"),
- null,
- new BigDecimal("999.999")
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("-999.999"),
- null
- )
-
- override def aggregator: AggregateFunction[BigDecimal, MinWithRetractAccumulator[BigDecimal]] =
- new DecimalMinWithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class StringMinWithRetractAggFunctionTest
- extends AggFunctionTestBase[String, MinWithRetractAccumulator[String]] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- "abc",
- "def",
- "ghi",
- null,
- "jkl",
- null,
- "zzz"
- ),
- Seq(
- null,
- null
- ),
- Seq(
- "x",
- null,
- "e"
- )
- )
-
- override def expectedResults: Seq[String] = Seq(
- "abc",
- null,
- "e"
- )
-
- override def aggregator: AggregateFunction[String, MinWithRetractAccumulator[String]] =
- new StringMinWithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0AggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0AggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0AggFunctionTest.scala
deleted file mode 100644
index ba98fa2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0AggFunctionTest.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in sum0 aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class Sum0AggFunctionTestBase[T: Numeric]
- extends AggFunctionTestBase[T, SumAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def maxVal: T
-
- private val minVal = numeric.negate(maxVal)
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- minVal,
- numeric.fromInt(1),
- null.asInstanceOf[T],
- numeric.fromInt(2),
- numeric.fromInt(3),
- numeric.fromInt(4),
- numeric.fromInt(5),
- numeric.fromInt(-10),
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T],
- maxVal
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- numeric.fromInt(2),
- 0.asInstanceOf[T]
- )
-}
-
-class ByteSum0AggFunctionTest extends Sum0AggFunctionTestBase[Byte] {
-
- override def maxVal = (Byte.MaxValue / 2).toByte
-
- override def aggregator: AggregateFunction[Byte, SumAccumulator[Byte]] =
- new ByteSum0AggFunction
-}
-
-class ShortSum0AggFunctionTest extends Sum0AggFunctionTestBase[Short] {
-
- override def maxVal = (Short.MaxValue / 2).toShort
-
- override def aggregator: AggregateFunction[Short, SumAccumulator[Short]] =
- new ShortSum0AggFunction
-}
-
-class IntSum0AggFunctionTest extends Sum0AggFunctionTestBase[Int] {
-
- override def maxVal = Int.MaxValue / 2
-
- override def aggregator: AggregateFunction[Int, SumAccumulator[Int]] =
- new IntSum0AggFunction
-}
-
-class LongSum0AggFunctionTest extends Sum0AggFunctionTestBase[Long] {
-
- override def maxVal = Long.MaxValue / 2
-
- override def aggregator: AggregateFunction[Long, SumAccumulator[Long]] =
- new LongSum0AggFunction
-}
-
-class FloatSum0AggFunctionTest extends Sum0AggFunctionTestBase[Float] {
-
- override def maxVal = 12345.6789f
-
- override def aggregator: AggregateFunction[Float, SumAccumulator[Float]] =
- new FloatSum0AggFunction
-}
-
-class DoubleSum0AggFunctionTest extends Sum0AggFunctionTestBase[Double] {
-
- override def maxVal = 12345.6789d
-
- override def aggregator: AggregateFunction[Double, SumAccumulator[Double]] =
- new DoubleSum0AggFunction
-}
-
-
-class DecimalSum0AggFunctionTest
- extends AggFunctionTestBase[BigDecimal, DecimalSumAccumulator] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("2"),
- new BigDecimal("3"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-1000"),
- new BigDecimal("0.000000000002"),
- new BigDecimal("1000"),
- new BigDecimal("-0.000000000001"),
- new BigDecimal("999.999"),
- null,
- new BigDecimal("4"),
- new BigDecimal("-999.999"),
- null
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("10.000000000001"),
- BigDecimal.ZERO
- )
-
- override def aggregator: AggregateFunction[BigDecimal, DecimalSumAccumulator] =
- new DecimalSum0AggFunction()
-}
-
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0WithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0WithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0WithRetractAggFunctionTest.scala
deleted file mode 100644
index 0a8f633..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/Sum0WithRetractAggFunctionTest.scala
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in sum0 with retract aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class Sum0WithRetractAggFunctionTestBase[T: Numeric]
- extends AggFunctionTestBase[T, SumWithRetractAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def maxVal: T
-
- private val minVal = numeric.negate(maxVal)
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- minVal,
- numeric.fromInt(1),
- null.asInstanceOf[T],
- numeric.fromInt(2),
- numeric.fromInt(3),
- numeric.fromInt(4),
- numeric.fromInt(5),
- numeric.fromInt(-10),
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T],
- maxVal
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- numeric.fromInt(2),
- 0.asInstanceOf[T]
- )
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class ByteSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Byte] {
-
- override def maxVal = (Byte.MaxValue / 2).toByte
-
- override def aggregator: AggregateFunction[Byte, SumWithRetractAccumulator[Byte]] =
- new ByteSum0WithRetractAggFunction
-}
-
-class ShortSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Short] {
-
- override def maxVal = (Short.MaxValue / 2).toShort
-
- override def aggregator: AggregateFunction[Short, SumWithRetractAccumulator[Short]] =
- new ShortSum0WithRetractAggFunction
-}
-
-class IntSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Int] {
-
- override def maxVal = Int.MaxValue / 2
-
- override def aggregator: AggregateFunction[Int, SumWithRetractAccumulator[Int]] =
- new IntSum0WithRetractAggFunction
-}
-
-class LongSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Long] {
-
- override def maxVal = Long.MaxValue / 2
-
- override def aggregator: AggregateFunction[Long, SumWithRetractAccumulator[Long]] =
- new LongSum0WithRetractAggFunction
-}
-
-class FloatSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Float] {
-
- override def maxVal = 12345.6789f
-
- override def aggregator: AggregateFunction[Float, SumWithRetractAccumulator[Float]] =
- new FloatSum0WithRetractAggFunction
-}
-
-class DoubleSum0WithRetractAggFunctionTest extends Sum0WithRetractAggFunctionTestBase[Double] {
-
- override def maxVal = 12345.6789d
-
- override def aggregator: AggregateFunction[Double, SumWithRetractAccumulator[Double]] =
- new DoubleSum0WithRetractAggFunction
-}
-
-
-class DecimalSum0WithRetractAggFunctionTest
- extends AggFunctionTestBase[BigDecimal, DecimalSumWithRetractAccumulator] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("2"),
- new BigDecimal("3"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-1000"),
- new BigDecimal("0.000000000002"),
- new BigDecimal("1000"),
- new BigDecimal("-0.000000000001"),
- new BigDecimal("999.999"),
- null,
- new BigDecimal("4"),
- new BigDecimal("-999.999"),
- null
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("10.000000000001"),
- BigDecimal.ZERO
- )
-
- override def aggregator: AggregateFunction[BigDecimal, DecimalSumWithRetractAccumulator] =
- new DecimalSum0WithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumAggFunctionTest.scala
deleted file mode 100644
index 6816a5e..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumAggFunctionTest.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in sum aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class SumAggFunctionTestBase[T: Numeric]
- extends AggFunctionTestBase[T, SumAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def maxVal: T
-
- private val minVal = numeric.negate(maxVal)
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- minVal,
- numeric.fromInt(1),
- null.asInstanceOf[T],
- numeric.fromInt(2),
- numeric.fromInt(3),
- numeric.fromInt(4),
- numeric.fromInt(5),
- numeric.fromInt(-10),
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T],
- maxVal
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- numeric.fromInt(2),
- null.asInstanceOf[T]
- )
-}
-
-class ByteSumAggFunctionTest extends SumAggFunctionTestBase[Byte] {
-
- override def maxVal = (Byte.MaxValue / 2).toByte
-
- override def aggregator: AggregateFunction[Byte, SumAccumulator[Byte]] =
- new ByteSumAggFunction
-}
-
-class ShortSumAggFunctionTest extends SumAggFunctionTestBase[Short] {
-
- override def maxVal = (Short.MaxValue / 2).toShort
-
- override def aggregator: AggregateFunction[Short, SumAccumulator[Short]] =
- new ShortSumAggFunction
-}
-
-class IntSumAggFunctionTest extends SumAggFunctionTestBase[Int] {
-
- override def maxVal = Int.MaxValue / 2
-
- override def aggregator: AggregateFunction[Int, SumAccumulator[Int]] =
- new IntSumAggFunction
-}
-
-class LongSumAggFunctionTest extends SumAggFunctionTestBase[Long] {
-
- override def maxVal = Long.MaxValue / 2
-
- override def aggregator: AggregateFunction[Long, SumAccumulator[Long]] =
- new LongSumAggFunction
-}
-
-class FloatSumAggFunctionTest extends SumAggFunctionTestBase[Float] {
-
- override def maxVal = 12345.6789f
-
- override def aggregator: AggregateFunction[Float, SumAccumulator[Float]] =
- new FloatSumAggFunction
-}
-
-class DoubleSumAggFunctionTest extends SumAggFunctionTestBase[Double] {
-
- override def maxVal = 12345.6789d
-
- override def aggregator: AggregateFunction[Double, SumAccumulator[Double]] =
- new DoubleSumAggFunction
-}
-
-
-class DecimalSumAggFunctionTest
- extends AggFunctionTestBase[BigDecimal, DecimalSumAccumulator] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("2"),
- new BigDecimal("3"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-1000"),
- new BigDecimal("0.000000000002"),
- new BigDecimal("1000"),
- new BigDecimal("-0.000000000001"),
- new BigDecimal("999.999"),
- null,
- new BigDecimal("4"),
- new BigDecimal("-999.999"),
- null
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("10.000000000001"),
- null
- )
-
- override def aggregator: AggregateFunction[BigDecimal, DecimalSumAccumulator] =
- new DecimalSumAggFunction()
-}
-
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunctionTest.scala
deleted file mode 100644
index 8b6daba..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunctionTest.scala
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in sum with retract aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class SumWithRetractAggFunctionTestBase[T: Numeric]
- extends AggFunctionTestBase[T, SumWithRetractAccumulator[T]] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def maxVal: T
-
- private val minVal = numeric.negate(maxVal)
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- minVal,
- numeric.fromInt(1),
- null.asInstanceOf[T],
- numeric.fromInt(2),
- numeric.fromInt(3),
- numeric.fromInt(4),
- numeric.fromInt(5),
- numeric.fromInt(-10),
- numeric.fromInt(-20),
- numeric.fromInt(17),
- null.asInstanceOf[T],
- maxVal
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- numeric.fromInt(2),
- null.asInstanceOf[T]
- )
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class ByteSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Byte] {
-
- override def maxVal = (Byte.MaxValue / 2).toByte
-
- override def aggregator: AggregateFunction[Byte, SumWithRetractAccumulator[Byte]] =
- new ByteSumWithRetractAggFunction
-}
-
-class ShortSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Short] {
-
- override def maxVal = (Short.MaxValue / 2).toShort
-
- override def aggregator: AggregateFunction[Short, SumWithRetractAccumulator[Short]] =
- new ShortSumWithRetractAggFunction
-}
-
-class IntSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Int] {
-
- override def maxVal = Int.MaxValue / 2
-
- override def aggregator: AggregateFunction[Int, SumWithRetractAccumulator[Int]] =
- new IntSumWithRetractAggFunction
-}
-
-class LongSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Long] {
-
- override def maxVal = Long.MaxValue / 2
-
- override def aggregator: AggregateFunction[Long, SumWithRetractAccumulator[Long]] =
- new LongSumWithRetractAggFunction
-}
-
-class FloatSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Float] {
-
- override def maxVal = 12345.6789f
-
- override def aggregator: AggregateFunction[Float, SumWithRetractAccumulator[Float]] =
- new FloatSumWithRetractAggFunction
-}
-
-class DoubleSumWithRetractAggFunctionTest extends SumWithRetractAggFunctionTestBase[Double] {
-
- override def maxVal = 12345.6789d
-
- override def aggregator: AggregateFunction[Double, SumWithRetractAccumulator[Double]] =
- new DoubleSumWithRetractAggFunction
-}
-
-
-class DecimalSumWithRetractAggFunctionTest
- extends AggFunctionTestBase[BigDecimal, DecimalSumWithRetractAccumulator] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("1"),
- new BigDecimal("2"),
- new BigDecimal("3"),
- null,
- new BigDecimal("0"),
- new BigDecimal("-1000"),
- new BigDecimal("0.000000000002"),
- new BigDecimal("1000"),
- new BigDecimal("-0.000000000001"),
- new BigDecimal("999.999"),
- null,
- new BigDecimal("4"),
- new BigDecimal("-999.999"),
- null
- ),
- Seq(
- null,
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- new BigDecimal("10.000000000001"),
- null
- )
-
- override def aggregator: AggregateFunction[BigDecimal, DecimalSumWithRetractAccumulator] =
- new DecimalSumWithRetractAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala
new file mode 100644
index 0000000..a15f1d1
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala
@@ -0,0 +1,509 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.{Ignore, Test}
+
+class ExpressionReductionRulesTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpressionForBatchSQL(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceProjectExpressionForBatchSQL(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ )
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceFilterExpressionForBatchSQL(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "*" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceCalcExpressionForBatchTableAPI(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceProjectExpressionForBatchTableAPI(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceFilterExpressionForBatchTableAPI(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceCalcExpressionForStreamSQL(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceProjectExpressionForStreamSQL(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ )
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceFilterExpressionForStreamSQL(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "*" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceCalcExpressionForStreamTableAPI(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceProjectExpressionForStreamTableAPI(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceFilterExpressionForStreamTableAPI(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testNestedTablesReductionStream(): Unit = {
+ val util = streamTestUtil()
+
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
+
+ util.tableEnv.registerTable("NewTable", newTable)
+
+ val sqlQuery = "SELECT a FROM NewTable"
+
+ // 1+1 should be normalized to 2
+ val expected = unaryNode("DataStreamCalc", streamTableNode(0), term("select", "+(2, a) AS a"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testNestedTablesReductionBatch(): Unit = {
+ val util = batchTestUtil()
+
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
+
+ util.tableEnv.registerTable("NewTable", newTable)
+
+ val sqlQuery = "SELECT a FROM NewTable"
+
+ // 1+1 should be normalized to 2
+ val expected = unaryNode("DataSetCalc", batchTableNode(0), term("select", "+(2, a) AS a"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ // TODO this NPE is caused by Calcite, it shall pass when [CALCITE-1860] is fixed
+ @Ignore
+ def testReduceDeterministicUDF(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ // if isDeterministic = true, will cause a Calcite NPE, which will be fixed in [CALCITE-1860]
+ val result = table
+ .select('a, 'b, 'c, DeterministicNullFunc() as 'd)
+ .where("d.isNull")
+ .select('a, 'b, 'c)
+
+ val expected: String = streamTableNode(0)
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceNonDeterministicUDF(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .select('a, 'b, 'c, NonDeterministicNullFunc() as 'd)
+ .where("d.isNull")
+ .select('a, 'b, 'c)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", s"IS NULL(${NonDeterministicNullFunc.functionIdentifier}())")
+ )
+
+ util.verifyTable(result, expected)
+ }
+}
+
+object NonDeterministicNullFunc extends ScalarFunction {
+ def eval(): String = null
+ override def isDeterministic = false
+}
+
+object DeterministicNullFunc extends ScalarFunction {
+ def eval(): String = null
+ override def isDeterministic = true
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala
new file mode 100644
index 0000000..3ca9232
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule
+import org.apache.calcite.tools.RuleSets
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.calcite.{CalciteConfig, CalciteConfigBuilder}
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class NormalizationRulesTest extends TableTestBase {
+
+ @Test
+ def testApplyNormalizationRuleForBatchSQL(): Unit = {
+ val util = batchTestUtil()
+
+ // rewrite distinct aggregate
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceNormRuleSet(RuleSets.ofList(AggregateExpandDistinctAggregatesRule.JOIN))
+ .replaceLogicalOptRuleSet(RuleSets.ofList())
+ .replacePhysicalOptRuleSet(RuleSets.ofList())
+ .build()
+ util.tableEnv.getConfig.setCalciteConfig(cc)
+
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "COUNT(DISTINCT a)" +
+ "FROM MyTable group by b"
+
+ // expect double aggregate
+ val expected = unaryNode("LogicalProject",
+ unaryNode("LogicalAggregate",
+ unaryNode("LogicalAggregate",
+ unaryNode("LogicalProject",
+ values("LogicalTableScan", term("table", "[_DataSetTable_0]")),
+ term("b", "$1"), term("a", "$0")),
+ term("group", "{0, 1}")),
+ term("group", "{0}"), term("EXPR$0", "COUNT($1)")
+ ),
+ term("EXPR$0", "$1")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testApplyNormalizationRuleForStreamSQL(): Unit = {
+ val util = streamTestUtil()
+
+ // rewrite distinct aggregate
+ val cc: CalciteConfig = new CalciteConfigBuilder()
+ .replaceNormRuleSet(RuleSets.ofList(AggregateExpandDistinctAggregatesRule.JOIN))
+ .replaceLogicalOptRuleSet(RuleSets.ofList())
+ .replacePhysicalOptRuleSet(RuleSets.ofList())
+ .build()
+ util.tableEnv.getConfig.setCalciteConfig(cc)
+
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "COUNT(DISTINCT a)" +
+ "FROM MyTable group by b"
+
+ // expect double aggregate
+ val expected = unaryNode(
+ "LogicalProject",
+ unaryNode("LogicalAggregate",
+ unaryNode("LogicalAggregate",
+ unaryNode("LogicalProject",
+ values("LogicalTableScan", term("table", "[_DataStreamTable_0]")),
+ term("b", "$1"), term("a", "$0")),
+ term("group", "{0, 1}")),
+ term("group", "{0}"), term("EXPR$0", "COUNT($1)")
+ ),
+ term("EXPR$0", "$1")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala
new file mode 100644
index 0000000..0c3796f
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class QueryDecorrelationTest extends TableTestBase {
+
+ @Test
+ def testCorrelationScalarAggAndFilter(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
+ util.addTable[(Int, String)]("dept", 'deptno, 'name)
+
+ val sql = "SELECT e1.empno\n" +
+ "FROM emp e1, dept d1 where e1.deptno = d1.deptno\n" +
+ "and e1.deptno < 10 and d1.deptno < 15\n" +
+ "and e1.salary > (select avg(salary) from emp e2 where e1.empno = e2.empno)"
+
+ val expectedQuery = unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "empno", "salary", "deptno"),
+ term("where", "<(deptno, 10)")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(1),
+ term("select", "deptno"),
+ term("where", "<(deptno, 15)")
+ ),
+ term("where", "=(deptno, deptno0)"),
+ term("join", "empno", "salary", "deptno", "deptno0"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "empno", "salary")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "empno", "salary"),
+ term("where", "IS NOT NULL(empno)")
+ ),
+ term("groupBy", "empno"),
+ term("select", "empno", "AVG(salary) AS EXPR$0")
+ ),
+ term("where", "AND(=(empno, empno0), >(salary, EXPR$0))"),
+ term("join", "empno", "salary", "empno0", "EXPR$0"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "empno")
+ )
+
+ util.verifySql(sql, expectedQuery)
+ }
+
+ @Test
+ def testDecorrelateWithMultiAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
+ util.addTable[(Int, String)]("dept", 'deptno, 'name)
+
+ val sql = "select sum(e1.empno) from emp e1, dept d1 " +
+ "where e1.deptno = d1.deptno " +
+ "and e1.salary > (" +
+ " select avg(e2.salary) from emp e2 where e2.deptno = d1.deptno" +
+ ")"
+
+ val expectedQuery = unaryNode(
+ "DataSetAggregate",
+ binaryNode(
+ "DataSetUnion",
+ values(
+ "DataSetValues",
+ tuples(List(null)),
+ term("values", "empno")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "empno", "salary", "deptno")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(1),
+ term("select", "deptno")
+ ),
+ term("where", "=(deptno, deptno0)"),
+ term("join", "empno", "salary", "deptno", "deptno0"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "empno", "salary", "deptno0")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "salary", "deptno"),
+ term("where", "IS NOT NULL(deptno)")
+ ),
+ term("groupBy", "deptno"),
+ term("select", "deptno", "AVG(salary) AS EXPR$0")
+ ),
+ term("where", "AND(=(deptno0, deptno), >(salary, EXPR$0))"),
+ term("join", "empno", "salary", "deptno0", "deptno", "EXPR$0"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "empno")
+ ),
+ term("union", "empno")
+ ),
+ term("select", "SUM(empno) AS EXPR$0")
+ )
+
+ util.verifySql(sql, expectedQuery)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RetractionRulesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RetractionRulesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RetractionRulesTest.scala
new file mode 100644
index 0000000..535bbf5
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/plan/RetractionRulesTest.scala
@@ -0,0 +1,320 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.plan
+
+import org.apache.calcite.rel.RelNode
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Table
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.plan.nodes.datastream._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Assert._
+import org.junit.{Ignore, Test}
+
+class RetractionRulesTest extends TableTestBase {
+
+ def streamTestForRetractionUtil(): StreamTableTestForRetractionUtil = {
+ new StreamTableTestForRetractionUtil()
+ }
+
+ @Test
+ def testSelect(): Unit = {
+ val util = streamTestForRetractionUtil()
+ val table = util.addTable[(String, Int)]('word, 'number)
+
+ val resultTable = table.select('word, 'number)
+
+ val expected = s"DataStreamScan(false, Acc)"
+
+ util.verifyTableTrait(resultTable, expected)
+ }
+
+ // one level unbounded groupBy
+ @Test
+ def testGroupBy(): Unit = {
+ val util = streamTestForRetractionUtil()
+ val table = util.addTable[(String, Int)]('word, 'number)
+ val defaultStatus = "false, Acc"
+
+ val resultTable = table
+ .groupBy('word)
+ .select('number.count)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ "DataStreamScan(true, Acc)",
+ s"$defaultStatus"
+ ),
+ s"$defaultStatus"
+ )
+
+ util.verifyTableTrait(resultTable, expected)
+ }
+
+ // two level unbounded groupBy
+ @Test
+ def testTwoGroupBy(): Unit = {
+ val util = streamTestForRetractionUtil()
+ val table = util.addTable[(String, Int)]('word, 'number)
+ val defaultStatus = "false, Acc"
+
+ val resultTable = table
+ .groupBy('word)
+ .select('word, 'number.count as 'count)
+ .groupBy('count)
+ .select('count, 'count.count as 'frequency)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ "DataStreamScan(true, Acc)",
+ "true, AccRetract"
+ ),
+ "true, AccRetract"
+ ),
+ s"$defaultStatus"
+ ),
+ s"$defaultStatus"
+ )
+
+ util.verifyTableTrait(resultTable, expected)
+ }
+
+ // group window
+ @Test
+ def testGroupWindow(): Unit = {
+ val util = streamTestForRetractionUtil()
+ val table = util.addTable[(String, Int)]('word, 'number, 'rowtime.rowtime)
+ val defaultStatus = "false, Acc"
+
+ val resultTable = table
+ .window(Tumble over 50.milli on 'rowtime as 'w)
+ .groupBy('w, 'word)
+ .select('word, 'number.count as 'count)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ "DataStreamScan(true, Acc)",
+ s"$defaultStatus"
+ ),
+ s"$defaultStatus"
+ )
+
+ util.verifyTableTrait(resultTable, expected)
+ }
+
+ // group window after unbounded groupBy
+ @Test
+ @Ignore // cannot pass rowtime through non-windowed aggregation
+ def testGroupWindowAfterGroupBy(): Unit = {
+ val util = streamTestForRetractionUtil()
+ val table = util.addTable[(String, Int)]('word, 'number, 'rowtime.rowtime)
+ val defaultStatus = "false, Acc"
+
+ val resultTable = table
+ .groupBy('word)
+ .select('word, 'number.count as 'count)
+ .window(Tumble over 50.milli on 'rowtime as 'w)
+ .groupBy('w, 'count)
+ .select('count, 'count.count as 'frequency)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ "DataStreamScan(true, Acc)",
+ "true, AccRetract"
+ ),
+ "true, AccRetract"
+ ),
+ s"$defaultStatus"
+ ),
+ s"$defaultStatus"
+ )
+
+ util.verifyTableTrait(resultTable, expected)
+ }
+
+ // over window
+ @Test
+ def testOverWindow(): Unit = {
+ val util = streamTestForRetractionUtil()
+ util.addTable[(String, Int)]("T1", 'word, 'number, 'proctime.proctime)
+ val defaultStatus = "false, Acc"
+
+ val sqlQuery =
+ "SELECT " +
+ "word, count(number) " +
+ "OVER (PARTITION BY word ORDER BY proctime " +
+ "ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW)" +
+ "FROM T1"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ "DataStreamScan(true, Acc)",
+ s"$defaultStatus"
+ ),
+ s"$defaultStatus"
+ )
+
+ util.verifySqlTrait(sqlQuery, expected)
+ }
+
+
+ // over window after unbounded groupBy
+ @Test
+ @Ignore // cannot pass rowtime through non-windowed aggregation
+ def testOverWindowAfterGroupBy(): Unit = {
+ val util = streamTestForRetractionUtil()
+ util.addTable[(String, Int)]("T1", 'word, 'number, 'proctime.proctime)
+ val defaultStatus = "false, Acc"
+
+ val sqlQuery =
+ "SELECT " +
+ "_count, count(word) " +
+ "OVER (PARTITION BY _count ORDER BY proctime " +
+ "ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW)" +
+ "FROM " +
+ "(SELECT word, count(number) as _count FROM T1 GROUP BY word) "
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ "DataStreamScan(true, Acc)",
+ "true, AccRetract"
+ ),
+ "true, AccRetract"
+ ),
+ s"$defaultStatus"
+ ),
+ s"$defaultStatus"
+ )
+
+ util.verifySqlTrait(sqlQuery, expected)
+ }
+
+ // test binaryNode
+ @Test
+ def testBinaryNode(): Unit = {
+ val util = streamTestForRetractionUtil()
+ val lTable = util.addTable[(String, Int)]('word, 'number)
+ val rTable = util.addTable[(String, Long)]('word_r, 'count_r)
+ val defaultStatus = "false, Acc"
+
+ val resultTable = lTable
+ .groupBy('word)
+ .select('word, 'number.count as 'count)
+ .unionAll(rTable)
+ .groupBy('count)
+ .select('count, 'count.count as 'frequency)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ binaryNode(
+ "DataStreamUnion",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ "DataStreamScan(true, Acc)",
+ "true, AccRetract"
+ ),
+ "true, AccRetract"
+ ),
+ "DataStreamScan(true, Acc)",
+ "true, AccRetract"
+ ),
+ "true, AccRetract"
+ ),
+ s"$defaultStatus"
+ ),
+ s"$defaultStatus"
+ )
+
+ util.verifyTableTrait(resultTable, expected)
+ }
+}
+
+class StreamTableTestForRetractionUtil extends StreamTableTestUtil {
+
+ def verifySqlTrait(query: String, expected: String): Unit = {
+ verifyTableTrait(tableEnv.sql(query), expected)
+ }
+
+ def verifyTableTrait(resultTable: Table, expected: String): Unit = {
+ val relNode = resultTable.getRelNode
+ val optimized = tableEnv.optimize(relNode, updatesAsRetraction = false)
+ val actual = TraitUtil.toString(optimized)
+ assertEquals(
+ expected.split("\n").map(_.trim).mkString("\n"),
+ actual.split("\n").map(_.trim).mkString("\n"))
+ }
+}
+
+object TraitUtil {
+ def toString(rel: RelNode): String = {
+ val className = rel.getClass.getSimpleName
+ var childString: String = ""
+ var i = 0
+ while (i < rel.getInputs.size()) {
+ childString += TraitUtil.toString(rel.getInput(i))
+ i += 1
+ }
+
+ val retractString = rel.getTraitSet.getTrait(UpdateAsRetractionTraitDef.INSTANCE).toString
+ val accModetString = rel.getTraitSet.getTrait(AccModeTraitDef.INSTANCE).toString
+
+ s"""$className($retractString, $accModetString)
+ |$childString
+ |""".stripMargin.stripLineEnd
+ }
+}
+
[02/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala
new file mode 100644
index 0000000..531e26f
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/OverWindowITCase.scala
@@ -0,0 +1,347 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.source.SourceFunction
+import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
+import org.apache.flink.table.api.java.utils.UserDefinedScalarFunctions.JavaFunc0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.table.runtime.datastream.table.OverWindowITCase._
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class OverWindowITCase extends StreamingWithStateTestBase {
+
+ @Test
+ def testProcTimeUnBoundedPartitionedRowOver(): Unit = {
+
+ val data = List(
+ (1L, 1, "Hello"),
+ (2L, 2, "Hello"),
+ (3L, 3, "Hello"),
+ (4L, 4, "Hello"),
+ (5L, 5, "Hello"),
+ (6L, 6, "Hello"),
+ (7L, 7, "Hello World"),
+ (8L, 8, "Hello World"),
+ (20L, 20, "Hello World"))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ StreamITCase.clear
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(
+ Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
+ .select('c, countFun('b) over 'w as 'mycount, weightAvgFun('a, 'b) over 'w as 'wAvg)
+ .select('c, 'mycount, 'wAvg)
+
+ val results = windowedTable.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "Hello World,1,7", "Hello World,2,7", "Hello World,3,14",
+ "Hello,1,1", "Hello,2,1", "Hello,3,2", "Hello,4,3", "Hello,5,3", "Hello,6,4")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ StreamITCase.testResults = mutable.MutableList()
+ StreamITCase.clear
+ env.setParallelism(1)
+
+ val data = Seq(
+ Left(14000005L, (1, 1L, "Hi")),
+ Left(14000000L, (2, 1L, "Hello")),
+ Left(14000002L, (1, 1L, "Hello")),
+ Left(14000002L, (1, 2L, "Hello")),
+ Left(14000002L, (1, 3L, "Hello world")),
+ Left(14000003L, (2, 2L, "Hello world")),
+ Left(14000003L, (2, 3L, "Hello world")),
+ Right(14000020L),
+ Left(14000021L, (1, 4L, "Hello world")),
+ Left(14000022L, (1, 5L, "Hello world")),
+ Left(14000022L, (1, 6L, "Hello world")),
+ Left(14000022L, (1, 7L, "Hello world")),
+ Left(14000023L, (2, 4L, "Hello world")),
+ Left(14000023L, (2, 5L, "Hello world")),
+ Right(14000030L)
+ )
+ val table = env
+ .addSource(new RowTimeSourceFunction[(Int, Long, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+ val countFun = new CountAggFunction
+ val weightAvgFun = new WeightedAvg
+ val plusOne = new JavaFunc0
+
+ val windowedTable = table
+ .window(Over partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_RANGE following
+ CURRENT_RANGE as 'w)
+ .select(
+ 'a, 'b, 'c,
+ 'b.sum over 'w,
+ "SUM:".toExpr + ('b.sum over 'w),
+ countFun('b) over 'w,
+ (countFun('b) over 'w) + 1,
+ plusOne(countFun('b) over 'w),
+ array('b.avg over 'w, 'b.max over 'w),
+ 'b.avg over 'w,
+ 'b.max over 'w,
+ 'b.min over 'w,
+ ('b.min over 'w).abs(),
+ weightAvgFun('b, 'a) over 'w)
+
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,1,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,2,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,1,Hi,7,SUM:7,4,5,5,[1, 3],1,3,1,1,1",
+ "2,1,Hello,1,SUM:1,1,2,2,[1, 1],1,1,1,1,1",
+ "2,2,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "2,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
+ "1,4,Hello world,11,SUM:11,5,6,6,[2, 4],2,4,1,1,2",
+ "1,5,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
+ "1,6,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
+ "1,7,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
+ "2,4,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3",
+ "2,5,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3"
+ )
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testProcTimeBoundedPartitionedRowsOver(): Unit = {
+
+ val data = List(
+ (1, 1L, 0, "Hallo", 1L),
+ (2, 2L, 1, "Hallo Welt", 2L),
+ (2, 3L, 2, "Hallo Welt wie", 1L),
+ (3, 4L, 3, "Hallo Welt wie gehts?", 2L),
+ (3, 5L, 4, "ABC", 2L),
+ (3, 6L, 5, "BCD", 3L),
+ (4, 7L, 6, "CDE", 2L),
+ (4, 8L, 7, "DEF", 1L),
+ (4, 9L, 8, "EFG", 1L),
+ (4, 10L, 9, "FGH", 2L),
+ (5, 11L, 10, "GHI", 1L),
+ (5, 12L, 11, "HIJ", 3L),
+ (5, 13L, 12, "IJK", 3L),
+ (5, 14L, 13, "JKL", 2L),
+ (5, 15L, 14, "KLM", 2L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setParallelism(1)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Over partitionBy 'a orderBy 'proctime preceding 4.rows following CURRENT_ROW as 'w)
+ .select('a, 'c.sum over 'w, 'c.min over 'w)
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,0,0",
+ "2,1,1",
+ "2,3,1",
+ "3,3,3",
+ "3,7,3",
+ "3,12,3",
+ "4,6,6",
+ "4,13,6",
+ "4,21,6",
+ "4,30,6",
+ "5,10,10",
+ "5,21,10",
+ "5,33,10",
+ "5,46,10",
+ "5,60,10")
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRowOver(): Unit = {
+ val data = Seq(
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((2L, (2L, 2, "Hello"))),
+ Left((1L, (1L, 1, "Hello"))),
+ Left((3L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Left((1L, (7L, 7, "Hello World"))),
+ Right(2L),
+ Left((3L, (3L, 3, "Hello"))),
+ Left((4L, (4L, 4, "Hello"))),
+ Left((5L, (5L, 5, "Hello"))),
+ Left((6L, (6L, 6, "Hello"))),
+ Left((20L, (20L, 20, "Hello World"))),
+ Right(6L),
+ Left((8L, (8L, 8, "Hello World"))),
+ Left((7L, (7L, 7, "Hello World"))),
+ Right(20L))
+
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setParallelism(1)
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val table = env.addSource[(Long, Int, String)](
+ new RowTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_ROW as 'w)
+ .select('c, 'a, 'a.count over 'w, 'a.sum over 'w)
+
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
+ "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
+ "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
+ "Hello,6,3,15",
+ "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
+ "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRangeOver(): Unit = {
+ val data = Seq(
+ Left((1500L, (1L, 15, "Hello"))),
+ Left((1600L, (1L, 16, "Hello"))),
+ Left((1000L, (1L, 1, "Hello"))),
+ Left((2000L, (2L, 2, "Hello"))),
+ Right(1000L),
+ Left((2000L, (2L, 2, "Hello"))),
+ Left((2000L, (2L, 3, "Hello"))),
+ Left((3000L, (3L, 3, "Hello"))),
+ Right(2000L),
+ Left((4000L, (4L, 4, "Hello"))),
+ Right(3000L),
+ Left((5000L, (5L, 5, "Hello"))),
+ Right(5000L),
+ Left((6000L, (6L, 6, "Hello"))),
+ Left((6500L, (6L, 65, "Hello"))),
+ Right(7000L),
+ Left((9000L, (6L, 9, "Hello"))),
+ Left((9500L, (6L, 18, "Hello"))),
+ Left((9000L, (6L, 9, "Hello"))),
+ Right(10000L),
+ Left((10000L, (7L, 7, "Hello World"))),
+ Left((11000L, (7L, 17, "Hello World"))),
+ Left((11000L, (7L, 77, "Hello World"))),
+ Right(12000L),
+ Left((14000L, (7L, 18, "Hello World"))),
+ Right(14000L),
+ Left((15000L, (8L, 8, "Hello World"))),
+ Right(17000L),
+ Left((20000L, (20L, 20, "Hello World"))),
+ Right(19000L))
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ env.setStateBackend(getStateBackend)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+
+ val table = env.addSource[(Long, Int, String)](
+ new RowTimeSourceFunction[(Long, Int, String)](data))
+ .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(
+ Over partitionBy 'c orderBy 'rowtime preceding 1.seconds following CURRENT_RANGE as 'w)
+ .select('c, 'b, 'a.count over 'w, 'a.sum over 'w)
+
+ val result = windowedTable.toAppendStream[Row]
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
+ "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
+ "Hello,3,4,9",
+ "Hello,4,2,7",
+ "Hello,5,2,9",
+ "Hello,6,2,11", "Hello,65,2,12",
+ "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
+ "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
+ "Hello World,8,2,15",
+ "Hello World,20,1,20")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
+
+object OverWindowITCase {
+
+ class RowTimeSourceFunction[T](
+ dataWithTimestampList: Seq[Either[(Long, T), Long]]) extends SourceFunction[T] {
+ override def run(ctx: SourceContext[T]): Unit = {
+ dataWithTimestampList.foreach {
+ case Left(t) => ctx.collectWithTimestamp(t._2, t._1)
+ case Right(w) => ctx.emitWatermark(new Watermark(w))
+ }
+ }
+
+ override def cancel(): Unit = ???
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala
new file mode 100644
index 0000000..e8cfd75
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/RetractionITCase.scala
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
+import org.apache.flink.table.utils.TableFunc0
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+
+/**
+ * tests for retraction
+ */
+class RetractionITCase extends StreamingWithStateTestBase {
+ // input data
+ val data = List(
+ ("Hello", 1),
+ ("word", 1),
+ ("Hello", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("bark", 1),
+ ("flink", 1)
+ )
+
+ // keyed groupby + keyed groupby
+ @Test
+ def testWordCount(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .groupBy('word)
+ .select('num.sum as 'count)
+ .groupBy('count)
+ .select('count, 'count.count as 'frequency)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = Seq("1,2", "2,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ // keyed groupby + non-keyed groupby
+ @Test
+ def testGroupByAndNonKeyedGroupBy(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .groupBy('word)
+ .select('word as 'word, 'num.sum as 'cnt)
+ .select('cnt.sum)
+
+ val results = resultTable.toRetractStream[Row]
+
+ results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
+ env.execute()
+
+ val expected = Seq("10")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ // non-keyed groupby + keyed groupby
+ @Test
+ def testNonKeyedGroupByAndGroupBy(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .select('num.sum as 'count)
+ .groupBy('count)
+ .select('count, 'count.count)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = Seq("10,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+ // test unique process, if the current output message of unbounded groupby equals the
+ // previous message, unbounded groupby will ignore the current one.
+ @Test
+ def testUniqueProcess(): Unit = {
+ // data input
+ val data = List(
+ (1, 1L),
+ (2, 2L),
+ (3, 3L),
+ (3, 3L),
+ (4, 1L),
+ (4, 0L),
+ (4, 0L),
+ (4, 0L),
+ (5, 1L),
+ (6, 6L),
+ (6, 6L),
+ (6, 6L),
+ (7, 8L)
+ )
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+ env.setParallelism(1)
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'pk, 'value)
+ val resultTable = table
+ .groupBy('pk)
+ .select('pk as 'pk, 'value.sum as 'sum)
+ .groupBy('sum)
+ .select('sum, 'pk.count as 'count)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractMessagesSink)
+ env.execute()
+
+ val expected = Seq(
+ "+1,1", "+2,1", "+3,1", "-3,1", "+6,1", "-1,1", "+1,2", "-1,2", "+1,3", "-6,1", "+6,2",
+ "-6,2", "+6,1", "+12,1", "-12,1", "+18,1", "+8,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ // correlate should handle retraction messages correctly
+ @Test
+ def testCorrelate(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.clear
+ env.setStateBackend(getStateBackend)
+
+ val func0 = new TableFunc0
+
+ val stream = env.fromCollection(data)
+ val table = stream.toTable(tEnv, 'word, 'num)
+ val resultTable = table
+ .groupBy('word)
+ .select('word as 'word, 'num.sum as 'cnt)
+ .leftOuterJoin(func0('word))
+ .groupBy('cnt)
+ .select('cnt, 'word.count as 'frequency)
+
+ val results = resultTable.toRetractStream[Row]
+ results.addSink(new StreamITCase.RetractingSink)
+ env.execute()
+
+ val expected = Seq("1,2", "2,1", "6,1")
+ assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala
new file mode 100644
index 0000000..8a1e398
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSinksITCase.scala
@@ -0,0 +1,510 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import java.io.File
+import java.lang.{Boolean => JBool}
+
+import org.apache.flink.api.common.functions.MapFunction
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.tuple.{Tuple2 => JTuple2}
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.datastream.DataStream
+import org.apache.flink.streaming.api.functions.sink.SinkFunction
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.sinks._
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class TableSinksITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testStreamTableSink(): Unit = {
+
+ val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
+ tmpFile.deleteOnExit()
+ val path = tmpFile.toURI.toString
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ env.setParallelism(4)
+
+ val input = StreamTestData.get3TupleDataStream(env)
+ .map(x => x).setParallelism(4) // increase DOP to 4
+
+ val results = input.toTable(tEnv, 'a, 'b, 'c)
+ .where('a < 5 || 'a > 17)
+ .select('c, 'b)
+ .writeToSink(new CsvTableSink(path))
+
+ env.execute()
+
+ val expected = Seq(
+ "Hi,1", "Hello,2", "Hello world,2", "Hello world, how are you?,3",
+ "Comment#12,6", "Comment#13,6", "Comment#14,6", "Comment#15,6").mkString("\n")
+
+ TestBaseUtils.compareResultsByLinesInMemory(expected, path)
+ }
+
+ @Test
+ def testAppendSinkOnAppendTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.end, 'id.count, 'num.sum)
+ .writeToSink(new TestAppendSink)
+
+ env.execute()
+
+ val result = RowCollector.getAndClearValues.map(_.f1.toString).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.005,4,8",
+ "1970-01-01 00:00:00.01,5,18",
+ "1970-01-01 00:00:00.015,5,24",
+ "1970-01-01 00:00:00.02,5,29",
+ "1970-01-01 00:00:00.025,2,12")
+ .sorted
+ assertEquals(expected, result)
+ }
+
+ @Test
+ def testRetractSinkOnUpdatingTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text)
+
+ t.select('id, 'num, 'text.charLength() as 'len)
+ .groupBy('len)
+ .select('len, 'id.count, 'num.sum)
+ .writeToSink(new TestRetractSink)
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ val retracted = restractResults(results).sorted
+ val expected = List(
+ "2,1,1",
+ "5,1,2",
+ "11,1,2",
+ "25,1,3",
+ "10,7,39",
+ "14,1,3",
+ "9,9,41").sorted
+ assertEquals(expected, retracted)
+
+ }
+
+ @Test
+ def testRetractSinkOnAppendTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.end, 'id.count, 'num.sum)
+ .writeToSink(new TestRetractSink)
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = restractResults(results).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.005,4,8",
+ "1970-01-01 00:00:00.01,5,18",
+ "1970-01-01 00:00:00.015,5,24",
+ "1970-01-01 00:00:00.02,5,29",
+ "1970-01-01 00:00:00.025,2,12")
+ .sorted
+ assertEquals(expected, retracted)
+
+ }
+
+ @Test
+ def testUpsertSinkOnUpdatingTableWithFullKey(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text)
+
+ t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
+ .groupBy('len, 'cTrue)
+ .select('len, 'id.count as 'cnt, 'cTrue)
+ .groupBy('cnt, 'cTrue)
+ .select('cnt, 'len.count, 'cTrue)
+ .writeToSink(new TestUpsertSink(Array("cnt", "cTrue"), false))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertTrue(
+ "Results must include delete messages",
+ results.exists(_.f0 == false)
+ )
+
+ val retracted = upsertResults(results, Array(0, 2)).sorted
+ val expected = List(
+ "1,5,true",
+ "7,1,true",
+ "9,1,true").sorted
+ assertEquals(expected, retracted)
+
+ }
+
+
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithFullKey1(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('num, 'w.end as 'wend, 'id.count)
+ .writeToSink(new TestUpsertSink(Array("wend", "num"), true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = upsertResults(results, Array(0, 1, 2)).sorted
+ val expected = List(
+ "1,1970-01-01 00:00:00.005,1",
+ "2,1970-01-01 00:00:00.005,2",
+ "3,1970-01-01 00:00:00.005,1",
+ "3,1970-01-01 00:00:00.01,2",
+ "4,1970-01-01 00:00:00.01,3",
+ "4,1970-01-01 00:00:00.015,1",
+ "5,1970-01-01 00:00:00.015,4",
+ "5,1970-01-01 00:00:00.02,1",
+ "6,1970-01-01 00:00:00.02,4",
+ "6,1970-01-01 00:00:00.025,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithFullKey2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('w.start as 'wstart, 'w.end as 'wend, 'num, 'id.count)
+ .writeToSink(new TestUpsertSink(Array("wstart", "wend", "num"), true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = upsertResults(results, Array(0, 1, 2)).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,1,1",
+ "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,2,2",
+ "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,3,1",
+ "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,3,2",
+ "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,4,3",
+ "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,4,1",
+ "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,5,4",
+ "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,5,1",
+ "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,6,4",
+ "1970-01-01 00:00:00.02,1970-01-01 00:00:00.025,6,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithoutFullKey1(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('w.end as 'wend, 'id.count as 'cnt)
+ .writeToSink(new TestUpsertSink(null, true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = results.map(_.f1.toString).sorted
+ val expected = List(
+ "1970-01-01 00:00:00.005,1",
+ "1970-01-01 00:00:00.005,2",
+ "1970-01-01 00:00:00.005,1",
+ "1970-01-01 00:00:00.01,2",
+ "1970-01-01 00:00:00.01,3",
+ "1970-01-01 00:00:00.015,1",
+ "1970-01-01 00:00:00.015,4",
+ "1970-01-01 00:00:00.02,1",
+ "1970-01-01 00:00:00.02,4",
+ "1970-01-01 00:00:00.025,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ @Test
+ def testUpsertSinkOnAppendingTableWithoutFullKey2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
+
+ t.window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'num)
+ .select('num, 'id.count as 'cnt)
+ .writeToSink(new TestUpsertSink(null, true))
+
+ env.execute()
+ val results = RowCollector.getAndClearValues
+
+ assertFalse(
+ "Received retraction messages for append only table",
+ results.exists(!_.f0))
+
+ val retracted = results.map(_.f1.toString).sorted
+ val expected = List(
+ "1,1",
+ "2,2",
+ "3,1",
+ "3,2",
+ "4,3",
+ "4,1",
+ "5,4",
+ "5,1",
+ "6,4",
+ "6,2").sorted
+ assertEquals(expected, retracted)
+ }
+
+ /** Converts a list of retraction messages into a list of final results. */
+ private def restractResults(results: List[JTuple2[JBool, Row]]): List[String] = {
+
+ val retracted = results
+ .foldLeft(Map[String, Int]()){ (m: Map[String, Int], v: JTuple2[JBool, Row]) =>
+ val cnt = m.getOrElse(v.f1.toString, 0)
+ if (v.f0) {
+ m + (v.f1.toString -> (cnt + 1))
+ } else {
+ m + (v.f1.toString -> (cnt - 1))
+ }
+ }.filter{ case (_, c: Int) => c != 0 }
+
+ assertFalse(
+ "Received retracted rows which have not been accumulated.",
+ retracted.exists{ case (_, c: Int) => c < 0})
+
+ retracted.flatMap { case (r: String, c: Int) => (0 until c).map(_ => r) }.toList
+ }
+
+ /** Converts a list of upsert messages into a list of final results. */
+ private def upsertResults(results: List[JTuple2[JBool, Row]], keys: Array[Int]): List[String] = {
+
+ def getKeys(r: Row): List[String] =
+ keys.foldLeft(List[String]())((k, i) => r.getField(i).toString :: k)
+
+ val upserted = results.foldLeft(Map[String, String]()){ (o: Map[String, String], r) =>
+ val key = getKeys(r.f1).mkString("")
+ if (r.f0) {
+ o + (key -> r.f1.toString)
+ } else {
+ o - key
+ }
+ }
+
+ upserted.values.toList
+ }
+
+}
+
+private[flink] class TestAppendSink extends AppendStreamTableSink[Row] {
+
+ var fNames: Array[String] = _
+ var fTypes: Array[TypeInformation[_]] = _
+
+ override def emitDataStream(s: DataStream[Row]): Unit = {
+ s.map(
+ new MapFunction[Row, JTuple2[JBool, Row]] {
+ override def map(value: Row): JTuple2[JBool, Row] = new JTuple2(true, value)
+ })
+ .addSink(new RowSink)
+ }
+
+ override def getOutputType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
+
+ override def getFieldNames: Array[String] = fNames
+
+ override def getFieldTypes: Array[TypeInformation[_]] = fTypes
+
+ override def configure(
+ fieldNames: Array[String],
+ fieldTypes: Array[TypeInformation[_]]): TableSink[Row] = {
+ val copy = new TestAppendSink
+ copy.fNames = fieldNames
+ copy.fTypes = fieldTypes
+ copy
+ }
+}
+
+private[flink] class TestRetractSink extends RetractStreamTableSink[Row] {
+
+ var fNames: Array[String] = _
+ var fTypes: Array[TypeInformation[_]] = _
+
+ override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
+ s.addSink(new RowSink)
+ }
+
+ override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
+
+ override def getFieldNames: Array[String] = fNames
+
+ override def getFieldTypes: Array[TypeInformation[_]] = fTypes
+
+ override def configure(
+ fieldNames: Array[String],
+ fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
+ val copy = new TestRetractSink
+ copy.fNames = fieldNames
+ copy.fTypes = fieldTypes
+ copy
+ }
+
+}
+
+private[flink] class TestUpsertSink(
+ expectedKeys: Array[String],
+ expectedIsAppendOnly: Boolean)
+ extends UpsertStreamTableSink[Row] {
+
+ var fNames: Array[String] = _
+ var fTypes: Array[TypeInformation[_]] = _
+
+ override def setKeyFields(keys: Array[String]): Unit =
+ if (keys != null) {
+ assertEquals("Provided key fields do not match expected keys",
+ expectedKeys.sorted.mkString(","),
+ keys.sorted.mkString(","))
+ } else {
+ assertNull("Provided key fields should not be null.", expectedKeys)
+ }
+
+ override def setIsAppendOnly(isAppendOnly: JBool): Unit =
+ assertEquals(
+ "Provided isAppendOnly does not match expected isAppendOnly",
+ expectedIsAppendOnly,
+ isAppendOnly)
+
+ override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
+
+ override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
+ s.addSink(new RowSink)
+ }
+
+ override def getFieldNames: Array[String] = fNames
+
+ override def getFieldTypes: Array[TypeInformation[_]] = fTypes
+
+ override def configure(
+ fieldNames: Array[String],
+ fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
+ val copy = new TestUpsertSink(expectedKeys, expectedIsAppendOnly)
+ copy.fNames = fieldNames
+ copy.fTypes = fieldTypes
+ copy
+ }
+}
+
+class RowSink extends SinkFunction[JTuple2[JBool, Row]] {
+ override def invoke(value: JTuple2[JBool, Row]): Unit = RowCollector.addValue(value)
+}
+
+object RowCollector {
+ private val sink: mutable.ArrayBuffer[JTuple2[JBool, Row]] =
+ new mutable.ArrayBuffer[JTuple2[JBool, Row]]()
+
+ def addValue(value: JTuple2[JBool, Row]): Unit = {
+ sink.synchronized {
+ sink += value
+ }
+ }
+
+ def getAndClearValues: List[JTuple2[JBool, Row]] = {
+ val out = sink.toList
+ sink.clear()
+ out
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala
new file mode 100644
index 0000000..07b748c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TableSourceITCase.scala
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.utils.{CommonTestData, TestFilterableTableSource}
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class TableSourceITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testCsvTableSource(): Unit = {
+
+ val csvTable = CommonTestData.getCsvTableSource
+ StreamITCase.testResults = mutable.MutableList()
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ tEnv.registerTableSource("csvTable", csvTable)
+ tEnv.scan("csvTable")
+ .where('id > 4)
+ .select('last, 'score * 2)
+ .toAppendStream[Row]
+ .addSink(new StreamITCase.StringSink[Row])
+
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Williams,69.0",
+ "Miller,13.56",
+ "Smith,180.2",
+ "Williams,4.68")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testCsvTableSourceWithFilterable(): Unit = {
+ StreamITCase.testResults = mutable.MutableList()
+ val tableName = "MyTable"
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerTableSource(tableName, new TestFilterableTableSource)
+ tEnv.scan(tableName)
+ .where("amount > 4 && price < 9")
+ .select("id, name")
+ .addSink(new StreamITCase.StringSink[Row])
+
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala
new file mode 100644
index 0000000..2f9549e
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/TimeAttributesITCase.scala
@@ -0,0 +1,407 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.api.watermark.Watermark
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.java.utils.Pojos.Pojo1
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, Types}
+import org.apache.flink.table.calcite.table.RelTimeIndicatorConverterTest.TableFunc
+import org.apache.flink.table.expressions.{ExpressionParser, TimeIntervalUnit}
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.runtime.datastream.table.TimeAttributesITCase._
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+/**
+ * Tests for access and materialization of time attributes.
+ */
+class TimeAttributesITCase extends StreamingMultipleProgramsTestBase {
+
+ val data = List(
+ (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
+ (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
+ (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
+ (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
+ (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
+ (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
+ (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
+
+ @Test
+ def testCalcMaterialization(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table.select('rowtime.cast(Types.STRING))
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.001",
+ "1970-01-01 00:00:00.002",
+ "1970-01-01 00:00:00.003",
+ "1970-01-01 00:00:00.004",
+ "1970-01-01 00:00:00.007",
+ "1970-01-01 00:00:00.008",
+ "1970-01-01 00:00:00.016")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testCalcMaterialization2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table
+ .filter('rowtime.cast(Types.LONG) > 4)
+ .select('rowtime, 'rowtime.floor(TimeIntervalUnit.DAY), 'rowtime.ceil(TimeIntervalUnit.DAY))
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.007,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
+ "1970-01-01 00:00:00.008,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0",
+ "1970-01-01 00:00:00.016,1970-01-01 00:00:00.0,1970-01-02 00:00:00.0")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testTableFunction(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(
+ tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
+ val func = new TableFunc
+
+ val t = table.join(func('rowtime, 'proctime, 'string) as 's).select('rowtime, 's)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.001,1trueHi",
+ "1970-01-01 00:00:00.002,2trueHallo",
+ "1970-01-01 00:00:00.003,3trueHello",
+ "1970-01-01 00:00:00.004,4trueHello",
+ "1970-01-01 00:00:00.007,7trueHello",
+ "1970-01-01 00:00:00.008,8trueHello world",
+ "1970-01-01 00:00:00.016,16trueHello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testWindowAfterTableFunction(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(
+ tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string, 'proctime.proctime)
+ val func = new TableFunc
+
+ val t = table
+ .join(func('rowtime, 'proctime, 'string) as 's)
+ .window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.rowtime, 's.count)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.004,4",
+ "1970-01-01 00:00:00.009,2",
+ "1970-01-01 00:00:00.019,1")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(
+ tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table.unionAll(table).select('rowtime)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.001",
+ "1970-01-01 00:00:00.001",
+ "1970-01-01 00:00:00.002",
+ "1970-01-01 00:00:00.002",
+ "1970-01-01 00:00:00.003",
+ "1970-01-01 00:00:00.003",
+ "1970-01-01 00:00:00.004",
+ "1970-01-01 00:00:00.004",
+ "1970-01-01 00:00:00.007",
+ "1970-01-01 00:00:00.007",
+ "1970-01-01 00:00:00.008",
+ "1970-01-01 00:00:00.008",
+ "1970-01-01 00:00:00.016",
+ "1970-01-01 00:00:00.016")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testWindowWithAggregationOnRowtimeSql(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ tEnv.registerTable("MyTable", table)
+
+ val t = tEnv.sql("SELECT COUNT(`rowtime`) FROM MyTable " +
+ "GROUP BY TUMBLE(rowtime, INTERVAL '0.003' SECOND)")
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1",
+ "2",
+ "2",
+ "2"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testMultiWindow(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val t = table
+ .window(Tumble over 2.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.rowtime as 'rowtime, 'int.count as 'int)
+ .window(Tumble over 4.millis on 'rowtime as 'w2)
+ .groupBy('w2)
+ .select('w2.rowtime, 'w2.end, 'int.count)
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.003,1970-01-01 00:00:00.004,2",
+ "1970-01-01 00:00:00.007,1970-01-01 00:00:00.008,2",
+ "1970-01-01 00:00:00.011,1970-01-01 00:00:00.012,1",
+ "1970-01-01 00:00:00.019,1970-01-01 00:00:00.02,1"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testCalcMaterializationWithPojoType(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ val table = stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ tEnv.registerTable("T1", table)
+ val querySql = "select rowtime as ts, string as msg from T1"
+
+ val results = tEnv.sql(querySql).toAppendStream[Pojo1]
+ results.addSink(new StreamITCase.StringSink[Pojo1])
+ env.execute()
+
+ val expected = Seq(
+ "Pojo1{ts=1970-01-01 00:00:00.001, msg='Hi'}",
+ "Pojo1{ts=1970-01-01 00:00:00.002, msg='Hallo'}",
+ "Pojo1{ts=1970-01-01 00:00:00.003, msg='Hello'}",
+ "Pojo1{ts=1970-01-01 00:00:00.004, msg='Hello'}",
+ "Pojo1{ts=1970-01-01 00:00:00.007, msg='Hello'}",
+ "Pojo1{ts=1970-01-01 00:00:00.008, msg='Hello world'}",
+ "Pojo1{ts=1970-01-01 00:00:00.016, msg='Hello world'}")
+
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testPojoSupport(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+
+ val p1 = new TestPojo
+ p1.a = 12
+ p1.b = 42L
+ p1.c = "Test me."
+
+ val p2 = new TestPojo
+ p2.a = 13
+ p2.b = 43L
+ p2.c = "And me."
+
+ val stream = env
+ .fromElements(p1, p2)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermarkPojo)
+ // use aliases, swap all attributes, and skip b2
+ val table = stream.toTable(tEnv, ('b as 'b).rowtime, 'c as 'c, 'a as 'a)
+ // no aliases, no swapping
+ val table2 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c)
+ // use proctime, no skipping
+ val table3 = stream.toTable(tEnv, 'a, 'b.rowtime, 'c, 'b2, 'proctime.proctime)
+
+ // Java expressions
+
+ // use aliases, swap all attributes, and skip b2
+ val table4 = stream.toTable(
+ tEnv,
+ ExpressionParser.parseExpressionList("(b as b).rowtime, c as c, a as a"): _*)
+ // no aliases, no swapping
+ val table5 = stream.toTable(
+ tEnv,
+ ExpressionParser.parseExpressionList("a, b.rowtime, c"): _*)
+
+ val t = table.select('b, 'c , 'a)
+ .unionAll(table2.select('b, 'c, 'a))
+ .unionAll(table3.select('b, 'c, 'a))
+ .unionAll(table4.select('b, 'c, 'a))
+ .unionAll(table5.select('b, 'c, 'a))
+
+ val results = t.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = Seq(
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.042,Test me.,12",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13",
+ "1970-01-01 00:00:00.043,And me.,13")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+}
+
+object TimeAttributesITCase {
+ class TimestampWithEqualWatermark
+ extends AssignerWithPunctuatedWatermarks[(Long, Int, Double, Float, BigDecimal, String)] {
+
+ override def checkAndGetNextWatermark(
+ lastElement: (Long, Int, Double, Float, BigDecimal, String),
+ extractedTimestamp: Long)
+ : Watermark = {
+ new Watermark(extractedTimestamp)
+ }
+
+ override def extractTimestamp(
+ element: (Long, Int, Double, Float, BigDecimal, String),
+ previousElementTimestamp: Long): Long = {
+ element._1
+ }
+ }
+
+ class TimestampWithEqualWatermarkPojo
+ extends AssignerWithPunctuatedWatermarks[TestPojo] {
+
+ override def checkAndGetNextWatermark(
+ lastElement: TestPojo,
+ extractedTimestamp: Long)
+ : Watermark = {
+ new Watermark(extractedTimestamp)
+ }
+
+ override def extractTimestamp(
+ element: TestPojo,
+ previousElementTimestamp: Long): Long = {
+ element.b
+ }
+ }
+
+ class TestPojo() {
+ var a: Int = _
+ var b: Long = _
+ var b2: String = "skip me"
+ var c: String = _
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala
new file mode 100644
index 0000000..f58b8a2
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UnionITCase.scala
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.datastream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+
+import scala.collection.mutable
+
+class UnionITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'd, 'e, 'f)
+
+ val unionDs = ds1.unionAll(ds2).select('c)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Hi", "Hello", "Hello world", "Hi", "Hello", "Hello world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUnionWithFilter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
+
+ val unionDs = ds1.unionAll(ds2.select('a, 'b, 'c)).filter('b < 2).select('c)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Hi", "Hallo")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala
new file mode 100644
index 0000000..f438588
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/table/UserDefinedFunctionITCase.scala
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.runtime.datastream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.expressions.utils.{Func13, Func18, RichFunc2}
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.utils._
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.{Before, Test}
+
+import scala.collection.mutable
+
+class UserDefinedFunctionITCase extends StreamingMultipleProgramsTestBase {
+
+ val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv: StreamTableEnvironment = TableEnvironment.getTableEnvironment(env)
+
+ @Before
+ def clear(): Unit = {
+ StreamITCase.clear
+ }
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+ val pojoFunc0 = new PojoTableFunc()
+
+ val result = t
+ .join(func0('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .join(pojoFunc0('c))
+ .where('age > 20)
+ .select('c, 'name, 'age)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Jack#22,Jack,22", "Anna#44,Anna,44")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = t
+ .leftOuterJoin(func0('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "nosharp,null,null", "Jack#22,Jack,22",
+ "John#19,John,19", "Anna#44,Anna,44")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = t
+ .join(func0('c) as('d, 'e))
+ .where(Func18('d, "J"))
+ .select('c, 'd, 'e)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("Jack#22,Jack,22", "John#19,John,19")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithParameter(): Unit = {
+ val tableFunc1 = new RichTableFunc1
+ tEnv.registerFunction("RichTableFunc1", tableFunc1)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> " "))
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.getSmall3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(tableFunc1('c) as 's)
+ .select('a, 's)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("3,Hello", "3,world")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithUserDefinedScalarFunction(): Unit = {
+ val tableFunc1 = new RichTableFunc1
+ val richFunc2 = new RichFunc2
+ tEnv.registerFunction("RichTableFunc1", tableFunc1)
+ tEnv.registerFunction("RichFunc2", richFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(
+ env,
+ Map("word_separator" -> "#", "string.value" -> "test"))
+ StreamITCase.testResults = mutable.MutableList()
+
+ val result = StreamTestData.getSmall3TupleDataStream(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(tableFunc1(richFunc2('c)) as 's)
+ .select('a, 's)
+
+ val results = result.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "1,Hi",
+ "1,test",
+ "2,Hello",
+ "2,test",
+ "3,Hello world",
+ "3,test")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testTableFunctionConstructorWithParams(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val config = Map("key1" -> "value1", "key2" -> "value2")
+ val func30 = new TableFunc3(null)
+ val func31 = new TableFunc3("OneConf_")
+ val func32 = new TableFunc3("TwoConf_", config)
+
+ val result = t
+ .join(func30('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .join(func31('c) as ('f, 'g))
+ .select('c, 'd, 'e, 'f, 'g)
+ .join(func32('c) as ('h, 'i))
+ .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
+ .toAppendStream[Row]
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Anna#44,Anna,OneConf_Anna,TwoConf__key=key1_value=value1_Anna,44,44,44",
+ "Anna#44,Anna,OneConf_Anna,TwoConf__key=key2_value=value2_Anna,44,44,44",
+ "Jack#22,Jack,OneConf_Jack,TwoConf__key=key1_value=value1_Jack,22,22,22",
+ "Jack#22,Jack,OneConf_Jack,TwoConf__key=key2_value=value2_Jack,22,22,22",
+ "John#19,John,OneConf_John,TwoConf__key=key1_value=value1_John,19,19,19",
+ "John#19,John,OneConf_John,TwoConf__key=key2_value=value2_John,19,19,19"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testScalarFunctionConstructorWithParams(): Unit = {
+ val t = testData(env).toTable(tEnv).as('a, 'b, 'c)
+ val func0 = new Func13("default")
+ val func1 = new Func13("Sunny")
+ val func2 = new Func13("kevin2")
+
+ val result = t.select(func0('c), func1('c),func2('c))
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44",
+ "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22",
+ "default-John#19,Sunny-John#19,kevin2-John#19",
+ "default-nosharp,Sunny-nosharp,kevin2-nosharp"
+ )
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test
+ def testTableFunctionWithVariableArguments(): Unit = {
+ val varArgsFunc0 = new VarArgsFunc0
+ tEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
+
+ val result = testData(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .select('c)
+ .join(varArgsFunc0("1", "2", 'c))
+
+ result.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList(
+ "Anna#44,1",
+ "Anna#44,2",
+ "Anna#44,Anna#44",
+ "Jack#22,1",
+ "Jack#22,2",
+ "Jack#22,Jack#22",
+ "John#19,1",
+ "John#19,2",
+ "John#19,John#19",
+ "nosharp,1",
+ "nosharp,2",
+ "nosharp,nosharp")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ private def testData(
+ env: StreamExecutionEnvironment)
+ : DataStream[(Int, Long, String)] = {
+
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Jack#22"))
+ data.+=((2, 2L, "John#19"))
+ data.+=((3, 2L, "Anna#44"))
+ data.+=((4, 3L, "nosharp"))
+ env.fromCollection(data)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/StreamTableSinksITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/StreamTableSinksITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/StreamTableSinksITCase.scala
deleted file mode 100644
index 47c55f1..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/StreamTableSinksITCase.scala
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.sinks
-
-import java.lang.{Boolean => JBool}
-
-import org.apache.flink.api.common.functions.MapFunction
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.api.java.tuple.{Tuple2 => JTuple2}
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.streaming.api.functions.sink.SinkFunction
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.types.Row
-
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class StreamTableSinksITCase extends StreamingMultipleProgramsTestBase {
-
- @Test(expected = classOf[TableException])
- def testAppendSinkOnUpdatingTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'id, 'num, 'text)
-
- t.groupBy('text)
- .select('text, 'id.count, 'num.sum)
- .writeToSink(new TestAppendSink)
-
- // must fail because table is not append-only
- env.execute()
- }
-
- @Test
- def testAppendSinkOnAppendTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.end, 'id.count, 'num.sum)
- .writeToSink(new TestAppendSink)
-
- env.execute()
-
- val result = RowCollector.getAndClearValues.map(_.f1.toString).sorted
- val expected = List(
- "1970-01-01 00:00:00.005,4,8",
- "1970-01-01 00:00:00.01,5,18",
- "1970-01-01 00:00:00.015,5,24",
- "1970-01-01 00:00:00.02,5,29",
- "1970-01-01 00:00:00.025,2,12")
- .sorted
- assertEquals(expected, result)
- }
-
- @Test
- def testRetractSinkOnUpdatingTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text)
-
- t.select('id, 'num, 'text.charLength() as 'len)
- .groupBy('len)
- .select('len, 'id.count, 'num.sum)
- .writeToSink(new TestRetractSink)
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- val retracted = restractResults(results).sorted
- val expected = List(
- "2,1,1",
- "5,1,2",
- "11,1,2",
- "25,1,3",
- "10,7,39",
- "14,1,3",
- "9,9,41").sorted
- assertEquals(expected, retracted)
-
- }
-
- @Test
- def testRetractSinkOnAppendTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.end, 'id.count, 'num.sum)
- .writeToSink(new TestRetractSink)
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = restractResults(results).sorted
- val expected = List(
- "1970-01-01 00:00:00.005,4,8",
- "1970-01-01 00:00:00.01,5,18",
- "1970-01-01 00:00:00.015,5,24",
- "1970-01-01 00:00:00.02,5,29",
- "1970-01-01 00:00:00.025,2,12")
- .sorted
- assertEquals(expected, retracted)
-
- }
-
- @Test
- def testUpsertSinkOnUpdatingTableWithFullKey(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text)
-
- t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
- .groupBy('len, 'cTrue)
- .select('len, 'id.count as 'cnt, 'cTrue)
- .groupBy('cnt, 'cTrue)
- .select('cnt, 'len.count, 'cTrue)
- .writeToSink(new TestUpsertSink(Array("cnt", "cTrue"), false))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertTrue(
- "Results must include delete messages",
- results.exists(_.f0 == false)
- )
-
- val retracted = upsertResults(results, Array(0, 2)).sorted
- val expected = List(
- "1,5,true",
- "7,1,true",
- "9,1,true").sorted
- assertEquals(expected, retracted)
-
- }
-
- @Test(expected = classOf[TableException])
- def testUpsertSinkOnUpdatingTableWithoutFullKey(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text)
-
- t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
- .groupBy('len, 'cTrue)
- .select('len, 'id.count, 'num.sum)
- .writeToSink(new TestUpsertSink(Array("len", "cTrue"), false))
-
- // must fail because table is updating table without full key
- env.execute()
- }
-
- @Test
- def testUpsertSinkOnAppendingTableWithFullKey1(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('num, 'w.end as 'wend, 'id.count)
- .writeToSink(new TestUpsertSink(Array("wend", "num"), true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = upsertResults(results, Array(0, 1, 2)).sorted
- val expected = List(
- "1,1970-01-01 00:00:00.005,1",
- "2,1970-01-01 00:00:00.005,2",
- "3,1970-01-01 00:00:00.005,1",
- "3,1970-01-01 00:00:00.01,2",
- "4,1970-01-01 00:00:00.01,3",
- "4,1970-01-01 00:00:00.015,1",
- "5,1970-01-01 00:00:00.015,4",
- "5,1970-01-01 00:00:00.02,1",
- "6,1970-01-01 00:00:00.02,4",
- "6,1970-01-01 00:00:00.025,2").sorted
- assertEquals(expected, retracted)
- }
-
- @Test
- def testUpsertSinkOnAppendingTableWithFullKey2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('w.start as 'wstart, 'w.end as 'wend, 'num, 'id.count)
- .writeToSink(new TestUpsertSink(Array("wstart", "wend", "num"), true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = upsertResults(results, Array(0, 1, 2)).sorted
- val expected = List(
- "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,1,1",
- "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,2,2",
- "1970-01-01 00:00:00.0,1970-01-01 00:00:00.005,3,1",
- "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,3,2",
- "1970-01-01 00:00:00.005,1970-01-01 00:00:00.01,4,3",
- "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,4,1",
- "1970-01-01 00:00:00.01,1970-01-01 00:00:00.015,5,4",
- "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,5,1",
- "1970-01-01 00:00:00.015,1970-01-01 00:00:00.02,6,4",
- "1970-01-01 00:00:00.02,1970-01-01 00:00:00.025,6,2").sorted
- assertEquals(expected, retracted)
- }
-
- @Test
- def testUpsertSinkOnAppendingTableWithoutFullKey1(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('w.end as 'wend, 'id.count as 'cnt)
- .writeToSink(new TestUpsertSink(null, true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = results.map(_.f1.toString).sorted
- val expected = List(
- "1970-01-01 00:00:00.005,1",
- "1970-01-01 00:00:00.005,2",
- "1970-01-01 00:00:00.005,1",
- "1970-01-01 00:00:00.01,2",
- "1970-01-01 00:00:00.01,3",
- "1970-01-01 00:00:00.015,1",
- "1970-01-01 00:00:00.015,4",
- "1970-01-01 00:00:00.02,1",
- "1970-01-01 00:00:00.02,4",
- "1970-01-01 00:00:00.025,2").sorted
- assertEquals(expected, retracted)
- }
-
- @Test
- def testUpsertSinkOnAppendingTableWithoutFullKey2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text, 'rowtime.rowtime)
-
- t.window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'num)
- .select('num, 'id.count as 'cnt)
- .writeToSink(new TestUpsertSink(null, true))
-
- env.execute()
- val results = RowCollector.getAndClearValues
-
- assertFalse(
- "Received retraction messages for append only table",
- results.exists(!_.f0))
-
- val retracted = results.map(_.f1.toString).sorted
- val expected = List(
- "1,1",
- "2,2",
- "3,1",
- "3,2",
- "4,3",
- "4,1",
- "5,4",
- "5,1",
- "6,4",
- "6,2").sorted
- assertEquals(expected, retracted)
- }
-
- /** Converts a list of retraction messages into a list of final results. */
- private def restractResults(results: List[JTuple2[JBool, Row]]): List[String] = {
-
- val retracted = results
- .foldLeft(Map[String, Int]()){ (m: Map[String, Int], v: JTuple2[JBool, Row]) =>
- val cnt = m.getOrElse(v.f1.toString, 0)
- if (v.f0) {
- m + (v.f1.toString -> (cnt + 1))
- } else {
- m + (v.f1.toString -> (cnt - 1))
- }
- }.filter{ case (_, c: Int) => c != 0 }
-
- assertFalse(
- "Received retracted rows which have not been accumulated.",
- retracted.exists{ case (_, c: Int) => c < 0})
-
- retracted.flatMap { case (r: String, c: Int) => (0 until c).map(_ => r) }.toList
- }
-
- /** Converts a list of upsert messages into a list of final results. */
- private def upsertResults(results: List[JTuple2[JBool, Row]], keys: Array[Int]): List[String] = {
-
- def getKeys(r: Row): List[String] =
- keys.foldLeft(List[String]())((k, i) => r.getField(i).toString :: k)
-
- val upserted = results.foldLeft(Map[String, String]()){ (o: Map[String, String], r) =>
- val key = getKeys(r.f1).mkString("")
- if (r.f0) {
- o + (key -> r.f1.toString)
- } else {
- o - key
- }
- }
-
- upserted.values.toList
- }
-
-}
-
-private class TestAppendSink extends AppendStreamTableSink[Row] {
-
- var fNames: Array[String] = _
- var fTypes: Array[TypeInformation[_]] = _
-
- override def emitDataStream(s: DataStream[Row]): Unit = {
- s.map(
- new MapFunction[Row, JTuple2[JBool, Row]] {
- override def map(value: Row): JTuple2[JBool, Row] = new JTuple2(true, value)
- })
- .addSink(new RowSink)
- }
-
- override def getOutputType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
-
- override def getFieldNames: Array[String] = fNames
-
- override def getFieldTypes: Array[TypeInformation[_]] = fTypes
-
- override def configure(
- fieldNames: Array[String],
- fieldTypes: Array[TypeInformation[_]]): TableSink[Row] = {
- val copy = new TestAppendSink
- copy.fNames = fieldNames
- copy.fTypes = fieldTypes
- copy
- }
-}
-
-private class TestRetractSink extends RetractStreamTableSink[Row] {
-
- var fNames: Array[String] = _
- var fTypes: Array[TypeInformation[_]] = _
-
- override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
- s.addSink(new RowSink)
- }
-
- override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
-
- override def getFieldNames: Array[String] = fNames
-
- override def getFieldTypes: Array[TypeInformation[_]] = fTypes
-
- override def configure(
- fieldNames: Array[String],
- fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
- val copy = new TestRetractSink
- copy.fNames = fieldNames
- copy.fTypes = fieldTypes
- copy
- }
-
-}
-
-private class TestUpsertSink(
- expectedKeys: Array[String],
- expectedIsAppendOnly: Boolean)
- extends UpsertStreamTableSink[Row] {
-
- var fNames: Array[String] = _
- var fTypes: Array[TypeInformation[_]] = _
-
- override def setKeyFields(keys: Array[String]): Unit =
- if (keys != null) {
- assertEquals("Provided key fields do not match expected keys",
- expectedKeys.sorted.mkString(","),
- keys.sorted.mkString(","))
- } else {
- assertNull("Provided key fields should not be null.", expectedKeys)
- }
-
- override def setIsAppendOnly(isAppendOnly: JBool): Unit =
- assertEquals(
- "Provided isAppendOnly does not match expected isAppendOnly",
- expectedIsAppendOnly,
- isAppendOnly)
-
- override def getRecordType: TypeInformation[Row] = new RowTypeInfo(fTypes, fNames)
-
- override def emitDataStream(s: DataStream[JTuple2[JBool, Row]]): Unit = {
- s.addSink(new RowSink)
- }
-
- override def getFieldNames: Array[String] = fNames
-
- override def getFieldTypes: Array[TypeInformation[_]] = fTypes
-
- override def configure(
- fieldNames: Array[String],
- fieldTypes: Array[TypeInformation[_]]): TableSink[JTuple2[JBool, Row]] = {
- val copy = new TestUpsertSink(expectedKeys, expectedIsAppendOnly)
- copy.fNames = fieldNames
- copy.fTypes = fieldTypes
- copy
- }
-}
-
-class RowSink extends SinkFunction[JTuple2[JBool, Row]] {
- override def invoke(value: JTuple2[JBool, Row]): Unit = RowCollector.addValue(value)
-}
-
-object RowCollector {
- private val sink: mutable.ArrayBuffer[JTuple2[JBool, Row]] =
- new mutable.ArrayBuffer[JTuple2[JBool, Row]]()
-
- def addValue(value: JTuple2[JBool, Row]): Unit = {
- sink.synchronized {
- sink += value
- }
- }
-
- def getAndClearValues: List[JTuple2[JBool, Row]] = {
- val out = sink.toList
- sink.clear()
- out
- }
-
-}
[44/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
[FLINK-6617] [table] Restructuring of tests
- tests are named like the operator or feature that they are testing e.g. Calc, Distinct etc.
- all tests have the same name everywhere (OverWindowTest, OverWindowValidationTest, OverWindowITCase, OverWindowStringExpressionTest)
- no packages with one class
- org.apache.flink.table.api contains all tests that test the translation from batch/stream/table/sql APIs
- org.apache.flink.table.plan contains all tests that modify the plan
- org.apache.flink.table.runtime contains all ITCases and runtime relevant tests
- all other package contain unit tests for the classes of the same package
Project: http://git-wip-us.apache.org/repos/asf/flink/repo
Commit: http://git-wip-us.apache.org/repos/asf/flink/commit/f1fafc0e
Tree: http://git-wip-us.apache.org/repos/asf/flink/tree/f1fafc0e
Diff: http://git-wip-us.apache.org/repos/asf/flink/diff/f1fafc0e
Branch: refs/heads/master
Commit: f1fafc0e1e664296e54c3a37e414087cf85c64cd
Parents: ecde7bc
Author: twalthr <tw...@apache.org>
Authored: Mon Jul 10 17:27:47 2017 +0200
Committer: twalthr <tw...@apache.org>
Committed: Thu Jul 13 12:17:42 2017 +0200
----------------------------------------------------------------------
.../api/java/batch/TableEnvironmentITCase.java | 686 ---------------
.../table/api/java/batch/TableSourceITCase.java | 96 ---
.../api/java/batch/sql/GroupingSetsITCase.java | 225 -----
.../table/api/java/batch/sql/SqlITCase.java | 178 ----
.../table/api/java/stream/sql/SqlITCase.java | 169 ----
.../api/java/stream/utils/StreamTestData.java | 67 --
.../flink/table/api/java/utils/Pojos.java | 45 -
.../api/java/utils/UserDefinedAggFunctions.java | 138 ---
.../java/utils/UserDefinedScalarFunctions.java | 83 --
.../java/utils/UserDefinedTableFunctions.java | 38 -
.../runtime/batch/JavaTableSourceITCase.java | 96 +++
.../runtime/batch/sql/GroupingSetsITCase.java | 225 +++++
.../table/runtime/batch/sql/JavaSqlITCase.java | 178 ++++
.../batch/table/JavaTableEnvironmentITCase.java | 686 +++++++++++++++
.../table/runtime/stream/sql/JavaSqlITCase.java | 167 ++++
.../flink/table/runtime/utils/JavaPojos.java | 45 +
.../table/runtime/utils/JavaStreamTestData.java | 67 ++
.../utils/JavaUserDefinedAggFunctions.java | 138 +++
.../utils/JavaUserDefinedScalarFunctions.java | 83 ++
.../utils/JavaUserDefinedTableFunctions.java | 38 +
.../flink/table/ExpressionReductionTest.scala | 509 -----------
.../flink/table/api/ExternalCatalogTest.scala | 193 +++++
.../flink/table/api/TableEnvironmentTest.scala | 248 ++++++
.../flink/table/api/TableSchemaTest.scala | 72 ++
.../flink/table/api/TableSourceTest.scala | 396 +++++++++
.../api/batch/BatchTableEnvironmentTest.scala | 66 ++
.../flink/table/api/batch/ExplainTest.scala | 122 +++
.../table/api/batch/sql/AggregateTest.scala | 341 ++++++++
.../flink/table/api/batch/sql/CalcTest.scala | 50 ++
.../table/api/batch/sql/CorrelateTest.scala | 237 +++++
.../api/batch/sql/DistinctAggregateTest.scala | 466 ++++++++++
.../table/api/batch/sql/GroupWindowTest.scala | 259 ++++++
.../table/api/batch/sql/GroupingSetsTest.scala | 207 +++++
.../table/api/batch/sql/SetOperatorsTest.scala | 84 ++
.../table/api/batch/sql/SingleRowJoinTest.scala | 428 ++++++++++
.../sql/validation/CalcValidationTest.scala | 39 +
.../validation/GroupWindowValidationTest.scala | 82 ++
.../sql/validation/JoinValidationTest.scala | 150 ++++
.../validation/OverWindowValidationTest.scala | 60 ++
.../sql/validation/SortValidationTest.scala | 39 +
.../table/api/batch/table/AggregateTest.scala | 133 +++
.../flink/table/api/batch/table/CalcTest.scala | 341 ++++++++
.../table/api/batch/table/CorrelateTest.scala | 99 +++
.../table/api/batch/table/GroupWindowTest.scala | 318 +++++++
.../AggregateStringExpressionTest.scala | 275 ++++++
.../stringexpr/CalcStringExpressionTest.scala | 365 ++++++++
.../CorrelateStringExpressionTest.scala | 92 ++
.../stringexpr/JoinStringExpressionTest.scala | 187 ++++
.../validation/AggregateValidationTest.scala | 211 +++++
.../table/validation/CalcValidationTest.scala | 131 +++
.../validation/GroupWindowValidationTest.scala | 171 ++++
.../table/validation/JoinValidationTest.scala | 192 +++++
.../validation/OverWindowValidationTest.scala | 55 ++
.../validation/SetOperatorsValidationTest.scala | 111 +++
.../table/validation/SortValidationTest.scala | 36 +
.../api/scala/batch/TableEnvironmentTest.scala | 318 -------
.../table/api/scala/batch/TableSchemaTest.scala | 73 --
.../api/scala/batch/sql/AggregationsTest.scala | 162 ----
.../batch/sql/CompositeFlatteningTest.scala | 52 --
.../batch/sql/DataSetSingleRowJoinTest.scala | 428 ----------
.../scala/batch/sql/DistinctAggregateTest.scala | 467 ----------
.../batch/sql/ExpressionReductionTest.scala | 136 ---
.../api/scala/batch/sql/GroupingSetsTest.scala | 206 -----
.../batch/sql/QueryDecorrelationTest.scala | 155 ----
.../api/scala/batch/sql/SetOperatorsTest.scala | 85 --
.../sql/UserDefinedTableFunctionTest.scala | 238 ------
.../scala/batch/sql/WindowAggregateTest.scala | 260 ------
.../validation/AggregationsValidationTest.scala | 43 -
.../sql/validation/CalcValidationTest.scala | 38 -
.../sql/validation/JoinValidationTest.scala | 149 ----
.../sql/validation/SortValidationTest.scala | 38 -
.../WindowAggregateValidationTest.scala | 96 ---
.../scala/batch/table/AggregationsTest.scala | 132 ---
.../batch/table/CompositeFlatteningTest.scala | 116 ---
.../api/scala/batch/table/ExplainTest.scala | 123 ---
.../batch/table/ExpressionReductionTest.scala | 119 ---
.../scala/batch/table/FieldProjectionTest.scala | 259 ------
.../api/scala/batch/table/GroupWindowTest.scala | 318 -------
.../table/UserDefinedTableFunctionTest.scala | 97 ---
.../AggregationsStringExpressionTest.scala | 295 -------
.../stringexpr/CalcStringExpressionTest.scala | 343 --------
.../CastingStringExpressionTest.scala | 121 ---
.../stringexpr/JoinStringExpressionTest.scala | 229 -----
...finedTableFunctionStringExpressionTest.scala | 90 --
.../validation/AggregationsValidationTest.scala | 227 -----
.../table/validation/CalcValidationTest.scala | 126 ---
.../CompositeFlatteningValidationTest.scala | 36 -
.../validation/GroupWindowValidationTest.scala | 185 ----
.../table/validation/JoinValidationTest.scala | 240 ------
.../validation/SetOperatorsValidationTest.scala | 112 ---
.../table/validation/SortValidationTest.scala | 38 -
.../batch/utils/LogicalPlanFormatUtils.scala | 40 -
.../api/scala/batch/utils/SortTestUtils.scala | 58 --
.../utils/TableProgramsClusterTestBase.scala | 51 --
.../utils/TableProgramsCollectionTestBase.scala | 46 -
.../batch/utils/TableProgramsTestBase.scala | 48 --
.../TableEnvironmentValidationTest.scala | 244 ------
.../api/scala/stream/TableEnvironmentTest.scala | 120 ---
.../api/scala/stream/TableSchemaTest.scala | 50 --
.../stream/sql/ExpressionReductionTest.scala | 136 ---
.../api/scala/stream/sql/OverWindowTest.scala | 504 -----------
.../table/api/scala/stream/sql/SortITCase.scala | 122 ---
.../table/api/scala/stream/sql/SortTest.scala | 81 --
.../api/scala/stream/sql/TimeTestUtil.scala | 39 -
.../sql/UserDefinedTableFunctionTest.scala | 237 -----
.../scala/stream/sql/WindowAggregateTest.scala | 168 ----
.../validation/AggregationsValidationTest.scala | 141 ---
.../validation/OverWindowValidationTest.scala | 45 -
.../WindowAggregateValidationTest.scala | 90 --
.../api/scala/stream/table/ExplainTest.scala | 74 --
.../stream/table/ExpressionReductionTest.scala | 119 ---
.../stream/table/FieldProjectionTest.scala | 98 ---
.../stream/table/GroupAggregationsTest.scala | 191 -----
.../table/GroupWindowAggregationsITCase.scala | 231 -----
.../table/GroupWindowAggregationsTest.scala | 785 -----------------
.../api/scala/stream/table/OverWindowTest.scala | 595 -------------
.../scala/stream/table/TableSourceTest.scala | 156 ----
.../table/UserDefinedTableFunctionTest.scala | 219 -----
.../stringexpr/CalcStringExpressionTest.scala | 126 ---
.../GroupAggregationsStringExpressionTest.scala | 63 --
.../GroupWindowStringExpressionTest.scala | 258 ------
.../OverWindowStringExpressionTest.scala | 209 -----
.../stringexpr/UnionStringExpressionTest.scala | 48 --
...finedTableFunctionStringExpressionTest.scala | 91 --
.../table/validation/CalcValidationTest.scala | 84 --
.../GroupAggregationsValidationTest.scala | 63 --
.../GroupWindowAggregationsValidationTest.scala | 207 -----
.../validation/OverWindowValidationTest.scala | 117 ---
.../validation/TableSinksValidationTest.scala | 64 --
.../validation/TableSourceValidationTest.scala | 50 --
.../TimeAttributesValidationTest.scala | 79 --
.../table/validation/UnionValidationTest.scala | 84 --
.../UnsupportedOpsValidationTest.scala | 98 ---
...UserDefinedTableFunctionValidationTest.scala | 199 -----
.../api/scala/stream/utils/StreamTestData.scala | 83 --
.../TableEnvironmentValidationTest.scala | 78 --
.../validation/TableSchemaValidationTest.scala | 35 -
.../flink/table/api/stream/ExplainTest.scala | 73 ++
.../api/stream/StreamTableEnvironmentTest.scala | 150 ++++
.../StreamTableEnvironmentValidationTest.scala | 112 +++
.../table/api/stream/sql/AggregateTest.scala | 157 ++++
.../table/api/stream/sql/CorrelateTest.scala | 236 +++++
.../table/api/stream/sql/GroupWindowTest.scala | 146 ++++
.../table/api/stream/sql/OverWindowTest.scala | 505 +++++++++++
.../flink/table/api/stream/sql/SortTest.scala | 64 ++
.../validation/OverWindowValidationTest.scala | 71 ++
.../sql/validation/SortValidationTest.scala | 49 ++
.../WindowAggregateValidationTest.scala | 80 ++
.../table/api/stream/table/AggregateTest.scala | 189 ++++
.../flink/table/api/stream/table/CalcTest.scala | 99 +++
.../table/api/stream/table/CorrelateTest.scala | 220 +++++
.../api/stream/table/GroupWindowTest.scala | 785 +++++++++++++++++
.../table/api/stream/table/OverWindowTest.scala | 596 +++++++++++++
.../api/stream/table/TableSourceTest.scala | 154 ++++
.../AggregateStringExpressionTest.scala | 63 ++
.../stringexpr/CalcStringExpressionTest.scala | 126 +++
.../CorrelateStringExpressionTest.scala | 92 ++
.../GroupWindowStringExpressionTest.scala | 257 ++++++
.../OverWindowStringExpressionTest.scala | 209 +++++
.../SetOperatorsStringExpressionTest.scala | 49 ++
.../validation/AggregateValidationTest.scala | 50 ++
.../table/validation/CalcValidationTest.scala | 49 ++
.../validation/CorrelateValidationTest.scala | 200 +++++
.../validation/GroupWindowValidationTest.scala | 191 +++++
.../validation/OverWindowValidationTest.scala | 144 ++++
.../validation/SetOperatorsValidationTest.scala | 84 ++
.../validation/TableSinkValidationTest.scala | 65 ++
.../validation/TableSourceValidationTest.scala | 50 ++
.../UnsupportedOpsValidationTest.scala | 98 +++
.../TableEnvironmentValidationTest.scala | 237 +++++
.../validation/TableSchemaValidationTest.scala | 35 +
.../validation/TableSinksValidationTest.scala | 42 +
.../validation/TableSourceValidationTest.scala | 51 ++
.../calcite/CalciteConfigBuilderTest.scala | 2 -
.../sql/RelTimeIndicatorConverterTest.scala | 146 ----
.../table/RelTimeIndicatorConverterTest.scala | 286 -------
.../catalog/ExternalCatalogSchemaTest.scala | 3 +-
.../catalog/batch/sql/ExternalCatalogTest.scala | 56 --
.../batch/table/ExternalCatalogTest.scala | 94 --
.../stream/sql/ExternalCatalogTest.scala | 57 --
.../stream/table/ExternalCatalogTest.scala | 65 --
.../catalog/utils/ExternalCatalogTestBase.scala | 38 -
.../table/expressions/CompositeAccessTest.scala | 5 +-
.../flink/table/expressions/MapTypeTest.scala | 1 -
.../expressions/NonDeterministicTests.scala | 2 +-
.../table/expressions/ScalarFunctionsTest.scala | 5 +-
.../table/expressions/ScalarOperatorsTest.scala | 7 +-
.../table/expressions/SqlExpressionTest.scala | 1 +
.../table/expressions/TemporalTypesTest.scala | 4 +-
.../UserDefinedScalarFunctionTest.scala | 4 +-
.../batch/sql/ExpressionReductionTest.scala | 154 ----
.../batch/table/ExpressionReductionTest.scala | 119 ---
.../stream/sql/ExpressionReductionTest.scala | 154 ----
.../stream/table/ExpressionReductionTest.scala | 137 ---
.../utils/CompositeAccessTestBase.scala | 79 --
.../utils/CompositeTypeTestBase.scala | 79 ++
.../expressions/utils/MapTypeTestBase.scala | 1 -
.../utils/ScalarFunctionsTestBase.scala | 105 ---
.../utils/ScalarOperatorsTestBase.scala | 5 +-
.../expressions/utils/ScalarTypesTestBase.scala | 106 +++
.../utils/UserDefinedScalarFunctions.scala | 270 ------
.../utils/userDefinedScalarFunctions.scala | 270 ++++++
.../CompositeAccessValidationTest.scala | 5 +-
.../ScalarFunctionsValidationTest.scala | 5 +-
.../ScalarOperatorsValidationTest.scala | 1 -
.../aggfunctions/AggFunctionTestBase.scala | 156 ----
.../aggfunctions/AvgFunctionTest.scala | 191 -----
.../aggfunctions/CountAggFunctionTest.scala | 38 -
.../aggfunctions/MaxAggFunctionTest.scala | 229 -----
.../MaxWithRetractAggFunctionTest.scala | 241 ------
.../aggfunctions/MinAggFunctionTest.scala | 230 -----
.../MinWithRetractAggFunctionTest.scala | 241 ------
.../aggfunctions/Sum0AggFunctionTest.scala | 156 ----
.../Sum0WithRetractAggFunctionTest.scala | 160 ----
.../aggfunctions/SumAggFunctionTest.scala | 156 ----
.../SumWithRetractAggFunctionTest.scala | 160 ----
.../plan/ExpressionReductionRulesTest.scala | 509 +++++++++++
.../table/plan/NormalizationRulesTest.scala | 100 +++
.../table/plan/QueryDecorrelationTest.scala | 156 ++++
.../flink/table/plan/RetractionRulesTest.scala | 320 +++++++
.../table/plan/RexProgramExtractorTest.scala | 524 ++++++++++++
.../table/plan/RexProgramRewriterTest.scala | 63 ++
.../flink/table/plan/RexProgramTestBase.scala | 79 ++
.../plan/TimeIndicatorConversionTest.scala | 398 +++++++++
.../plan/rules/NormalizationRulesTest.scala | 100 ---
.../table/plan/rules/RetractionRulesTest.scala | 321 -------
.../plan/util/RexProgramExtractorTest.scala | 523 ------------
.../plan/util/RexProgramRewriterTest.scala | 62 --
.../table/plan/util/RexProgramTestBase.scala | 80 --
.../aggfunctions/AggFunctionTestBase.scala | 159 ++++
.../runtime/aggfunctions/AvgFunctionTest.scala | 194 +++++
.../aggfunctions/CountAggFunctionTest.scala | 39 +
.../aggfunctions/MaxAggFunctionTest.scala | 232 +++++
.../MaxWithRetractAggFunctionTest.scala | 244 ++++++
.../aggfunctions/MinAggFunctionTest.scala | 233 +++++
.../MinWithRetractAggFunctionTest.scala | 244 ++++++
.../aggfunctions/Sum0AggFunctionTest.scala | 158 ++++
.../Sum0WithRetractAggFunctionTest.scala | 162 ++++
.../aggfunctions/SumAggFunctionTest.scala | 158 ++++
.../SumWithRetractAggFunctionTest.scala | 162 ++++
.../aggregate/TimeSortProcessFunctionTest.scala | 276 ------
.../runtime/batch/sql/AggregateITCase.scala | 394 +++++++++
.../table/runtime/batch/sql/CalcITCase.scala | 323 +++++++
.../table/runtime/batch/sql/JoinITCase.scala | 520 +++++++++++
.../runtime/batch/sql/SetOperatorsITCase.scala | 263 ++++++
.../table/runtime/batch/sql/SortITCase.scala | 185 ++++
.../batch/sql/TableEnvironmentITCase.scala | 116 +++
.../runtime/batch/sql/TableSourceITCase.scala | 80 ++
.../runtime/batch/table/AggregateITCase.scala | 379 ++++++++
.../table/runtime/batch/table/CalcITCase.scala | 542 ++++++++++++
.../runtime/batch/table/CorrelateITCase.scala | 327 +++++++
.../runtime/batch/table/GroupWindowITCase.scala | 357 ++++++++
.../table/runtime/batch/table/JoinITCase.scala | 298 +++++++
.../batch/table/SetOperatorsITCase.scala | 228 +++++
.../table/runtime/batch/table/SortITCase.scala | 225 +++++
.../batch/table/TableEnvironmentITCase.scala | 179 ++++
.../runtime/batch/table/TableSinkITCase.scala | 67 ++
.../runtime/batch/table/TableSourceITCase.scala | 79 ++
.../dataset/sql/AggregationsITCase.scala | 394 ---------
.../table/runtime/dataset/sql/CalcITCase.scala | 323 -------
.../table/runtime/dataset/sql/JoinITCase.scala | 521 -----------
.../dataset/sql/SetOperatorsITCase.scala | 264 ------
.../table/runtime/dataset/sql/SortITCase.scala | 186 ----
.../runtime/dataset/sql/TableSourceITCase.scala | 81 --
.../dataset/sql/TableWithSQLITCase.scala | 116 ---
.../dataset/table/AggregationsITCase.scala | 379 --------
.../runtime/dataset/table/CalcITCase.scala | 381 ---------
.../runtime/dataset/table/CastingITCase.scala | 110 ---
.../dataset/table/DataSetCalcITCase.scala | 105 ---
.../DataSetUserDefinedFunctionITCase.scala | 346 --------
.../table/DataSetWindowAggregateITCase.scala | 357 --------
.../runtime/dataset/table/JoinITCase.scala | 298 -------
.../dataset/table/SetOperatorsITCase.scala | 228 -----
.../runtime/dataset/table/SortITCase.scala | 226 -----
.../dataset/table/TableEnvironmentITCase.scala | 179 ----
.../runtime/dataset/table/TableSinkITCase.scala | 69 --
.../dataset/table/TableSourceITCase.scala | 79 --
.../table/runtime/datastream/StreamITCase.scala | 82 --
.../datastream/StreamingWithStateTestBase.scala | 39 -
.../datastream/sql/OverWindowITCase.scala | 838 ------------------
.../runtime/datastream/sql/SqlITCase.scala | 319 -------
.../datastream/sql/TableSourceITCase.scala | 61 --
.../runtime/datastream/table/CalcITCase.scala | 269 ------
.../table/GroupAggregationsITCase.scala | 158 ----
.../table/GroupWindowAggregationsITCase.scala | 446 ----------
.../datastream/table/OverWindowITCase.scala | 347 --------
.../datastream/table/RetractionITCase.scala | 193 -----
.../datastream/table/TableSinksITCase.scala | 510 -----------
.../datastream/table/TableSourceITCase.scala | 80 --
.../datastream/table/TimeAttributesITCase.scala | 407 ---------
.../runtime/datastream/table/UnionITCase.scala | 75 --
.../table/UserDefinedFunctionITCase.scala | 246 ------
.../table/runtime/harness/HarnessTestBase.scala | 17 +-
.../SortProcessFunctionHarnessTest.scala | 275 ++++++
.../runtime/stream/TimeAttributesITCase.scala | 407 +++++++++
.../runtime/stream/sql/OverWindowITCase.scala | 854 +++++++++++++++++++
.../table/runtime/stream/sql/SortITCase.scala | 121 +++
.../table/runtime/stream/sql/SqlITCase.scala | 318 +++++++
.../runtime/stream/sql/TableSourceITCase.scala | 60 ++
.../runtime/stream/table/AggregateITCase.scala | 157 ++++
.../table/runtime/stream/table/CalcITCase.scala | 300 +++++++
.../runtime/stream/table/CorrelateITCase.scala | 225 +++++
.../stream/table/GroupWindowITCase.scala | 445 ++++++++++
.../runtime/stream/table/OverWindowITCase.scala | 346 ++++++++
.../runtime/stream/table/RetractionITCase.scala | 191 +++++
.../stream/table/SetOperatorsITCase.scala | 73 ++
.../runtime/stream/table/TableSinkITCase.scala | 509 +++++++++++
.../stream/table/TableSourceITCase.scala | 80 ++
.../table/runtime/utils/CommonTestData.scala | 177 ++++
.../table/runtime/utils/SortTestUtils.scala | 57 ++
.../table/runtime/utils/StreamITCase.scala | 82 ++
.../table/runtime/utils/StreamTestData.scala | 83 ++
.../utils/StreamingWithStateTestBase.scala | 39 +
.../utils/TableProgramsClusterTestBase.scala | 50 ++
.../utils/TableProgramsCollectionTestBase.scala | 45 +
.../runtime/utils/TableProgramsTestBase.scala | 48 ++
.../table/runtime/utils/TimeTestUtil.scala | 38 +
.../utils/UserDefinedFunctionTestUtils.scala | 53 ++
.../validation/TableSinksValidationTest.scala | 45 -
.../flink/table/sources/TableSourceTest.scala | 84 --
.../table/sources/TableSourceTestBase.scala | 61 --
.../table/sources/batch/TableSourceTest.scala | 421 ---------
.../sources/stream/sql/TableSourceTest.scala | 45 -
.../sources/stream/table/TableSourceTest.scala | 91 --
.../validation/TableSourceBalidationTest.scala | 52 --
.../flink/table/utils/CommonTestData.scala | 178 ----
.../table/utils/LogicalPlanFormatUtils.scala | 40 +
.../flink/table/utils/TableTestBase.scala | 13 +-
.../utils/UserDefinedFunctionTestUtils.scala | 53 --
329 files changed, 28016 insertions(+), 29976 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableEnvironmentITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableEnvironmentITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableEnvironmentITCase.java
deleted file mode 100644
index 0def39a..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableEnvironmentITCase.java
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.batch;
-
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.java.DataSet;
-import org.apache.flink.api.java.ExecutionEnvironment;
-import org.apache.flink.api.java.tuple.Tuple3;
-import org.apache.flink.api.java.tuple.Tuple4;
-import org.apache.flink.api.java.tuple.Tuple5;
-import org.apache.flink.api.java.typeutils.GenericTypeInfo;
-import org.apache.flink.api.java.typeutils.TupleTypeInfo;
-import org.apache.flink.table.api.Table;
-import org.apache.flink.table.api.TableEnvironment;
-import org.apache.flink.table.api.TableException;
-import org.apache.flink.table.api.java.BatchTableEnvironment;
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase;
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase;
-import org.apache.flink.table.calcite.CalciteConfig;
-import org.apache.flink.table.calcite.CalciteConfigBuilder;
-import org.apache.flink.test.operators.util.CollectionDataSets;
-import org.apache.flink.types.Row;
-
-import org.apache.calcite.tools.RuleSets;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * Integration tests for {@link BatchTableEnvironment}.
- */
-@RunWith(Parameterized.class)
-public class TableEnvironmentITCase extends TableProgramsCollectionTestBase {
-
- public TableEnvironmentITCase(TableConfigMode configMode) {
- super(configMode);
- }
-
- @Parameterized.Parameters(name = "Table config = {0}")
- public static Collection<Object[]> parameters() {
- return Arrays.asList(new Object[][] {
- { TableProgramsTestBase.DEFAULT() }
- });
- }
-
- @Test
- public void testSimpleRegister() throws Exception {
- final String tableName = "MyTable";
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- tableEnv.registerDataSet(tableName, ds);
- Table t = tableEnv.scan(tableName);
-
- Table result = t.select("f0, f1");
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
- "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testRegisterWithFields() throws Exception {
- final String tableName = "MyTable";
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- tableEnv.registerDataSet(tableName, ds, "a, b, c");
- Table t = tableEnv.scan(tableName);
-
- Table result = t.select("a, b, c");
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" +
- "14,5,Comment#8\n" + "15,5,Comment#9\n" + "16,6,Comment#10\n" +
- "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19,6,Comment#13\n" +
- "20,6,Comment#14\n" + "21,6,Comment#15\n";
- compareResultAsText(results, expected);
- }
-
- @Test(expected = TableException.class)
- public void testRegisterExistingDatasetTable() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- tableEnv.registerDataSet("MyTable", ds);
- DataSet<Tuple5<Integer, Long, Integer, String, Long>> ds2 =
- CollectionDataSets.getSmall5TupleDataSet(env);
- // Must fail. Name is already used for different table.
- tableEnv.registerDataSet("MyTable", ds2);
- }
-
- @Test(expected = TableException.class)
- public void testScanUnregisteredTable() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // Must fail. No table registered under that name.
- tableEnv.scan("nonRegisteredTable");
- }
-
- @Test
- public void testTableRegister() throws Exception {
- final String tableName = "MyTable";
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- Table t = tableEnv.fromDataSet(ds);
- tableEnv.registerTable(tableName, t);
- Table result = tableEnv.scan(tableName).select("f0, f1").filter("f0 > 7");
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" +
- "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n";
- compareResultAsText(results, expected);
- }
-
- @Test(expected = TableException.class)
- public void testIllegalName() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- Table t = tableEnv.fromDataSet(ds);
- // Must fail. Table name matches internal name pattern.
- tableEnv.registerTable("_DataSetTable_42", t);
- }
-
- @Test(expected = TableException.class)
- public void testRegisterTableFromOtherEnv() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv1 = TableEnvironment.getTableEnvironment(env, config());
- BatchTableEnvironment tableEnv2 = TableEnvironment.getTableEnvironment(env, config());
-
- Table t = tableEnv1.fromDataSet(CollectionDataSets.get3TupleDataSet(env));
- // Must fail. Table is bound to different TableEnvironment.
- tableEnv2.registerTable("MyTable", t);
- }
-
- @Test
- public void testAsFromTuple() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- Table table = tableEnv
- .fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, c")
- .select("a, b, c");
-
- DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
- List<Row> results = ds.collect();
- String expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" +
- "14,5,Comment#8\n" + "15,5,Comment#9\n" + "16,6,Comment#10\n" +
- "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19,6,Comment#13\n" +
- "20,6,Comment#14\n" + "21,6,Comment#15\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testAsFromAndToTuple() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- Table table = tableEnv
- .fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, c")
- .select("a, b, c");
-
- TypeInformation<?> ti = new TupleTypeInfo<Tuple3<Integer, Long, String>>(
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.LONG_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO);
-
- DataSet<?> ds = tableEnv.toDataSet(table, ti);
- List<?> results = ds.collect();
- String expected = "(1,1,Hi)\n" + "(2,2,Hello)\n" + "(3,2,Hello world)\n" +
- "(4,3,Hello world, how are you?)\n" + "(5,3,I am fine.)\n" + "(6,3,Luke Skywalker)\n" +
- "(7,4,Comment#1)\n" + "(8,4,Comment#2)\n" + "(9,4,Comment#3)\n" + "(10,4,Comment#4)\n" +
- "(11,5,Comment#5)\n" + "(12,5,Comment#6)\n" + "(13,5,Comment#7)\n" +
- "(14,5,Comment#8)\n" + "(15,5,Comment#9)\n" + "(16,6,Comment#10)\n" +
- "(17,6,Comment#11)\n" + "(18,6,Comment#12)\n" + "(19,6,Comment#13)\n" +
- "(20,6,Comment#14)\n" + "(21,6,Comment#15)\n";
- compareResultAsText(results, expected);
- }
-
- @Ignore
- @Test
- public void testAsFromTupleToPojo() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- List<Tuple4<String, Integer, Double, String>> data = new ArrayList<>();
- data.add(new Tuple4<>("Rofl", 1, 1.0, "Hi"));
- data.add(new Tuple4<>("lol", 2, 1.0, "Hi"));
- data.add(new Tuple4<>("Test me", 4, 3.33, "Hello world"));
-
- Table table = tableEnv
- .fromDataSet(env.fromCollection(data), "q, w, e, r")
- .select("q as a, w as b, e as c, r as d");
-
- DataSet<SmallPojo2> ds = tableEnv.toDataSet(table, SmallPojo2.class);
- List<SmallPojo2> results = ds.collect();
- String expected = "Rofl,1,1.0,Hi\n" + "lol,2,1.0,Hi\n" + "Test me,4,3.33,Hello world\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testAsFromPojo() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- List<SmallPojo> data = new ArrayList<>();
- data.add(new SmallPojo("Peter", 28, 4000.00, "Sales", new Integer[] {42}));
- data.add(new SmallPojo("Anna", 56, 10000.00, "Engineering", new Integer[] {}));
- data.add(new SmallPojo("Lucy", 42, 6000.00, "HR", new Integer[] {1, 2, 3}));
-
- Table table = tableEnv
- .fromDataSet(env.fromCollection(data),
- "department AS a, " +
- "age AS b, " +
- "salary AS c, " +
- "name AS d," +
- "roles as e")
- .select("a, b, c, d, e");
-
- DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
- List<Row> results = ds.collect();
- String expected =
- "Sales,28,4000.0,Peter,[42]\n" +
- "Engineering,56,10000.0,Anna,[]\n" +
- "HR,42,6000.0,Lucy,[1, 2, 3]\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testAsFromPrivateFieldsPojo() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- List<PrivateSmallPojo> data = new ArrayList<>();
- data.add(new PrivateSmallPojo("Peter", 28, 4000.00, "Sales"));
- data.add(new PrivateSmallPojo("Anna", 56, 10000.00, "Engineering"));
- data.add(new PrivateSmallPojo("Lucy", 42, 6000.00, "HR"));
-
- Table table = tableEnv
- .fromDataSet(env.fromCollection(data),
- "department AS a, " +
- "age AS b, " +
- "salary AS c, " +
- "name AS d")
- .select("a, b, c, d");
-
- DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
- List<Row> results = ds.collect();
- String expected =
- "Sales,28,4000.0,Peter\n" +
- "Engineering,56,10000.0,Anna\n" +
- "HR,42,6000.0,Lucy\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testAsFromAndToPojo() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- List<SmallPojo> data = new ArrayList<>();
- data.add(new SmallPojo("Peter", 28, 4000.00, "Sales", new Integer[] {42}));
- data.add(new SmallPojo("Anna", 56, 10000.00, "Engineering", new Integer[] {}));
- data.add(new SmallPojo("Lucy", 42, 6000.00, "HR", new Integer[] {1, 2, 3}));
-
- Table table = tableEnv
- .fromDataSet(env.fromCollection(data),
- "department AS a, " +
- "age AS b, " +
- "salary AS c, " +
- "name AS d," +
- "roles AS e")
- .select("a, b, c, d, e");
-
- DataSet<SmallPojo2> ds = tableEnv.toDataSet(table, SmallPojo2.class);
- List<SmallPojo2> results = ds.collect();
- String expected =
- "Sales,28,4000.0,Peter,[42]\n" +
- "Engineering,56,10000.0,Anna,[]\n" +
- "HR,42,6000.0,Lucy,[1, 2, 3]\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testAsFromAndToPrivateFieldPojo() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- List<PrivateSmallPojo> data = new ArrayList<>();
- data.add(new PrivateSmallPojo("Peter", 28, 4000.00, "Sales"));
- data.add(new PrivateSmallPojo("Anna", 56, 10000.00, "Engineering"));
- data.add(new PrivateSmallPojo("Lucy", 42, 6000.00, "HR"));
-
- Table table = tableEnv
- .fromDataSet(env.fromCollection(data),
- "department AS a, " +
- "age AS b, " +
- "salary AS c, " +
- "name AS d")
- .select("a, b, c, d");
-
- DataSet<PrivateSmallPojo2> ds = tableEnv.toDataSet(table, PrivateSmallPojo2.class);
- List<PrivateSmallPojo2> results = ds.collect();
- String expected =
- "Sales,28,4000.0,Peter\n" +
- "Engineering,56,10000.0,Anna\n" +
- "HR,42,6000.0,Lucy\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testAsWithPojoAndGenericTypes() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- List<PojoWithGeneric> data = new ArrayList<>();
- data.add(new PojoWithGeneric("Peter", 28, new HashMap<String, String>(), new ArrayList<String>()));
- HashMap<String, String> hm1 = new HashMap<>();
- hm1.put("test1", "test1");
- data.add(new PojoWithGeneric("Anna", 56, hm1, new ArrayList<String>()));
- HashMap<String, String> hm2 = new HashMap<>();
- hm2.put("abc", "cde");
- data.add(new PojoWithGeneric("Lucy", 42, hm2, new ArrayList<String>()));
-
- Table table = tableEnv
- .fromDataSet(env.fromCollection(data),
- "name AS a, " +
- "age AS b, " +
- "generic AS c, " +
- "generic2 AS d")
- .select("a, b, c, c as c2, d")
- .select("a, b, c, c === c2, d");
-
- DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
- List<Row> results = ds.collect();
- String expected =
- "Peter,28,{},true,[]\n" +
- "Anna,56,{test1=test1},true,[]\n" +
- "Lucy,42,{abc=cde},true,[]\n";
- compareResultAsText(results, expected);
- }
-
- @Test(expected = TableException.class)
- public void testGenericRow() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // use null value the enforce GenericType
- DataSet<Row> dataSet = env.fromElements(Row.of(1, 2L, "Hello", null));
- assertTrue(dataSet.getType() instanceof GenericTypeInfo);
- assertTrue(dataSet.getType().getTypeClass().equals(Row.class));
-
- // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
- tableEnv.fromDataSet(dataSet);
- }
-
- @Test(expected = TableException.class)
- public void testGenericRowWithAlias() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // use null value the enforce GenericType
- DataSet<Row> dataSet = env.fromElements(Row.of((Integer) null));
- assertTrue(dataSet.getType() instanceof GenericTypeInfo);
- assertTrue(dataSet.getType().getTypeClass().equals(Row.class));
-
- // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
- tableEnv.fromDataSet(dataSet, "nullField");
- }
-
- @Test(expected = TableException.class)
- public void testAsWithToManyFields() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // Must fail. Too many field names specified.
- tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, c, d");
- }
-
- @Test(expected = TableException.class)
- public void testAsWithAmbiguousFields() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // Must fail. Specified field names are not unique.
- tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, b");
- }
-
- @Test(expected = TableException.class)
- public void testAsWithNonFieldReference1() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // Must fail. as() does only allow field name expressions
- tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a + 1, b, c");
- }
-
- @Test(expected = TableException.class)
- public void testAsWithNonFieldReference2() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // Must fail. as() does only allow field name expressions
- tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a as foo, b, c");
- }
-
- @Test(expected = TableException.class)
- public void testNonStaticClassInput() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // Must fail since class is not static
- tableEnv.fromDataSet(env.fromElements(new MyNonStatic()), "name");
- }
-
- @Test(expected = TableException.class)
- public void testNonStaticClassOutput() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- // Must fail since class is not static
- Table t = tableEnv.fromDataSet(env.fromElements(1, 2, 3), "number");
- tableEnv.toDataSet(t, MyNonStatic.class);
- }
-
- @Test(expected = TableException.class)
- public void testCustomCalciteConfig() {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- CalciteConfig cc = new CalciteConfigBuilder()
- .replaceLogicalOptRuleSet(RuleSets.ofList())
- .replacePhysicalOptRuleSet(RuleSets.ofList())
- .build();
- tableEnv.getConfig().setCalciteConfig(cc);
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- Table t = tableEnv.fromDataSet(ds);
- tableEnv.toDataSet(t, Row.class);
- }
-
- // --------------------------------------------------------------------------------------------
-
- /**
- * Non-static class.
- */
- public class MyNonStatic {
- public int number;
- }
-
- /**
- * Small POJO.
- */
- @SuppressWarnings("unused")
- public static class SmallPojo {
-
- public SmallPojo() { }
-
- public SmallPojo(String name, int age, double salary, String department, Integer[] roles) {
- this.name = name;
- this.age = age;
- this.salary = salary;
- this.department = department;
- this.roles = roles;
- }
-
- public String name;
- public int age;
- public double salary;
- public String department;
- public Integer[] roles;
- }
-
- /**
- * POJO with generic fields.
- */
- @SuppressWarnings("unused")
- public static class PojoWithGeneric {
- public String name;
- public int age;
- public HashMap<String, String> generic;
- public ArrayList<String> generic2;
-
- public PojoWithGeneric() {
- // default constructor
- }
-
- public PojoWithGeneric(String name, int age, HashMap<String, String> generic,
- ArrayList<String> generic2) {
- this.name = name;
- this.age = age;
- this.generic = generic;
- this.generic2 = generic2;
- }
-
- @Override
- public String toString() {
- return name + "," + age + "," + generic + "," + generic2;
- }
- }
-
- /**
- * Small POJO with private fields.
- */
- @SuppressWarnings("unused")
- public static class PrivateSmallPojo {
-
- public PrivateSmallPojo() { }
-
- public PrivateSmallPojo(String name, int age, double salary, String department) {
- this.name = name;
- this.age = age;
- this.salary = salary;
- this.department = department;
- }
-
- private String name;
- private int age;
- private double salary;
- private String department;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- public double getSalary() {
- return salary;
- }
-
- public void setSalary(double salary) {
- this.salary = salary;
- }
-
- public String getDepartment() {
- return department;
- }
-
- public void setDepartment(String department) {
- this.department = department;
- }
- }
-
- /**
- * Another small POJO.
- */
- @SuppressWarnings("unused")
- public static class SmallPojo2 {
-
- public SmallPojo2() { }
-
- public SmallPojo2(String a, int b, double c, String d, Integer[] e) {
- this.a = a;
- this.b = b;
- this.c = c;
- this.d = d;
- this.e = e;
- }
-
- public String a;
- public int b;
- public double c;
- public String d;
- public Integer[] e;
-
- @Override
- public String toString() {
- return a + "," + b + "," + c + "," + d + "," + Arrays.toString(e);
- }
- }
-
- /**
- * Another small POJO with private fields.
- */
- @SuppressWarnings("unused")
- public static class PrivateSmallPojo2 {
-
- public PrivateSmallPojo2() { }
-
- public PrivateSmallPojo2(String a, int b, double c, String d) {
- this.a = a;
- this.b = b;
- this.c = c;
- this.d = d;
- }
-
- private String a;
- private int b;
- private double c;
- private String d;
-
- public String getA() {
- return a;
- }
-
- public void setA(String a) {
- this.a = a;
- }
-
- public int getB() {
- return b;
- }
-
- public void setB(int b) {
- this.b = b;
- }
-
- public double getC() {
- return c;
- }
-
- public void setC(double c) {
- this.c = c;
- }
-
- public String getD() {
- return d;
- }
-
- public void setD(String d) {
- this.d = d;
- }
-
- @Override
- public String toString() {
- return a + "," + b + "," + c + "," + d;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableSourceITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableSourceITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableSourceITCase.java
deleted file mode 100644
index 864d4f8..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/TableSourceITCase.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.batch;
-
-import org.apache.flink.api.java.DataSet;
-import org.apache.flink.api.java.ExecutionEnvironment;
-import org.apache.flink.table.api.Table;
-import org.apache.flink.table.api.TableEnvironment;
-import org.apache.flink.table.api.java.BatchTableEnvironment;
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase;
-import org.apache.flink.table.sources.BatchTableSource;
-import org.apache.flink.table.utils.CommonTestData;
-import org.apache.flink.types.Row;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.List;
-
-/**
- * Integration tests for {@link BatchTableSource}.
- */
-@RunWith(Parameterized.class)
-public class TableSourceITCase extends TableProgramsCollectionTestBase {
-
- public TableSourceITCase(TableConfigMode configMode) {
- super(configMode);
- }
-
- @Test
- public void testBatchTableSourceTableAPI() throws Exception {
-
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
- BatchTableSource csvTable = CommonTestData.getCsvTableSource();
-
- tableEnv.registerTableSource("persons", csvTable);
-
- Table result = tableEnv.scan("persons")
- .select("id, first, last, score");
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
-
- String expected = "1,Mike,Smith,12.3\n" +
- "2,Bob,Taylor,45.6\n" +
- "3,Sam,Miller,7.89\n" +
- "4,Peter,Smith,0.12\n" +
- "5,Liz,Williams,34.5\n" +
- "6,Sally,Miller,6.78\n" +
- "7,Alice,Smith,90.1\n" +
- "8,Kelly,Williams,2.34\n";
-
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testBatchTableSourceSQL() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
- BatchTableSource csvTable = CommonTestData.getCsvTableSource();
-
- tableEnv.registerTableSource("persons", csvTable);
-
- Table result = tableEnv
- .sql("SELECT `last`, FLOOR(id), score * 2 FROM persons WHERE score < 20");
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
-
- String expected = "Smith,1,24.6\n" +
- "Miller,3,15.78\n" +
- "Smith,4,0.24\n" +
- "Miller,6,13.56\n" +
- "Williams,8,4.68\n";
-
- compareResultAsText(results, expected);
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/GroupingSetsITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/GroupingSetsITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/GroupingSetsITCase.java
deleted file mode 100644
index 29fbdf5..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/GroupingSetsITCase.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.batch.sql;
-
-import org.apache.flink.api.common.functions.MapFunction;
-import org.apache.flink.api.java.DataSet;
-import org.apache.flink.api.java.ExecutionEnvironment;
-import org.apache.flink.api.java.operators.MapOperator;
-import org.apache.flink.api.java.tuple.Tuple3;
-import org.apache.flink.table.api.Table;
-import org.apache.flink.table.api.TableConfig;
-import org.apache.flink.table.api.TableEnvironment;
-import org.apache.flink.table.api.java.BatchTableEnvironment;
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase;
-import org.apache.flink.test.operators.util.CollectionDataSets;
-import org.apache.flink.test.util.TestBaseUtils;
-import org.apache.flink.types.Row;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * This test should be replaced by a DataSetAggregateITCase.
- * We should only perform logical unit tests here.
- * Until then, we perform a cluster test here.
- */
-@RunWith(Parameterized.class)
-public class GroupingSetsITCase extends TableProgramsClusterTestBase {
-
- private static final String TABLE_NAME = "MyTable";
- private static final String TABLE_WITH_NULLS_NAME = "MyTableWithNulls";
- private BatchTableEnvironment tableEnv;
-
- public GroupingSetsITCase(TestExecutionMode mode, TableConfigMode tableConfigMode) {
- super(mode, tableConfigMode);
- }
-
- @Before
- public void setupTables() {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- tableEnv = TableEnvironment.getTableEnvironment(env, new TableConfig());
-
- DataSet<Tuple3<Integer, Long, String>> dataSet = CollectionDataSets.get3TupleDataSet(env);
- tableEnv.registerDataSet(TABLE_NAME, dataSet);
-
- MapOperator<Tuple3<Integer, Long, String>, Tuple3<Integer, Long, String>> dataSetWithNulls =
- dataSet.map(new MapFunction<Tuple3<Integer, Long, String>, Tuple3<Integer, Long, String>>() {
-
- @Override
- public Tuple3<Integer, Long, String> map(Tuple3<Integer, Long, String> value) throws Exception {
- if (value.f2.toLowerCase().contains("world")) {
- value.f2 = null;
- }
- return value;
- }
- });
- tableEnv.registerDataSet(TABLE_WITH_NULLS_NAME, dataSetWithNulls);
- }
-
- @Test
- public void testGroupingSets() throws Exception {
- String query =
- "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
- " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
- " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
- " GROUPING_ID(f1, f2) as gid " +
- " FROM " + TABLE_NAME +
- " GROUP BY GROUPING SETS (f1, f2)";
-
- String expected =
- "1,null,1,1,0,1,0,1,1\n" +
- "6,null,18,1,0,1,0,1,1\n" +
- "2,null,2,1,0,1,0,1,1\n" +
- "4,null,8,1,0,1,0,1,1\n" +
- "5,null,13,1,0,1,0,1,1\n" +
- "3,null,5,1,0,1,0,1,1\n" +
- "null,Comment#11,17,2,1,0,1,0,2\n" +
- "null,Comment#8,14,2,1,0,1,0,2\n" +
- "null,Comment#2,8,2,1,0,1,0,2\n" +
- "null,Comment#1,7,2,1,0,1,0,2\n" +
- "null,Comment#14,20,2,1,0,1,0,2\n" +
- "null,Comment#7,13,2,1,0,1,0,2\n" +
- "null,Comment#6,12,2,1,0,1,0,2\n" +
- "null,Comment#3,9,2,1,0,1,0,2\n" +
- "null,Comment#12,18,2,1,0,1,0,2\n" +
- "null,Comment#5,11,2,1,0,1,0,2\n" +
- "null,Comment#15,21,2,1,0,1,0,2\n" +
- "null,Comment#4,10,2,1,0,1,0,2\n" +
- "null,Hi,1,2,1,0,1,0,2\n" +
- "null,Comment#10,16,2,1,0,1,0,2\n" +
- "null,Hello world,3,2,1,0,1,0,2\n" +
- "null,I am fine.,5,2,1,0,1,0,2\n" +
- "null,Hello world, how are you?,4,2,1,0,1,0,2\n" +
- "null,Comment#9,15,2,1,0,1,0,2\n" +
- "null,Comment#13,19,2,1,0,1,0,2\n" +
- "null,Luke Skywalker,6,2,1,0,1,0,2\n" +
- "null,Hello,2,2,1,0,1,0,2";
-
- checkSql(query, expected);
- }
-
- @Test
- public void testGroupingSetsWithNulls() throws Exception {
- String query =
- "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g FROM " + TABLE_WITH_NULLS_NAME +
- " GROUP BY GROUPING SETS (f1, f2)";
-
- String expected =
- "6,null,18,1\n5,null,13,1\n4,null,8,1\n3,null,5,1\n2,null,2,1\n1,null,1,1\n" +
- "null,Luke Skywalker,6,2\nnull,I am fine.,5,2\nnull,Hi,1,2\n" +
- "null,null,3,2\nnull,Hello,2,2\nnull,Comment#9,15,2\nnull,Comment#8,14,2\n" +
- "null,Comment#7,13,2\nnull,Comment#6,12,2\nnull,Comment#5,11,2\n" +
- "null,Comment#4,10,2\nnull,Comment#3,9,2\nnull,Comment#2,8,2\n" +
- "null,Comment#15,21,2\nnull,Comment#14,20,2\nnull,Comment#13,19,2\n" +
- "null,Comment#12,18,2\nnull,Comment#11,17,2\nnull,Comment#10,16,2\n" +
- "null,Comment#1,7,2";
-
- checkSql(query, expected);
- }
-
- @Test
- public void testCubeAsGroupingSets() throws Exception {
- String cubeQuery =
- "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
- " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
- " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
- " GROUPING_ID(f1, f2) as gid " +
- " FROM " + TABLE_NAME + " GROUP BY CUBE (f1, f2)";
-
- String groupingSetsQuery =
- "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
- " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
- " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
- " GROUPING_ID(f1, f2) as gid " +
- " FROM " + TABLE_NAME +
- " GROUP BY GROUPING SETS ((f1, f2), (f1), (f2), ())";
-
- compareSql(cubeQuery, groupingSetsQuery);
- }
-
- @Test
- public void testRollupAsGroupingSets() throws Exception {
- String rollupQuery =
- "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
- " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
- " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
- " GROUPING_ID(f1, f2) as gid " +
- " FROM " + TABLE_NAME + " GROUP BY ROLLUP (f1, f2)";
-
- String groupingSetsQuery =
- "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
- " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
- " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
- " GROUPING_ID(f1, f2) as gid " +
- " FROM " + TABLE_NAME +
- " GROUP BY GROUPING SETS ((f1, f2), (f1), ())";
-
- compareSql(rollupQuery, groupingSetsQuery);
- }
-
- /**
- * Execute SQL query and check results.
- *
- * @param query SQL query.
- * @param expected Expected result.
- */
- private void checkSql(String query, String expected) throws Exception {
- Table resultTable = tableEnv.sql(query);
- DataSet<Row> resultDataSet = tableEnv.toDataSet(resultTable, Row.class);
- List<Row> results = resultDataSet.collect();
- TestBaseUtils.compareResultAsText(results, expected);
- }
-
- private void compareSql(String query1, String query2) throws Exception {
-
- // Function to map row to string
- MapFunction<Row, String> mapFunction = new MapFunction<Row, String>() {
-
- @Override
- public String map(Row value) throws Exception {
- return value == null ? "null" : value.toString();
- }
- };
-
- // Execute first query and store results
- Table resultTable1 = tableEnv.sql(query1);
- DataSet<Row> resultDataSet1 = tableEnv.toDataSet(resultTable1, Row.class);
- List<String> results1 = resultDataSet1.map(mapFunction).collect();
-
- // Execute second query and store results
- Table resultTable2 = tableEnv.sql(query2);
- DataSet<Row> resultDataSet2 = tableEnv.toDataSet(resultTable2, Row.class);
- List<String> results2 = resultDataSet2.map(mapFunction).collect();
-
- // Compare results
- TestBaseUtils.compareResultCollections(results1, results2, new Comparator<String>() {
-
- @Override
- public int compare(String o1, String o2) {
- return o2 == null ? o1 == null ? 0 : 1 : o1.compareTo(o2);
- }
- });
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/SqlITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/SqlITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/SqlITCase.java
deleted file mode 100644
index 6a72b3e..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/batch/sql/SqlITCase.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.batch.sql;
-
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.java.DataSet;
-import org.apache.flink.api.java.ExecutionEnvironment;
-import org.apache.flink.api.java.tuple.Tuple2;
-import org.apache.flink.api.java.tuple.Tuple3;
-import org.apache.flink.api.java.tuple.Tuple5;
-import org.apache.flink.api.java.typeutils.MapTypeInfo;
-import org.apache.flink.api.java.typeutils.TupleTypeInfo;
-import org.apache.flink.table.api.Table;
-import org.apache.flink.table.api.TableEnvironment;
-import org.apache.flink.table.api.java.BatchTableEnvironment;
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase;
-import org.apache.flink.test.operators.util.CollectionDataSets;
-import org.apache.flink.types.Row;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Integration tests for batch SQL.
- */
-@RunWith(Parameterized.class)
-public class SqlITCase extends TableProgramsCollectionTestBase {
-
- public SqlITCase(TableConfigMode configMode) {
- super(configMode);
- }
-
- @Test
- public void testValues() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- String sqlQuery = "VALUES (1, 'Test', TRUE, DATE '1944-02-24', 12.4444444444444445)," +
- "(2, 'Hello', TRUE, DATE '1944-02-24', 12.666666665)," +
- "(3, 'World', FALSE, DATE '1944-12-24', 12.54444445)";
- Table result = tableEnv.sql(sqlQuery);
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
-
- List<Row> results = resultSet.collect();
- String expected = "3,World,false,1944-12-24,12.5444444500000000\n" +
- "2,Hello,true,1944-02-24,12.6666666650000000\n" +
- // Calcite converts to decimals and strings with equal length
- "1,Test ,true,1944-02-24,12.4444444444444445\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testSelectFromTable() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- Table in = tableEnv.fromDataSet(ds, "a,b,c");
- tableEnv.registerTable("T", in);
-
- String sqlQuery = "SELECT a, c FROM T";
- Table result = tableEnv.sql(sqlQuery);
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "1,Hi\n" + "2,Hello\n" + "3,Hello world\n" +
- "4,Hello world, how are you?\n" + "5,I am fine.\n" + "6,Luke Skywalker\n" +
- "7,Comment#1\n" + "8,Comment#2\n" + "9,Comment#3\n" + "10,Comment#4\n" +
- "11,Comment#5\n" + "12,Comment#6\n" + "13,Comment#7\n" +
- "14,Comment#8\n" + "15,Comment#9\n" + "16,Comment#10\n" +
- "17,Comment#11\n" + "18,Comment#12\n" + "19,Comment#13\n" +
- "20,Comment#14\n" + "21,Comment#15\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testFilterFromDataSet() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- tableEnv.registerDataSet("DataSetTable", ds, "x, y, z");
-
- String sqlQuery = "SELECT x FROM DataSetTable WHERE z LIKE '%Hello%'";
- Table result = tableEnv.sql(sqlQuery);
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "2\n" + "3\n" + "4";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testAggregation() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
- tableEnv.registerDataSet("AggTable", ds, "x, y, z");
-
- String sqlQuery = "SELECT sum(x), min(x), max(x), count(y), avg(x) FROM AggTable";
- Table result = tableEnv.sql(sqlQuery);
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "231,1,21,21,11";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testJoin() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- DataSet<Tuple3<Integer, Long, String>> ds1 = CollectionDataSets.getSmall3TupleDataSet(env);
- DataSet<Tuple5<Integer, Long, Integer, String, Long>> ds2 = CollectionDataSets.get5TupleDataSet(env);
-
- tableEnv.registerDataSet("t1", ds1, "a, b, c");
- tableEnv.registerDataSet("t2", ds2, "d, e, f, g, h");
-
- String sqlQuery = "SELECT c, g FROM t1, t2 WHERE b = e";
- Table result = tableEnv.sql(sqlQuery);
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n";
- compareResultAsText(results, expected);
- }
-
- @Test
- public void testMap() throws Exception {
- ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
- BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
-
- List<Tuple2<Integer, Map<String, String>>> rows = new ArrayList<>();
- rows.add(new Tuple2<>(1, Collections.singletonMap("foo", "bar")));
- rows.add(new Tuple2<>(2, Collections.singletonMap("foo", "spam")));
-
- TypeInformation<Tuple2<Integer, Map<String, String>>> ty = new TupleTypeInfo<>(
- BasicTypeInfo.INT_TYPE_INFO,
- new MapTypeInfo<>(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO));
-
- DataSet<Tuple2<Integer, Map<String, String>>> ds1 = env.fromCollection(rows, ty);
- tableEnv.registerDataSet("t1", ds1, "a, b");
-
- String sqlQuery = "SELECT b['foo'] FROM t1";
- Table result = tableEnv.sql(sqlQuery);
-
- DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
- List<Row> results = resultSet.collect();
- String expected = "bar\n" + "spam\n";
- compareResultAsText(results, expected);
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java
deleted file mode 100644
index 68719b8d..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.stream.sql;
-
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.java.tuple.Tuple3;
-import org.apache.flink.api.java.tuple.Tuple5;
-import org.apache.flink.api.java.typeutils.RowTypeInfo;
-import org.apache.flink.streaming.api.datastream.DataStream;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase;
-import org.apache.flink.table.api.Table;
-import org.apache.flink.table.api.TableEnvironment;
-import org.apache.flink.table.api.java.StreamTableEnvironment;
-import org.apache.flink.table.api.java.stream.utils.StreamTestData;
-import org.apache.flink.table.runtime.datastream.StreamITCase;
-import org.apache.flink.types.Row;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-
-/**
- * Integration tests for streaming SQL.
- */
-public class SqlITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- public void testRowRegisterRowWithNames() throws Exception {
- StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
- StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
- StreamITCase.clear();
-
- List<Row> data = new ArrayList<>();
- data.add(Row.of(1, 1L, "Hi"));
- data.add(Row.of(2, 2L, "Hello"));
- data.add(Row.of(3, 2L, "Hello world"));
-
- TypeInformation<?>[] types = {
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.LONG_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO};
- String[] names = {"a", "b", "c"};
-
- RowTypeInfo typeInfo = new RowTypeInfo(types, names);
-
- DataStream<Row> ds = env.fromCollection(data).returns(typeInfo);
-
- Table in = tableEnv.fromDataStream(ds, "a,b,c");
- tableEnv.registerTable("MyTableRow", in);
-
- String sqlQuery = "SELECT a,c FROM MyTableRow";
- Table result = tableEnv.sql(sqlQuery);
-
- DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
- resultSet.addSink(new StreamITCase.StringSink<Row>());
- env.execute();
-
- List<String> expected = new ArrayList<>();
- expected.add("1,Hi");
- expected.add("2,Hello");
- expected.add("3,Hello world");
-
- StreamITCase.compareWithList(expected);
- }
-
- @Test
- public void testSelect() throws Exception {
- StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
- StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
- StreamITCase.clear();
-
- DataStream<Tuple3<Integer, Long, String>> ds = StreamTestData.getSmall3TupleDataSet(env);
- Table in = tableEnv.fromDataStream(ds, "a,b,c");
- tableEnv.registerTable("MyTable", in);
-
- String sqlQuery = "SELECT * FROM MyTable";
- Table result = tableEnv.sql(sqlQuery);
-
- DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
- resultSet.addSink(new StreamITCase.StringSink<Row>());
- env.execute();
-
- List<String> expected = new ArrayList<>();
- expected.add("1,1,Hi");
- expected.add("2,2,Hello");
- expected.add("3,2,Hello world");
-
- StreamITCase.compareWithList(expected);
- }
-
- @Test
- public void testFilter() throws Exception {
- StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
- StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
- StreamITCase.clear();
-
- DataStream<Tuple5<Integer, Long, Integer, String, Long>> ds = StreamTestData.get5TupleDataStream(env);
- tableEnv.registerDataStream("MyTable", ds, "a, b, c, d, e");
-
- String sqlQuery = "SELECT a, b, e FROM MyTable WHERE c < 4";
- Table result = tableEnv.sql(sqlQuery);
-
- DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
- resultSet.addSink(new StreamITCase.StringSink<Row>());
- env.execute();
-
- List<String> expected = new ArrayList<>();
- expected.add("1,1,1");
- expected.add("2,2,2");
- expected.add("2,3,1");
- expected.add("3,4,2");
-
- StreamITCase.compareWithList(expected);
- }
-
- @Test
- public void testUnion() throws Exception {
- StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
- StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
- StreamITCase.clear();
-
- DataStream<Tuple3<Integer, Long, String>> ds1 = StreamTestData.getSmall3TupleDataSet(env);
- Table t1 = tableEnv.fromDataStream(ds1, "a,b,c");
- tableEnv.registerTable("T1", t1);
-
- DataStream<Tuple5<Integer, Long, Integer, String, Long>> ds2 = StreamTestData.get5TupleDataStream(env);
- tableEnv.registerDataStream("T2", ds2, "a, b, d, c, e");
-
- String sqlQuery = "SELECT * FROM T1 " +
- "UNION ALL " +
- "(SELECT a, b, c FROM T2 WHERE a < 3)";
- Table result = tableEnv.sql(sqlQuery);
-
- DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
- resultSet.addSink(new StreamITCase.StringSink<Row>());
- env.execute();
-
- List<String> expected = new ArrayList<>();
- expected.add("1,1,Hi");
- expected.add("2,2,Hello");
- expected.add("3,2,Hello world");
- expected.add("1,1,Hallo");
- expected.add("2,2,Hallo Welt");
- expected.add("2,3,Hallo Welt wie");
-
- StreamITCase.compareWithList(expected);
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/utils/StreamTestData.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/utils/StreamTestData.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/utils/StreamTestData.java
deleted file mode 100644
index a23bc5a..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/utils/StreamTestData.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.stream.utils;
-
-import org.apache.flink.api.java.tuple.Tuple3;
-import org.apache.flink.api.java.tuple.Tuple5;
-import org.apache.flink.streaming.api.datastream.DataStream;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Test data.
- */
-public class StreamTestData {
-
- public static DataStream<Tuple3<Integer, Long, String>> getSmall3TupleDataSet(StreamExecutionEnvironment env) {
-
- List<Tuple3<Integer, Long, String>> data = new ArrayList<>();
- data.add(new Tuple3<>(1, 1L, "Hi"));
- data.add(new Tuple3<>(2, 2L, "Hello"));
- data.add(new Tuple3<>(3, 2L, "Hello world"));
-
- Collections.shuffle(data);
-
- return env.fromCollection(data);
- }
-
- public static DataStream<Tuple5<Integer, Long, Integer, String, Long>> get5TupleDataStream(StreamExecutionEnvironment env) {
-
- List<Tuple5<Integer, Long, Integer, String, Long>> data = new ArrayList<>();
- data.add(new Tuple5<>(1, 1L, 0, "Hallo", 1L));
- data.add(new Tuple5<>(2, 2L, 1, "Hallo Welt", 2L));
- data.add(new Tuple5<>(2, 3L, 2, "Hallo Welt wie", 1L));
- data.add(new Tuple5<>(3, 4L, 3, "Hallo Welt wie gehts?", 2L));
- data.add(new Tuple5<>(3, 5L, 4, "ABC", 2L));
- data.add(new Tuple5<>(3, 6L, 5, "BCD", 3L));
- data.add(new Tuple5<>(4, 7L, 6, "CDE", 2L));
- data.add(new Tuple5<>(4, 8L, 7, "DEF", 1L));
- data.add(new Tuple5<>(4, 9L, 8, "EFG", 1L));
- data.add(new Tuple5<>(4, 10L, 9, "FGH", 2L));
- data.add(new Tuple5<>(5, 11L, 10, "GHI", 1L));
- data.add(new Tuple5<>(5, 12L, 11, "HIJ", 3L));
- data.add(new Tuple5<>(5, 13L, 12, "IJK", 3L));
- data.add(new Tuple5<>(5, 15L, 14, "KLM", 2L));
- data.add(new Tuple5<>(5, 14L, 13, "JKL", 2L));
- return env.fromCollection(data);
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/Pojos.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/Pojos.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/Pojos.java
deleted file mode 100644
index 69b7890..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/Pojos.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.utils;
-
-import java.io.Serializable;
-import java.sql.Timestamp;
-
-/**
- * POJOs for Table API testing.
- */
-public class Pojos {
-
- /**
- * Pojo1 for test.
- */
- public static class Pojo1 implements Serializable {
-
- public Timestamp ts;
- public String msg;
-
- @Override
- public String toString() {
- return "Pojo1{" +
- "ts=" + ts +
- ", msg='" + msg + '\'' +
- '}';
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedAggFunctions.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedAggFunctions.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedAggFunctions.java
deleted file mode 100644
index a32d619..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedAggFunctions.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.utils;
-
-import org.apache.flink.api.java.tuple.Tuple2;
-import org.apache.flink.table.functions.AggregateFunction;
-
-import java.util.Iterator;
-
-/**
- * Test aggregator functions.
- */
-public class UserDefinedAggFunctions {
- /**
- * Accumulator for test requiresOver.
- */
- public static class Accumulator0 extends Tuple2<Long, Integer>{}
-
- /**
- * Test for requiresOver.
- */
- public static class OverAgg0 extends AggregateFunction<Long, Accumulator0> {
- @Override
- public Accumulator0 createAccumulator() {
- return new Accumulator0();
- }
-
- @Override
- public Long getValue(Accumulator0 accumulator) {
- return 1L;
- }
-
- //Overloaded accumulate method
- public void accumulate(Accumulator0 accumulator, long iValue, int iWeight) {
- }
-
- @Override
- public boolean requiresOver() {
- return true;
- }
- }
-
- /**
- * Accumulator for WeightedAvg.
- */
- public static class WeightedAvgAccum {
- public long sum = 0;
- public int count = 0;
- }
-
- /**
- * Base class for WeightedAvg.
- */
- public static class WeightedAvg extends AggregateFunction<Long, WeightedAvgAccum> {
- @Override
- public WeightedAvgAccum createAccumulator() {
- return new WeightedAvgAccum();
- }
-
- @Override
- public Long getValue(WeightedAvgAccum accumulator) {
- if (accumulator.count == 0) {
- return null;
- } else {
- return accumulator.sum / accumulator.count;
- }
- }
-
- // overloaded accumulate method
- public void accumulate(WeightedAvgAccum accumulator, long iValue, int iWeight) {
- accumulator.sum += iValue * iWeight;
- accumulator.count += iWeight;
- }
-
- //Overloaded accumulate method
- public void accumulate(WeightedAvgAccum accumulator, int iValue, int iWeight) {
- accumulator.sum += iValue * iWeight;
- accumulator.count += iWeight;
- }
- }
-
- /**
- * A WeightedAvg class with merge method.
- */
- public static class WeightedAvgWithMerge extends WeightedAvg {
- public void merge(WeightedAvgAccum acc, Iterable<WeightedAvgAccum> it) {
- Iterator<WeightedAvgAccum> iter = it.iterator();
- while (iter.hasNext()) {
- WeightedAvgAccum a = iter.next();
- acc.count += a.count;
- acc.sum += a.sum;
- }
- }
- }
-
- /**
- * A WeightedAvg class with merge and reset method.
- */
- public static class WeightedAvgWithMergeAndReset extends WeightedAvgWithMerge {
- public void resetAccumulator(WeightedAvgAccum acc) {
- acc.count = 0;
- acc.sum = 0L;
- }
- }
-
- /**
- * A WeightedAvg class with retract method.
- */
- public static class WeightedAvgWithRetract extends WeightedAvg {
- //Overloaded retract method
- public void retract(WeightedAvgAccum accumulator, long iValue, int iWeight) {
- accumulator.sum -= iValue * iWeight;
- accumulator.count -= iWeight;
- }
-
- //Overloaded retract method
- public void retract(WeightedAvgAccum accumulator, int iValue, int iWeight) {
- accumulator.sum -= iValue * iWeight;
- accumulator.count -= iWeight;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedScalarFunctions.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedScalarFunctions.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedScalarFunctions.java
deleted file mode 100644
index 214dbea..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedScalarFunctions.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.utils;
-
-import org.apache.flink.table.functions.ScalarFunction;
-
-import java.util.Arrays;
-
-/**
- * Test scalar functions.
- */
-public class UserDefinedScalarFunctions {
-
- /**
- * Increment input.
- */
- public static class JavaFunc0 extends ScalarFunction {
- public long eval(Long l) {
- return l + 1;
- }
- }
-
- /**
- * Concatenate inputs as strings.
- */
- public static class JavaFunc1 extends ScalarFunction {
- public String eval(Integer a, int b, Long c) {
- return a + " and " + b + " and " + c;
- }
- }
-
- /**
- * Append product to string.
- */
- public static class JavaFunc2 extends ScalarFunction {
- public String eval(String s, Integer... a) {
- int m = 1;
- for (int n : a) {
- m *= n;
- }
- return s + m;
- }
- }
-
- /**
- * Test overloading.
- */
- public static class JavaFunc3 extends ScalarFunction {
- public int eval(String a, int... b) {
- return b.length;
- }
-
- public String eval(String c) {
- return c;
- }
- }
-
- /**
- * Concatenate arrays as strings.
- */
- public static class JavaFunc4 extends ScalarFunction {
- public String eval(Integer[] a, String[] b) {
- return Arrays.toString(a) + " and " + Arrays.toString(b);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedTableFunctions.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedTableFunctions.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedTableFunctions.java
deleted file mode 100644
index 63c07ed..0000000
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/utils/UserDefinedTableFunctions.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.java.utils;
-
-import org.apache.flink.table.functions.TableFunction;
-
-/**
- * Test functions.
- */
-public class UserDefinedTableFunctions {
-
- /**
- * Emit inputs as long.
- */
- public static class JavaTableFunc0 extends TableFunction<Long> {
- public void eval(Integer a, Long b, Long c) {
- collect(a.longValue());
- collect(b);
- collect(c);
- }
- }
-}
[05/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala
new file mode 100644
index 0000000..408db25
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala
@@ -0,0 +1,379 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class AggregationsITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testAggregationTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1.sum, '_1.sum0, '_1.min, '_1.max, '_1.count, '_1.avg)
+
+ val results = t.toDataSet[Row].collect()
+ val expected = "231,231,1,21,21,11"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testWorkingAggregationDataTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ .select('_1.avg, '_2.avg, '_3.avg, '_4.avg, '_5.avg, '_6.avg, '_7.count)
+
+ val expected = "1,1,1,1,1.5,1.5,2"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements(
+ (1: Byte, 1: Short),
+ (2: Byte, 2: Short)).toTable(tEnv)
+ .select('_1.avg, '_1.sum, '_1.count, '_2.avg, '_2.sum)
+
+ val expected = "1,3,2,1,3"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationWithArithmetic(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ .select(('_1 + 2).avg + 2, '_2.count + 5)
+
+ val expected = "5.5,7"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationWithTwoCount(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ .select('_1.count, '_2.count)
+
+ val expected = "2,2"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationAfterProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .select('_1.avg, '_2.sum, '_3.count)
+
+ val expected = "1,3,2"
+ val result = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testSQLStyleAggregations(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select(
+ """Sum( a) as a1, a.sum as a2,
+ |Min (a) as b1, a.min as b2,
+ |Max (a ) as c1, a.max as c2,
+ |Avg ( a ) as d1, a.avg as d2,
+ |Count(a) as e1, a.count as e2
+ """.stripMargin)
+
+ val expected = "231,231,1,1,21,21,11,11,21,21"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testPojoAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val input = env.fromElements(
+ WC("hello", 1),
+ WC("hello", 1),
+ WC("ciao", 1),
+ WC("hola", 1),
+ WC("hola", 1))
+ val expr = input.toTable(tEnv)
+ val result = expr
+ .groupBy('word)
+ .select('word, 'frequency.sum as 'frequency)
+ .filter('frequency === 2)
+ .toDataSet[WC]
+
+ val mappedResult = result.map(w => (w.word, w.frequency * 10)).collect()
+ val expected = "(hello,20)\n" + "(hola,20)"
+ TestBaseUtils.compareResultAsText(mappedResult.asJava, expected)
+ }
+
+ @Test
+ def testDistinct(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val distinct = ds.select('b).distinct()
+
+ val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
+ val results = distinct.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDistinctAfterAggregate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val distinct = ds.groupBy('a, 'e).select('e).distinct()
+
+ val expected = "1\n" + "2\n" + "3\n"
+ val results = distinct.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val countFun = new CountAggFunction
+ val wAvgFun = new WeightedAvgWithMergeAndReset
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('b, 'a.sum, countFun('c), wAvgFun('b, 'a), wAvgFun('a, 'a))
+
+ val expected = "1,1,1,1,1\n" + "2,5,2,2,2\n" + "3,15,3,3,5\n" + "4,34,4,4,8\n" +
+ "5,65,5,5,13\n" + "6,111,6,6,18\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupingKeyForwardIfNotUsed(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('a.sum)
+
+ val expected = "1\n" + "5\n" + "15\n" + "34\n" + "65\n" + "111\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupNoAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('a.sum as 'd, 'b)
+ .groupBy('b, 'd)
+ .select('b)
+
+ val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithLongKeys(): Unit = {
+ // This uses very long keys to force serialized comparison.
+ // With short keys, the normalized key is sufficient.
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = env.fromElements(
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2))
+ .rebalance().setParallelism(2).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('a, 'b)
+ .select('c.sum)
+
+ val expected = "10\n" + "8\n"
+ val results = ds.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithConstant1(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a, 4 as 'four, 'b)
+ .groupBy('four, 'a)
+ .select('four, 'b.sum)
+
+ val expected = "4,2\n" + "4,3\n" + "4,5\n" + "4,5\n" + "4,5\n" + "4,6\n" +
+ "4,6\n" + "4,6\n" + "4,3\n" + "4,4\n" + "4,6\n" + "4,1\n" + "4,4\n" +
+ "4,4\n" + "4,5\n" + "4,6\n" + "4,2\n" + "4,3\n" + "4,4\n" + "4,5\n" + "4,6\n"
+ val results = t.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithConstant2(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('b, 4 as 'four, 'a)
+ .groupBy('b, 'four)
+ .select('four, 'a.sum)
+
+ val expected = "4,1\n" + "4,5\n" + "4,15\n" + "4,34\n" + "4,65\n" + "4,111\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithExpression(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .groupBy('e, 'b % 3)
+ .select('c.min, 'e, 'a.avg, 'd.count)
+
+ val expected = "0,1,1,1\n" + "3,2,3,3\n" + "7,1,4,2\n" + "14,2,5,1\n" +
+ "5,3,4,2\n" + "2,1,3,2\n" + "1,2,3,3\n" + "12,3,5,1"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('b, 'a.sum)
+ .where('b === 2)
+
+ val expected = "2,5\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAnalyticAggregation(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val ds = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, BigDecimal.ONE),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, new BigDecimal(2))).toTable(tEnv)
+ val res = ds.select(
+ '_1.stddevPop, '_2.stddevPop, '_3.stddevPop, '_4.stddevPop, '_5.stddevPop,
+ '_6.stddevPop, '_7.stddevPop,
+ '_1.stddevSamp, '_2.stddevSamp, '_3.stddevSamp, '_4.stddevSamp, '_5.stddevSamp,
+ '_6.stddevSamp, '_7.stddevSamp,
+ '_1.varPop, '_2.varPop, '_3.varPop, '_4.varPop, '_5.varPop,
+ '_6.varPop, '_7.varPop,
+ '_1.varSamp, '_2.varSamp, '_3.varSamp, '_4.varSamp, '_5.varSamp,
+ '_6.varSamp, '_7.varSamp)
+ val expected =
+ "0,0,0," +
+ "0,0.5,0.5,0.5," +
+ "1,1,1," +
+ "1,0.70710677,0.7071067811865476,0.7071067811865476," +
+ "0,0,0," +
+ "0,0.25,0.25,0.25," +
+ "1,1,1," +
+ "1,0.5,0.5,0.5"
+ val results = res.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
+
+case class WC(word: String, frequency: Long)
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala
new file mode 100644
index 0000000..72e74c4
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import java.sql.{Date, Time, Timestamp}
+import java.util
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class CalcITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSimpleSelectAll(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).select('_1, '_2, '_3)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectAllWithAs(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('a, 'b, 'c)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectWithNaming(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
+ .select('a, 'b)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
+ "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectRenameAll(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1 as 'a, '_2 as 'b, '_3 as 'c)
+ .select('a, 'b)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
+ "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectStar(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('*)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(false) )
+
+ val expected = "\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(true) )
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
+ "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
+ "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
+ "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
+ "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
+ "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnStringTupleField(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val filterDs = ds.filter( 'c.like("%world%") )
+
+ val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnIntegerTupleField(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 === 0 )
+
+ val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
+ "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
+ "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
+ "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testNotEquals(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 !== 0)
+ val expected = "1,1,Hi\n" + "3,2,Hello world\n" +
+ "5,3,I am fine.\n" + "7,4,Comment#1\n" + "9,4,Comment#3\n" +
+ "11,5,Comment#5\n" + "13,5,Comment#7\n" + "15,5,Comment#9\n" +
+ "17,6,Comment#11\n" + "19,6,Comment#13\n" + "21,6,Comment#15\n"
+ val results = filterDs.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDisjunctivePredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a < 2 || 'a > 20)
+ val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
+ val results = filterDs.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testConsecutiveFilters(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter('a % 2 !== 0).filter('b % 2 === 0)
+ val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
+ "9,4,Comment#3\n" + "17,6,Comment#11\n" +
+ "19,6,Comment#13\n" + "21,6,Comment#15\n"
+ val results = filterDs.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterBasicType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.getStringDataSet(env)
+
+ val filterDs = ds.toTable(tEnv, 'a).filter( 'a.like("H%") )
+
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hello world, how are you?\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnCustomType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.getCustomTypeDataSet(env)
+ val filterDs = ds.toTable(tEnv, 'myInt as 'i, 'myLong as 'l, 'myString as 's)
+ .filter( 's.like("%a%") )
+
+ val expected = "3,3,Hello world, how are you?\n" + "3,4,I am fine.\n" + "3,5,Luke Skywalker\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleCalc(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .where('_1 < 7)
+ .select('_1, '_3)
+
+ val expected = "1,Hi\n" + "2,Hello\n" + "3,Hello world\n" +
+ "4,Hello world, how are you?\n" + "5,I am fine.\n" + "6,Luke Skywalker\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCalcWithTwoFilters(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .where('_1 < 7 && '_2 === 3)
+ .select('_1, '_3)
+ .where('_1 === 4)
+ .select('_1)
+
+ val expected = "4\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCalcWithAggregation(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .where('_1 < 15)
+ .groupBy('_2)
+ .select('_1.min, '_2.count as 'cnt)
+ .where('cnt > 3)
+
+ val expected = "7,4\n" + "11,4\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCalcJoin(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.select('a, 'b).join(ds2).where('b === 'e).select('a, 'b, 'd, 'e, 'f)
+ .where('b > 1).select('a, 'd).where('d === 2)
+
+ val expected = "2,2\n" + "3,2\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAdvancedDataTypes(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env
+ .fromElements((
+ BigDecimal("78.454654654654654").bigDecimal,
+ BigDecimal("4E+9999").bigDecimal,
+ Date.valueOf("1984-07-12"),
+ Time.valueOf("14:34:24"),
+ Timestamp.valueOf("1984-07-12 14:34:24")))
+ .toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .select('a, 'b, 'c, 'd, 'e, BigDecimal("11.2"), BigDecimal("11.2").bigDecimal,
+ Date.valueOf("1984-07-12"), Time.valueOf("14:34:24"),
+ Timestamp.valueOf("1984-07-12 14:34:24"))
+
+ val expected = "78.454654654654654,4E+9999,1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
+ "11.2,11.2,1984-07-12,14:34:24,1984-07-12 14:34:24.0"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedScalarFunction() {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ tableEnv.registerFunction("hashCode", OldHashCode)
+ tableEnv.registerFunction("hashCode", HashCode)
+ val table = env.fromElements("a", "b", "c").toTable(tableEnv, 'text)
+ val result = table.select("text.hashCode()")
+ val results = result.toDataSet[Row].collect()
+ val expected = "97\n98\n99"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
+
+object CalcITCase {
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](
+ Array(TableProgramsTestBase.DEFAULT),
+ Array(TableProgramsTestBase.NO_NULL)).asJava
+ }
+}
+
+object HashCode extends ScalarFunction {
+ def eval(s: String): Int = s.hashCode
+}
+
+object OldHashCode extends ScalarFunction {
+ def eval(s: String): Int = -1
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala
new file mode 100644
index 0000000..dbc233b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.Types._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils.compareResultAsText
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class CastingITCase(configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testNumericAutocastInArithmetic() {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements(
+ (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d, 1L, 1001.1)).toTable(tableEnv)
+ .select('_1 + 1, '_2 + 1, '_3 + 1L, '_4 + 1.0f,
+ '_5 + 1.0d, '_6 + 1, '_7 + 1.0d, '_8 + '_1)
+
+ val results = table.toDataSet[Row].collect()
+ val expected = "2,2,2,2.0,2.0,2.0,2.0,1002.1"
+ compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ @throws[Exception]
+ def testNumericAutocastInComparison() {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements(
+ (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d),
+ (2.toByte, 2.toShort, 2, 2L, 2.0f, 2.0d))
+ .toTable(tableEnv, 'a, 'b, 'c, 'd, 'e, 'f)
+ .filter('a > 1 && 'b > 1 && 'c > 1L && 'd > 1.0f && 'e > 1.0d && 'f > 1)
+
+ val results = table.toDataSet[Row].collect()
+ val expected: String = "2,2,2,2,2.0,2.0"
+ compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ @throws[Exception]
+ def testCasting() {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val table = env.fromElements((1, 0.0, 1L, true)).toTable(tableEnv)
+ .select(
+ // * -> String
+ '_1.cast(STRING), '_2.cast(STRING), '_3.cast(STRING), '_4.cast(STRING),
+ // NUMERIC TYPE -> Boolean
+ '_1.cast(BOOLEAN), '_2.cast(BOOLEAN), '_3.cast(BOOLEAN),
+ // NUMERIC TYPE -> NUMERIC TYPE
+ '_1.cast(DOUBLE), '_2.cast(INT), '_3.cast(SHORT),
+ // Boolean -> NUMERIC TYPE
+ '_4.cast(DOUBLE),
+ // identity casting
+ '_1.cast(INT), '_2.cast(DOUBLE), '_3.cast(LONG), '_4.cast(BOOLEAN))
+
+ val results = table.toDataSet[Row].collect()
+ val expected = "1,0.0,1,true," + "true,false,true," +
+ "1.0,0,1," + "1.0," + "1,0.0,1,true\n"
+ compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ @throws[Exception]
+ def testCastFromString() {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val table = env.fromElements(("1", "true", "2.0")).toTable(tableEnv)
+ .select('_1.cast(BYTE), '_1.cast(SHORT), '_1.cast(INT), '_1.cast(LONG),
+ '_3.cast(DOUBLE), '_3.cast(FLOAT), '_2.cast(BOOLEAN))
+
+ val results = table.toDataSet[Row].collect()
+ val expected = "1,1,1,1,2.0,2.0,true\n"
+ compareResultAsText(results.asJava, expected)
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala
new file mode 100644
index 0000000..2350e8a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.expressions.utils.{RichFunc1, RichFunc2, RichFunc3}
+import org.apache.flink.table.utils._
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class DataSetCalcITCase(
+ mode: TestExecutionMode,
+ configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ @Test
+ def testUserDefinedScalarFunctionWithParameter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
+
+ val ds = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT c FROM t1 where RichFunc2(c)='ABC#Hello'"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedScalarFunctionWithDistributedCache(): Unit = {
+ val words = "Hello\nWord"
+ val filePath = UserDefinedFunctionTestUtils.writeCacheFile("test_words", words)
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ env.registerCachedFile(filePath, "words")
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc3", new RichFunc3)
+
+ val ds = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT c FROM t1 where RichFunc3(c)=true"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMultipleUserDefinedScalarFunctions(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc1", new RichFunc1)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
+
+ val ds = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT c FROM t1 where " +
+ "RichFunc2(c)='Abc#Hello' or RichFunc1(a)=3 and b=2"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello\nHello world"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala
new file mode 100644
index 0000000..611f521
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.runtime.dataset.table
+
+import java.sql.{Date, Timestamp}
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.java.utils.UserDefinedTableFunctions.JavaTableFunc0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.expressions.utils.{Func1, Func13, Func18, RichFunc2}
+import org.apache.flink.table.utils._
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+@RunWith(classOf[Parameterized])
+class DataSetUserDefinedFunctionITCase(
+ mode: TestExecutionMode,
+ configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val func1 = new TableFunc1
+ val result = in.join(func1('c) as 's).select('c, 's).toDataSet[Row]
+ val results = result.collect()
+ val expected = "Jack#22,Jack\n" + "Jack#22,22\n" + "John#19,John\n" + "John#19,19\n" +
+ "Anna#44,Anna\n" + "Anna#44,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+
+ // with overloading
+ val result2 = in.join(func1('c, "$") as 's).select('c, 's).toDataSet[Row]
+ val results2 = result2.collect()
+ val expected2 = "Jack#22,$Jack\n" + "Jack#22,$22\n" + "John#19,$John\n" +
+ "John#19,$19\n" + "Anna#44,$Anna\n" + "Anna#44,$44\n"
+ TestBaseUtils.compareResultAsText(results2.asJava, expected2)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val func2 = new TableFunc2
+ val result = in.leftOuterJoin(func2('c) as ('s, 'l)).select('c, 's, 'l).toDataSet[Row]
+ val results = result.collect()
+ val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
+ "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n" + "nosharp,null,null"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testWithFilter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = in
+ .join(func0('c) as ('name, 'age))
+ .select('c, 'name, 'age)
+ .filter('age > 20)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCustomReturnType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func2 = new TableFunc2
+
+ val result = in
+ .join(func2('c) as ('name, 'len))
+ .select('c, 'name, 'len)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
+ "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testHierarchyType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val hierarchy = new HierarchyTableFunction
+ val result = in
+ .join(hierarchy('c) as ('name, 'adult, 'len))
+ .select('c, 'name, 'adult, 'len)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,true,22\n" + "John#19,John,false,19\n" +
+ "Anna#44,Anna,true,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testPojoType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val pojo = new PojoTableFunc()
+ val result = in
+ .join(pojo('c))
+ .where('age > 20)
+ .select('c, 'name, 'age)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func1 = new TableFunc1
+
+ val result = in
+ .join(func1('c.substring(2)) as 's)
+ .select('c, 's)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,ack\n" + "Jack#22,22\n" + "John#19,ohn\n" + "John#19,19\n" +
+ "Anna#44,nna\n" + "Anna#44,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunctionInCondition(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = in
+ .join(func0('c))
+ .where(Func18('name, "J") && (Func1('a) < 3) && Func1('age) > 20)
+ .select('c, 'name, 'age)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,22"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLongAndTemporalTypes(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func0 = new JavaTableFunc0
+
+ val result = in
+ .where('a === 1)
+ .select(Date.valueOf("1990-10-14") as 'x,
+ 1000L as 'y,
+ Timestamp.valueOf("1990-10-14 12:10:10") as 'z)
+ .join(func0('x, 'y, 'z) as 's)
+ .select('s)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "1000\n" + "655906210000\n" + "7591\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithParameter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val richTableFunc1 = new RichTableFunc1
+ tEnv.registerFunction("RichTableFunc1", richTableFunc1)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> "#"))
+
+ val result = testData(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(richTableFunc1('c) as 's)
+ .select('a, 's)
+
+ val expected = "1,Jack\n" + "1,22\n" + "2,John\n" + "2,19\n" + "3,Anna\n" + "3,44"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunctionWithParameters(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val richTableFunc1 = new RichTableFunc1
+ tEnv.registerFunction("RichTableFunc1", richTableFunc1)
+ val richFunc2 = new RichFunc2
+ tEnv.registerFunction("RichFunc2", richFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(
+ env,
+ Map("word_separator" -> "#", "string.value" -> "test"))
+
+ val result = CollectionDataSets.getSmall3TupleDataSet(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(richTableFunc1(richFunc2('c)) as 's)
+ .select('a, 's)
+
+ val expected = "1,Hi\n1,test\n2,Hello\n2,test\n3,Hello world\n3,test"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableFunctionConstructorWithParams(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func30 = new TableFunc3(null)
+ val func31 = new TableFunc3("OneConf_")
+ val func32 = new TableFunc3("TwoConf_")
+
+ val result = in
+ .join(func30('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .join(func31('c) as ('f, 'g))
+ .select('c, 'd, 'e, 'f, 'g)
+ .join(func32('c) as ('h, 'i))
+ .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
+ .toDataSet[Row]
+
+ val results = result.collect()
+
+ val expected = "Anna#44,Anna,OneConf_Anna,TwoConf_Anna,44,44,44\n" +
+ "Jack#22,Jack,OneConf_Jack,TwoConf_Jack,22,22,22\n" +
+ "John#19,John,OneConf_John,TwoConf_John,19,19,19\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testScalarFunctionConstructorWithParams(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val func0 = new Func13("default")
+ val func1 = new Func13("Sunny")
+ val func2 = new Func13("kevin2")
+
+ val result = in.select(func0('c), func1('c),func2('c))
+
+ val results = result.collect()
+
+ val expected = "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44\n" +
+ "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22\n" +
+ "default-John#19,Sunny-John#19,kevin2-John#19\n" +
+ "default-nosharp,Sunny-nosharp,kevin2-nosharp"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableFunctionWithVariableArguments(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val varArgsFunc0 = new VarArgsFunc0
+ tableEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
+
+ val result = testData(env)
+ .toTable(tableEnv, 'a, 'b, 'c)
+ .select('c)
+ .join(varArgsFunc0("1", "2", 'c))
+
+ val expected = "Anna#44,1\n" +
+ "Anna#44,2\n" +
+ "Anna#44,Anna#44\n" +
+ "Jack#22,1\n" +
+ "Jack#22,2\n" +
+ "Jack#22,Jack#22\n" +
+ "John#19,1\n" +
+ "John#19,2\n" +
+ "John#19,John#19\n" +
+ "nosharp,1\n" +
+ "nosharp,2\n" +
+ "nosharp,nosharp"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+
+ // Test for empty cases
+ val result0 = testData(env)
+ .toTable(tableEnv, 'a, 'b, 'c)
+ .select('c)
+ .join(varArgsFunc0())
+ val results0 = result0.toDataSet[Row].collect()
+ assertTrue(results0.isEmpty)
+ }
+
+ private def testData(
+ env: ExecutionEnvironment)
+ : DataSet[(Int, Long, String)] = {
+
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Jack#22"))
+ data.+=((2, 2L, "John#19"))
+ data.+=((3, 2L, "Anna#44"))
+ data.+=((4, 3L, "nosharp"))
+ env.fromCollection(data)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala
new file mode 100644
index 0000000..e28acb8
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class DataSetWindowAggregateITCase(
+ mode: TestExecutionMode,
+ configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ val data = List(
+ (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
+ (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
+ (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
+ (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
+ (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
+ (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"),
+ (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"))
+
+ @Test(expected = classOf[UnsupportedOperationException])
+ def testAllEventTimeTumblingWindowOverCount(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ // Count tumbling non-grouping window on event-time are currently not supported
+ table
+ .window(Tumble over 2.rows on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+ .toDataSet[Row]
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverCount(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.sum, 'int.count, 'int.max, 'int.min, 'int.avg,
+ 'double.sum, 'double.count, 'double.max, 'double.min, 'double.avg,
+ 'float.sum, 'float.count, 'float.max, 'float.min, 'float.avg,
+ 'bigdec.sum, 'bigdec.count, 'bigdec.max, 'bigdec.min, 'bigdec.avg)
+
+ val expected = "Hello,7,2,5,2,3,7.0,2,5.0,2.0,3.5,7.0,2,5.0,2.0,3.5,7,2,5,2,3.5\n" +
+ "Hello world,7,2,4,3,3,7.0,2,4.0,3.0,3.5,7.0,2,4.0,3.0,3.5,7,2,4,3,3.5\n"
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.sum, 'w.start, 'w.end)
+
+ val expected = "Hello world,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
+ "Hello world,4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n" +
+ "Hello,7,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
+ "Hallo,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllEventTimeTumblingWindowOverTime(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.sum, 'w.start, 'w.end)
+
+ val expected = "10,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "6,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
+ "4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindow(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'string.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toDataSet[Row].collect()
+
+ val expected = "Hallo,1,1970-01-01 00:00:00.002,1970-01-01 00:00:00.009\n" +
+ "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.015\n" +
+ "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.023\n" +
+ "Hello,3,1970-01-01 00:00:00.003,1970-01-01 00:00:00.014\n" +
+ "Hi,1,1970-01-01 00:00:00.001,1970-01-01 00:00:00.008"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllEventTimeSessionGroupWindow(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val results =table
+ .window(Session withGap 2.milli on 'long as 'w)
+ .groupBy('w)
+ .select('string.count, 'w.start, 'w.end).toDataSet[Row].collect()
+
+ val expected = "4,1970-01-01 00:00:00.001,1970-01-01 00:00:00.006\n" +
+ "2,1970-01-01 00:00:00.007,1970-01-01 00:00:00.01\n" +
+ "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.018"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMultiGroupWindow(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ .window( Slide over 5.milli every 1.milli on 'int as 'w2)
+ .groupBy('w2)
+ .select('string)
+ .toDataSet[Row]
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Sliding windows
+ // ----------------------------------------------------------------------------------------------
+
+ @Test(expected = classOf[UnsupportedOperationException])
+ def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ // Count sliding group window on event-time are currently not supported
+ table
+ .window(Slide over 2.rows every 2.rows on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+ .toDataSet[Row]
+ }
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 2.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count, 'w.start, 'w.end)
+
+ val expected =
+ "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
+ "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
+ "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019\n" +
+ "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
+ "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003\n" +
+ "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011\n" +
+ "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007\n" +
+ "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
+ "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 10.milli every 5.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
+ "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
+ "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
+ "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02\n" +
+ "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025\n" +
+ "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
+ "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
+ "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
+ "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 4.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
+ "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
+ "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
+ "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 10.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 3.milli every 10.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala
new file mode 100644
index 0000000..9743bf6
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.utils.TableFunc2
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class JoinITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testJoin(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithFilter(): Unit = {
+
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e && 'b < 2).select('c, 'g)
+
+ val expected = "Hi,Hallo\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithJoinFilter(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e && 'a < 6).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e && 'a < 6 && 'h < 'b).select('c, 'g)
+
+ val results = joinT.toDataSet[Row].collect()
+ val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).filter('a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
+ "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithAggregation(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ // use different table env in order to let tmp table ids are the same
+ val tEnv2 = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('a === 'd).select('g.count)
+
+ val expected = "6"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithGroupedAggregation(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2)
+ .where('a === 'd)
+ .groupBy('a, 'd)
+ .select('b.sum, 'g.count)
+
+ val expected = "6,3\n" + "4,2\n" + "1,1"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinPushThroughJoin(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'j, 'k, 'l)
+
+ val joinT = ds1.join(ds2)
+ .where(Literal(true))
+ .join(ds3)
+ .where('a === 'd && 'e === 'k)
+ .select('a, 'f, 'l)
+
+ val expected = "2,1,Hello\n" + "2,1,Hello world\n" + "1,0,Hi"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithDisjunctivePred(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).filter('a === 'd && ('b === 'e || 'b === 'e - 10)).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" +
+ "Hello,Hallo Welt\n" +
+ "I am fine.,IJK"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithExpressionPreds(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).filter('b === 'h + 1 && 'a - 1 === 'd + 2).select('c, 'g)
+
+ val expected = "I am fine.,Hallo Welt\n" +
+ "Luke Skywalker,Hallo Welt wie gehts?\n" +
+ "Luke Skywalker,ABC\n" +
+ "Comment#2,HIJ\n" +
+ "Comment#2,IJK"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLeftJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.leftOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
+ "Hello world,ABC\n" + "Hello world, how are you?,null\n" + "I am fine.,HIJ\n" +
+ "I am fine.,IJK\n" + "Luke Skywalker,null\n" + "Comment#1,null\n" + "Comment#2,null\n" +
+ "Comment#3,null\n" + "Comment#4,null\n" + "Comment#5,null\n" + "Comment#6,null\n" +
+ "Comment#7,null\n" + "Comment#8,null\n" + "Comment#9,null\n" + "Comment#10,null\n" +
+ "Comment#11,null\n" + "Comment#12,null\n" + "Comment#13,null\n" + "Comment#14,null\n" +
+ "Comment#15,null\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.rightOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
+ "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
+ "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
+ "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFullOuterJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.fullOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
+ "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
+ "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
+ "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n" + "Luke Skywalker,null\n" +
+ "Comment#1,null\n" + "Comment#2,null\n" + "Comment#3,null\n" + "Comment#4,null\n" +
+ "Comment#5,null\n" + "Comment#6,null\n" + "Comment#7,null\n" + "Comment#8,null\n" +
+ "Comment#9,null\n" + "Comment#10,null\n" + "Comment#11,null\n" + "Comment#12,null\n" +
+ "Comment#13,null\n" + "Comment#14,null\n" + "Comment#15,null\n" +
+ "Hello world, how are you?,null\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUDTFJoinOnTuples(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List("hi#world", "how#are#you")
+
+ val ds1 = env.fromCollection(data).toTable(tEnv, 'a)
+ val func2 = new TableFunc2
+
+ val joinDs = ds1.join(func2('a) as ('name, 'len))
+
+ val results = joinDs.toDataSet[Row].collect()
+ val expected = Seq(
+ "hi#world,hi,2",
+ "hi#world,world,5",
+ "how#are#you,how,3",
+ "how#are#you,are,3",
+ "how#are#you,you,3").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+}
[12/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala
index 4837fcc..a377ca3 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/JoinValidationTest.scala
@@ -22,17 +22,17 @@ import org.apache.flink.api.scala._
import org.apache.flink.api.scala.util.CollectionDataSets
import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.{TableEnvironment, TableException, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
import org.junit._
-class JoinValidationTest {
+class JoinValidationTest extends TableTestBase {
@Test(expected = classOf[ValidationException])
def testJoinNonExistingKey(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
ds1.join(ds2)
// must fail. Field 'foo does not exist
@@ -42,11 +42,9 @@ class JoinValidationTest {
@Test(expected = classOf[ValidationException])
def testJoinWithNonMatchingKeyTypes(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
ds1.join(ds2)
// must fail. Field 'a is Int, and 'g is String
@@ -56,11 +54,9 @@ class JoinValidationTest {
@Test(expected = classOf[ValidationException])
def testJoinWithAmbiguousFields(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'c)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
ds1.join(ds2)
// must fail. Both inputs share the same field 'c
@@ -70,11 +66,9 @@ class JoinValidationTest {
@Test(expected = classOf[TableException])
def testNoEqualityJoinPredicate1(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
ds1.join(ds2)
// must fail. No equality join predicate
@@ -84,11 +78,9 @@ class JoinValidationTest {
@Test(expected = classOf[TableException])
def testNoEqualityJoinPredicate2(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
ds1.join(ds2)
// must fail. No equality join predicate
@@ -101,34 +93,29 @@ class JoinValidationTest {
val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
val tEnv1 = TableEnvironment.getTableEnvironment(env)
val tEnv2 = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv1, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv2, 'd, 'e, 'f, 'g, 'h)
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ val in1 = tEnv1.fromDataSet(ds1, 'a, 'b, 'c)
+ val in2 = tEnv2.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'c)
// Must fail. Tables are bound to different TableEnvironments.
- ds1.join(ds2).where('b === 'e).select('c, 'g)
+ in1.join(in2).where('b === 'e).select('c, 'g)
}
@Test(expected = classOf[ValidationException])
def testNoJoinCondition(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
ds2.leftOuterJoin(ds1, 'b === 'd && 'b < 3).select('c, 'g)
}
@Test(expected = classOf[ValidationException])
def testNoEquiJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
ds2.leftOuterJoin(ds1, 'b < 'd).select('c, 'g)
}
@@ -136,26 +123,21 @@ class JoinValidationTest {
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testJoinNonExistingKeyJava() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- val in1 = tableEnv.fromDataSet(ds1, 'a, 'b, 'c)
- val in2 = tableEnv.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'h)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'h)
+
// Must fail. Field foo does not exist.
- in1.join(in2).where("foo === e").select("c, g")
+ ds1.join(ds2).where("foo === e").select("c, g")
}
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testJoinWithNonMatchingKeyTypesJava() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- val in1 = tableEnv.fromDataSet(ds1, 'a, 'b, 'c)
- val in2 = tableEnv.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'c)
- in1.join(in2)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
+ ds1.join(ds2)
// Must fail. Types of join fields are not compatible (Integer and String)
.where("a === g").select("c, g")
}
@@ -163,14 +145,11 @@ class JoinValidationTest {
@Test(expected = classOf[ValidationException])
@throws[Exception]
def testJoinWithAmbiguousFieldsJava() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- val in1 = tableEnv.fromDataSet(ds1, 'a, 'b, 'c)
- val in2 = tableEnv.fromDataSet(ds2, 'd, 'e, 'f, 'g, 'c)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'd, 'e, 'f, 'g, 'c)
// Must fail. Join input have overlapping field names.
- in1.join(in2).where("a === d").select("c, g")
+ ds1.join(ds2).where("a === d").select("c, g")
}
@Test(expected = classOf[ValidationException])
@@ -185,4 +164,77 @@ class JoinValidationTest {
// Must fail. Tables are bound to different TableEnvironments.
in1.join(in2).where("a === d").select("g.count")
}
+
+ @Test(expected = classOf[ValidationException])
+ def testRightJoinWithNonEquiJoinPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testLeftJoinWithLocalPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFullJoinWithLocalPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testRightJoinWithLocalPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testLeftJoinWithNonEquiJoinPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFullJoinWithNonEquiJoinPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
+ }
+
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala
index baac9ea..c5586bf 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SetOperatorsValidationTest.scala
@@ -22,17 +22,16 @@ import org.apache.flink.api.scala._
import org.apache.flink.api.scala.util.CollectionDataSets
import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
import org.junit._
-class SetOperatorsValidationTest {
+class SetOperatorsValidationTest extends TableTestBase {
@Test(expected = classOf[ValidationException])
def testUnionDifferentColumnSize(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'd, 'c, 'e)
// must fail. Union inputs have different column size.
ds1.unionAll(ds2)
@@ -40,11 +39,9 @@ class SetOperatorsValidationTest {
@Test(expected = classOf[ValidationException])
def testUnionDifferentFieldTypes(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
.select('a, 'b, 'c)
// must fail. Union inputs have different field types.
@@ -66,11 +63,9 @@ class SetOperatorsValidationTest {
@Test(expected = classOf[ValidationException])
def testMinusDifferentFieldTypes(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
.select('a, 'b, 'c)
// must fail. Minus inputs have different field types.
@@ -92,11 +87,9 @@ class SetOperatorsValidationTest {
@Test(expected = classOf[ValidationException])
def testIntersectWithDifferentFieldTypes(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val util = batchTestUtil()
+ val ds1 = util.addTable[(Int, Long, String)]("Table3",'a, 'b, 'c)
+ val ds2 = util.addTable[(Int, Long, Int, String, Long)]("Table5", 'a, 'b, 'c, 'd, 'e)
.select('a, 'b, 'c)
// must fail. Intersect inputs have different field types.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala
index 4188f51..a82d4d6 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/validation/SortValidationTest.scala
@@ -18,30 +18,21 @@
package org.apache.flink.table.api.scala.batch.table.validation
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.api.scala.{ExecutionEnvironment, _}
+import org.apache.flink.table.utils.TableTestBase
import org.apache.flink.types.Row
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
import org.junit._
-class SortValidationTest {
-
- def getExecutionEnvironment = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(4)
- env
- }
+class SortValidationTest extends TableTestBase {
@Test(expected = classOf[ValidationException])
def testFetchWithoutOrder(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).limit(0, 5)
+ val util = batchTestUtil()
+ val ds = util.addTable[(Int, Long, String)]("Table3", 'a, 'b, 'c)
- t.toDataSet[Row].collect()
+ val t = ds.limit(0, 5).toDataSet[Row].collect()
}
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala
index 9313b5b..712b818 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/utils/TableProgramsClusterTestBase.scala
@@ -21,6 +21,7 @@ package org.apache.flink.table.api.scala.batch.utils
import java.util
import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.runtime.dataset.table.DataSetWindowAggregateITCase
import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
import org.junit.runners.Parameterized
@@ -29,7 +30,7 @@ import scala.collection.JavaConversions._
/**
* This test base provides full cluster-like integration tests for batch programs. Only runtime
* operator tests should use this test base as they are expensive.
- * (e.g. [[org.apache.flink.table.runtime.dataset.DataSetWindowAggregateITCase]])
+ * (e.g. [[DataSetWindowAggregateITCase]])
*/
class TableProgramsClusterTestBase(
executionMode: TestExecutionMode,
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala
new file mode 100644
index 0000000..030a415
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/validation/TableEnvironmentValidationTest.scala
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.validation
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo.{DOUBLE_TYPE_INFO, INT_TYPE_INFO, STRING_TYPE_INFO}
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.{GenericTypeInfo, RowTypeInfo, TupleTypeInfo, TypeExtractor}
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.api.scala.batch.{CClass, PojoClass}
+import org.apache.flink.table.api.{TableEnvironment, TableException}
+import org.apache.flink.table.expressions.{Alias, UnresolvedFieldReference}
+import org.apache.flink.table.runtime.types.CRowTypeInfo
+import org.apache.flink.types.Row
+import org.junit.Assert.assertTrue
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@RunWith(classOf[Parameterized])
+class TableEnvironmentValidationTest(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val tupleType = new TupleTypeInfo(
+ INT_TYPE_INFO,
+ STRING_TYPE_INFO,
+ DOUBLE_TYPE_INFO)
+
+ val rowType = new RowTypeInfo(INT_TYPE_INFO, STRING_TYPE_INFO,DOUBLE_TYPE_INFO)
+
+ val cRowType = new CRowTypeInfo(rowType)
+
+ val caseClassType: TypeInformation[CClass] = implicitly[TypeInformation[CClass]]
+
+ val pojoType: TypeInformation[PojoClass] = TypeExtractor.createTypeInfo(classOf[PojoClass])
+
+ val atomicType = INT_TYPE_INFO
+
+ val genericRowType = new GenericTypeInfo[Row](classOf[Row])
+
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoPojoNames1(): Unit = {
+ tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoAtomicName2(): Unit = {
+ tEnv.getFieldInfo(
+ atomicType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoTupleAlias3(): Unit = {
+ tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ Alias(UnresolvedFieldReference("xxx"), "name1"),
+ Alias(UnresolvedFieldReference("yyy"), "name2"),
+ Alias(UnresolvedFieldReference("zzz"), "name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoCClassAlias3(): Unit = {
+ tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ Alias(UnresolvedFieldReference("xxx"), "name1"),
+ Alias(UnresolvedFieldReference("yyy"), "name2"),
+ Alias(UnresolvedFieldReference("zzz"), "name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoPojoAlias3(): Unit = {
+ tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ Alias(UnresolvedFieldReference("xxx"), "name1"),
+ Alias(UnresolvedFieldReference("yyy"), "name2"),
+ Alias(UnresolvedFieldReference("zzz"), "name3")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoAtomicAlias(): Unit = {
+ tEnv.getFieldInfo(
+ atomicType,
+ Array(
+ Alias(UnresolvedFieldReference("name1"), "name2")
+ ))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGetFieldInfoGenericRowAlias(): Unit = {
+ tEnv.getFieldInfo(
+ genericRowType,
+ Array(UnresolvedFieldReference("first")))
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRegisterExistingDataSet(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds1)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ // Must fail. Name is already in use.
+ tEnv.registerDataSet("MyTable", ds2)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testScanUnregisteredTable(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ // Must fail. No table registered under that name.
+ tEnv.scan("someTable")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRegisterExistingTable(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", t1)
+ val t2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
+ // Must fail. Name is already in use.
+ tEnv.registerDataSet("MyTable", t2)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRegisterTableFromOtherEnv(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env, config)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env, config)
+
+ val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv1)
+ // Must fail. Table is bound to different TableEnvironment.
+ tEnv2.registerTable("MyTable", t1)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithToManyFields(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ CollectionDataSets.get3TupleDataSet(env)
+ // Must fail. Number of fields does not match.
+ .toTable(tEnv, 'a, 'b, 'c, 'd)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithAmbiguousFields(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ CollectionDataSets.get3TupleDataSet(env)
+ // Must fail. Field names not unique.
+ .toTable(tEnv, 'a, 'b, 'b)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithNonFieldReference1(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ // Must fail. as() can only have field references
+ CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a + 1, 'b, 'c)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testToTableWithNonFieldReference2(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ // Must fail. as() can only have field references
+ CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a as 'foo, 'b, 'c)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGenericRow() {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ // use null value the enforce GenericType
+ val dataSet = env.fromElements(Row.of(null))
+ assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
+ assertTrue(dataSet.getType().getTypeClass == classOf[Row])
+
+ // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
+ tableEnv.fromDataSet(dataSet)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testGenericRowWithAlias() {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ // use null value the enforce GenericType
+ val dataSet = env.fromElements(Row.of(null))
+ assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
+ assertTrue(dataSet.getType().getTypeClass == classOf[Row])
+
+ // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
+ tableEnv.fromDataSet(dataSet, "nullField")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/ExplainStreamTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/ExplainStreamTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/ExplainStreamTest.scala
deleted file mode 100644
index 7b168bb..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/ExplainStreamTest.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.junit.Assert.assertEquals
-import org.junit._
-
-class ExplainStreamTest
- extends StreamingMultipleProgramsTestBase {
-
- val testFilePath = ExplainStreamTest.this.getClass.getResource("/").getFile
-
- @Test
- def testFilter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements((1, "hello"))
- .toTable(tEnv, 'a, 'b)
- .filter("a % 2 = 0")
-
- val result = replaceString(tEnv.explain(table))
-
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testFilterStream0.out").mkString
- val expect = replaceString(source)
- assertEquals(result, expect)
- }
-
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table = table1.unionAll(table2)
-
- val result = replaceString(tEnv.explain(table))
-
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testUnionStream0.out").mkString
- val expect = replaceString(source)
- assertEquals(result, expect)
- }
-
- def replaceString(s: String): String = {
- /* Stage {id} is ignored, because id keeps incrementing in test class
- * while StreamExecutionEnvironment is up
- */
- s.replaceAll("\\r\\n", "\n").replaceAll("Stage \\d+", "")
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/RetractionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/RetractionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/RetractionITCase.scala
deleted file mode 100644
index 40f4c7d..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/RetractionITCase.scala
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream
-
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.table.utils.TableFunc0
-
-
-/**
- * tests for retraction
- */
-class RetractionITCase extends StreamingWithStateTestBase {
- // input data
- val data = List(
- ("Hello", 1),
- ("word", 1),
- ("Hello", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("bark", 1),
- ("flink", 1)
- )
-
- // keyed groupby + keyed groupby
- @Test
- def testWordCount(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .groupBy('word)
- .select('num.sum as 'count)
- .groupBy('count)
- .select('count, 'count.count as 'frequency)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = Seq("1,2", "2,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- // keyed groupby + non-keyed groupby
- @Test
- def testGroupByAndNonKeyedGroupBy(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .groupBy('word)
- .select('word as 'word, 'num.sum as 'cnt)
- .select('cnt.sum)
-
- val results = resultTable.toRetractStream[Row]
-
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = Seq("10")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- // non-keyed groupby + keyed groupby
- @Test
- def testNonKeyedGroupByAndGroupBy(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .select('num.sum as 'count)
- .groupBy('count)
- .select('count, 'count.count)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = Seq("10,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- // test unique process, if the current output message of unbounded groupby equals the
- // previous message, unbounded groupby will ignore the current one.
- @Test
- def testUniqueProcess(): Unit = {
- // data input
- val data = List(
- (1, 1L),
- (2, 2L),
- (3, 3L),
- (3, 3L),
- (4, 1L),
- (4, 0L),
- (4, 0L),
- (4, 0L),
- (5, 1L),
- (6, 6L),
- (6, 6L),
- (6, 6L),
- (7, 8L)
- )
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'pk, 'value)
- val resultTable = table
- .groupBy('pk)
- .select('pk as 'pk, 'value.sum as 'sum)
- .groupBy('sum)
- .select('sum, 'pk.count as 'count)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractMessagesSink)
- env.execute()
-
- val expected = Seq(
- "+1,1", "+2,1", "+3,1", "-3,1", "+6,1", "-1,1", "+1,2", "-1,2", "+1,3", "-6,1", "+6,2",
- "-6,2", "+6,1", "+12,1", "-12,1", "+18,1", "+8,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- // correlate should handle retraction messages correctly
- @Test
- def testCorrelate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
- env.setStateBackend(getStateBackend)
-
- val func0 = new TableFunc0
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'word, 'num)
- val resultTable = table
- .groupBy('word)
- .select('word as 'word, 'num.sum as 'cnt)
- .leftOuterJoin(func0('word))
- .groupBy('cnt)
- .select('cnt, 'word.count as 'frequency)
-
- val results = resultTable.toRetractStream[Row]
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = Seq("1,2", "2,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/StreamTableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/StreamTableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/StreamTableEnvironmentTest.scala
deleted file mode 100644
index 3c1668f..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/StreamTableEnvironmentTest.scala
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream
-
-import java.lang.{Integer => JInt, Long => JLong}
-
-import org.apache.flink.api.java.tuple.{Tuple5 => JTuple5}
-import org.apache.flink.api.java.typeutils.TupleTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.streaming.api.environment.{StreamExecutionEnvironment => JStreamExecEnv}
-import org.apache.flink.table.api.java.{StreamTableEnvironment => JStreamTableEnv}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableEnvironment, TableException, Types}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-import org.mockito.Mockito.{mock, when}
-
-class StreamTableEnvironmentTest extends TableTestBase {
-
- @Test(expected = classOf[TableException])
- def testInvalidTimeAttributes(): Unit = {
- val util = streamTestUtil()
- // table definition makes no sense
- util.addTable[(Long, Int, String, Int, Long)]('a.rowtime.rowtime, 'b, 'c, 'd, 'e)
- }
-
- @Test(expected = classOf[TableException])
- def testInvalidProctimeAttribute(): Unit = {
- val util = streamTestUtil()
- // cannot replace an attribute with proctime
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b.proctime, 'c, 'd, 'e)
- }
-
- @Test
- def testProctimeAttribute(): Unit = {
- val util = streamTestUtil()
- // cannot replace an attribute with proctime
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime)
- }
-
- @Test(expected = classOf[TableException])
- def testRowtimeAttributeReplaceFieldOfInvalidType(): Unit = {
- val util = streamTestUtil()
- // cannot replace a non-time attribute with rowtime
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c.rowtime, 'd, 'e)
- }
-
- @Test
- def testReplacedRowtimeAttribute(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e)
- }
-
- @Test
- def testAppendedRowtimeAttribute(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime)
- }
-
- @Test
- def testRowtimeAndProctimeAttribute1(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime, 'pt.proctime)
- }
-
- @Test
- def testRowtimeAndProctimeAttribute2(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime, 'rt.rowtime)
- }
-
- @Test
- def testRowtimeAndProctimeAttribute3(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e, 'pt.proctime)
- }
-
- @Test(expected = classOf[TableException])
- def testRowtimeAndInvalidProctimeAttribute(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'pt.proctime)
- }
-
- @Test(expected = classOf[TableException])
- def testOnlyOneRowtimeAttribute1(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a.rowtime, 'b, 'c, 'd, 'e, 'rt.rowtime)
- }
-
- @Test(expected = classOf[TableException])
- def testOnlyOneProctimeAttribute1(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt1.proctime, 'pt2.proctime)
- }
-
- @Test(expected = classOf[TableException])
- def testRowtimeAttributeUsedName(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'a.rowtime)
- }
-
- @Test(expected = classOf[TableException])
- def testProctimeAttributeUsedName(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'b.proctime)
- }
-
- @Test
- def testProctimeAttributeParsed(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime")
- }
-
- @Test
- def testReplacingRowtimeAttributeParsed(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a.rowtime, b, c, d, e")
- }
-
- @Test
- def testAppedingRowtimeAttributeParsed(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a, b, c, d, e, rt.rowtime")
- }
-
- @Test
- def testRowtimeAndProctimeAttributeParsed1(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime, rt.rowtime")
- }
-
- @Test
- def testRowtimeAndProctimeAttributeParsed2(): Unit = {
- val (jTEnv, ds) = prepareSchemaExpressionParser
- jTEnv.fromDataStream(ds, "rt.rowtime, b, c, d, e, pt.proctime")
- }
-
- private def prepareSchemaExpressionParser:
- (JStreamTableEnv, DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]) = {
-
- val jStreamExecEnv = mock(classOf[JStreamExecEnv])
- when(jStreamExecEnv.getStreamTimeCharacteristic).thenReturn(TimeCharacteristic.EventTime)
- val jTEnv = TableEnvironment.getTableEnvironment(jStreamExecEnv)
-
- val sType = new TupleTypeInfo(Types.LONG, Types.INT, Types.STRING, Types.INT, Types.LONG)
- .asInstanceOf[TupleTypeInfo[JTuple5[JLong, JInt, String, JInt, JLong]]]
- val ds = mock(classOf[DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]])
- when(ds.getType).thenReturn(sType)
-
- (jTEnv, ds)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala
new file mode 100644
index 0000000..ea09f32
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableEnvironmentTest.scala
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream
+
+import java.lang.{Integer => JInt, Long => JLong}
+
+import org.apache.flink.api.java.tuple.{Tuple5 => JTuple5}
+import org.apache.flink.api.java.typeutils.TupleTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.datastream.DataStream
+import org.apache.flink.streaming.api.environment.{StreamExecutionEnvironment => JStreamExecEnv}
+import org.apache.flink.table.api.java.{StreamTableEnvironment => JStreamTableEnv}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, Types}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+import org.mockito.Mockito.{mock, when}
+
+class TableEnvironmentTest extends TableTestBase {
+
+ @Test
+ def testProctimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ // cannot replace an attribute with proctime
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime)
+ }
+
+ @Test
+ def testReplacedRowtimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e)
+ }
+
+ @Test
+ def testAppendedRowtimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime)
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttribute1(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime, 'pt.proctime)
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttribute2(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime, 'rt.rowtime)
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttribute3(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e, 'pt.proctime)
+ }
+
+ @Test
+ def testProctimeAttributeParsed(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime")
+ }
+
+ @Test
+ def testReplacingRowtimeAttributeParsed(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a.rowtime, b, c, d, e")
+ }
+
+ @Test
+ def testAppedingRowtimeAttributeParsed(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a, b, c, d, e, rt.rowtime")
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttributeParsed1(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime, rt.rowtime")
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttributeParsed2(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "rt.rowtime, b, c, d, e, pt.proctime")
+ }
+
+ private def prepareSchemaExpressionParser:
+ (JStreamTableEnv, DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]) = {
+
+ val jStreamExecEnv = mock(classOf[JStreamExecEnv])
+ when(jStreamExecEnv.getStreamTimeCharacteristic).thenReturn(TimeCharacteristic.EventTime)
+ val jTEnv = TableEnvironment.getTableEnvironment(jStreamExecEnv)
+
+ val sType = new TupleTypeInfo(Types.LONG, Types.INT, Types.STRING, Types.INT, Types.LONG)
+ .asInstanceOf[TupleTypeInfo[JTuple5[JLong, JInt, String, JInt, JLong]]]
+ val ds = mock(classOf[DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]])
+ when(ds.getType).thenReturn(sType)
+
+ (jTEnv, ds)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala
new file mode 100644
index 0000000..1f976b7
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSchemaTest.scala
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Assert.{assertEquals, assertTrue}
+import org.junit.Test
+
+class TableSchemaTest extends TableTestBase {
+
+ @Test
+ def testStreamTableSchema(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
+ val schema = table.getSchema
+
+ assertEquals("a", schema.getColumnNames.apply(0))
+ assertEquals("b", schema.getColumnNames.apply(1))
+
+ assertEquals(Types.INT, schema.getTypes.apply(0))
+ assertEquals(Types.STRING, schema.getTypes.apply(1))
+
+ val expectedString = "root\n" +
+ " |-- a: Integer\n" +
+ " |-- b: String\n"
+ assertEquals(expectedString, schema.toString)
+
+ assertTrue(schema.getColumnName(3).isEmpty)
+ assertTrue(schema.getType(-1).isEmpty)
+ assertTrue(schema.getType("c").isEmpty)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSinkITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSinkITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSinkITCase.scala
deleted file mode 100644
index c446d64..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSinkITCase.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream
-
-import java.io.File
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.sinks.CsvTableSink
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit.Test
-
-class TableSinkITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testStreamTableSink(): Unit = {
-
- val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
- tmpFile.deleteOnExit()
- val path = tmpFile.toURI.toString
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setParallelism(4)
-
- val input = StreamTestData.get3TupleDataStream(env)
- .map(x => x).setParallelism(4) // increase DOP to 4
-
- val results = input.toTable(tEnv, 'a, 'b, 'c)
- .where('a < 5 || 'a > 17)
- .select('c, 'b)
- .writeToSink(new CsvTableSink(path))
-
- env.execute()
-
- val expected = Seq(
- "Hi,1", "Hello,2", "Hello world,2", "Hello world, how are you?,3",
- "Comment#12,6", "Comment#13,6", "Comment#14,6", "Comment#15,6").mkString("\n")
-
- TestBaseUtils.compareResultsByLinesInMemory(expected, path)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceITCase.scala
deleted file mode 100644
index a7037bb..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceITCase.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream
-
-import org.apache.flink.table.api.scala.stream.utils.StreamITCase
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.utils.{CommonTestData, TestFilterableTableSource}
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class TableSourceITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testCsvTableSourceSQL(): Unit = {
-
- val csvTable = CommonTestData.getCsvTableSource
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- tEnv.registerTableSource("persons", csvTable)
-
- tEnv.sql(
- "SELECT id, `first`, `last`, score FROM persons WHERE id < 4 ")
- .toAppendStream[Row]
- .addSink(new StreamITCase.StringSink[Row])
-
- env.execute()
-
- val expected = mutable.MutableList(
- "1,Mike,Smith,12.3",
- "2,Bob,Taylor,45.6",
- "3,Sam,Miller,7.89")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testCsvTableSourceTableAPI(): Unit = {
-
- val csvTable = CommonTestData.getCsvTableSource
- StreamITCase.testResults = mutable.MutableList()
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- tEnv.registerTableSource("csvTable", csvTable)
- tEnv.scan("csvTable")
- .where('id > 4)
- .select('last, 'score * 2)
- .toAppendStream[Row]
- .addSink(new StreamITCase.StringSink[Row])
-
- env.execute()
-
- val expected = mutable.MutableList(
- "Williams,69.0",
- "Miller,13.56",
- "Smith,180.2",
- "Williams,4.68")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testCsvTableSourceWithFilterable(): Unit = {
- StreamITCase.testResults = mutable.MutableList()
- val tableName = "MyTable"
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerTableSource(tableName, new TestFilterableTableSource)
- tEnv.scan(tableName)
- .where("amount > 4 && price < 9")
- .select("id, name")
- .addSink(new StreamITCase.StringSink[Row])
-
- env.execute()
-
- val expected = mutable.MutableList(
- "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceTest.scala
deleted file mode 100644
index 32961a6..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/TableSourceTest.scala
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment
-import org.apache.flink.table.api.{TableException, Types}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.sources.{DefinedProctimeAttribute, DefinedRowtimeAttribute, StreamTableSource}
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil.{term, unaryNode}
-import org.apache.flink.types.Row
-import org.junit.Test
-
-class TableSourceTest extends TableTestBase {
-
- @Test
- def testRowTimeTableSourceSimple(): Unit = {
- val util = streamTestUtil()
- util.tEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
-
- val t = util.tEnv.scan("rowTimeT").select("addTime, id, name, val")
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
- term("select", "TIME_MATERIALIZATION(addTime) AS addTime", "id", "name", "val")
- )
- util.verifyTable(t, expected)
- }
-
- @Test
- def testRowTimeTableSourceGroupWindow(): Unit = {
- val util = streamTestUtil()
- util.tEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
-
- val t = util.tEnv.scan("rowTimeT")
- .filter("val > 100")
- .window(Tumble over 10.minutes on 'addTime as 'w)
- .groupBy('name, 'w)
- .select('name, 'w.end, 'val.avg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
- term("select", "name", "val", "addTime"),
- term("where", ">(val, 100)")
- ),
- term("groupBy", "name"),
- term("window", "TumblingGroupWindow('w, 'addTime, 600000.millis)"),
- term("select", "name", "AVG(val) AS TMP_1", "end('w) AS TMP_0")
- ),
- term("select", "name", "TMP_0", "TMP_1")
- )
- util.verifyTable(t, expected)
- }
-
- @Test
- def testProcTimeTableSourceSimple(): Unit = {
- val util = streamTestUtil()
- util.tEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
-
- val t = util.tEnv.scan("procTimeT").select("pTime, id, name, val")
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
- term("select", "TIME_MATERIALIZATION(pTime) AS pTime", "id", "name", "val")
- )
- util.verifyTable(t, expected)
- }
-
- @Test
- def testProcTimeTableSourceOverWindow(): Unit = {
- val util = streamTestUtil()
- util.tEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
-
- val t = util.tEnv.scan("procTimeT")
- .window(Over partitionBy 'id orderBy 'pTime preceding 2.hours as 'w)
- .select('id, 'name, 'val.sum over 'w as 'valSum)
- .filter('valSum > 100)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
- term("partitionBy", "id"),
- term("orderBy", "pTime"),
- term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
- term("select", "id", "val", "name", "pTime", "SUM(val) AS w0$o0")
- ),
- term("select", "id", "name", "w0$o0 AS valSum"),
- term("where", ">(w0$o0, 100)")
- )
- util.verifyTable(t, expected)
- }
-
- @Test(expected = classOf[TableException])
- def testRowtimeTableSourceWithEmptyName(): Unit = {
- val util = streamTestUtil()
- util.tEnv.registerTableSource("rowTimeT", new TestRowtimeSource(" "))
-
- val t = util.tEnv.scan("rowTimeT")
- .select('id)
-
- util.tEnv.optimize(t.getRelNode, false)
- }
-
- @Test(expected = classOf[TableException])
- def testProctimeTableSourceWithEmptyName(): Unit = {
- val util = streamTestUtil()
- util.tEnv.registerTableSource("procTimeT", new TestProctimeSource(" "))
-
- val t = util.tEnv.scan("procTimeT")
- .select('id)
-
- util.tEnv.optimize(t.getRelNode, false)
- }
-}
-
-class TestRowtimeSource(timeField: String)
- extends StreamTableSource[Row] with DefinedRowtimeAttribute {
-
- override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
-
- override def getRowtimeAttribute: String = timeField
-
- override def getReturnType: TypeInformation[Row] = {
- new RowTypeInfo(
- Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
- Array("id", "val", "name"))
- }
-}
-
-class TestProctimeSource(timeField: String)
- extends StreamTableSource[Row] with DefinedProctimeAttribute {
-
- override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
-
- override def getProctimeAttribute: String = timeField
-
- override def getReturnType: TypeInformation[Row] = {
- new RowTypeInfo(
- Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
- Array("id", "val", "name"))
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/AggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/AggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/AggregationsTest.scala
deleted file mode 100644
index 4ab5cf6..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/AggregationsTest.scala
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.typeutils.CaseClassTypeInfo
-import org.apache.flink.table.api.{Types, ValidationException}
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil.{streamTableNode, term, unaryNode}
-import org.apache.flink.table.expressions.AggFunctionCall
-import org.apache.flink.table.functions.AggregateFunction
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert.{assertEquals, assertTrue}
-import org.junit.{Ignore, Test}
-
-class AggregationsTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c)
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- streamUtil.addFunction("overAgg", new OverAgg0)
-
- val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
-
- streamUtil.tEnv.sql(sqlQuery)
- }
-
- @Test
- def testDistinct(): Unit = {
- val sql = "SELECT DISTINCT a, b, c FROM MyTable"
-
- val expected =
- unaryNode(
- "DataStreamGroupAggregate",
- streamTableNode(0),
- term("groupBy", "a, b, c"),
- term("select", "a, b, c")
- )
- streamUtil.verifySql(sql, expected)
- }
-
- // TODO: this query should be optimized to only have a single DataStreamGroupAggregate
- // TODO: reopen this until FLINK-7144 fixed
- @Ignore
- @Test
- def testDistinctAfterAggregate(): Unit = {
- val sql = "SELECT DISTINCT a FROM MyTable GROUP BY a, b, c"
-
- val expected =
- unaryNode(
- "DataStreamGroupAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a")
- ),
- term("groupBy", "a"),
- term("select", "a")
- )
- streamUtil.verifySql(sql, expected)
- }
-
-
- @Test
- def testUserDefinedAggregateFunctionWithScalaAccumulator(): Unit = {
- streamUtil.addFunction("udag", new MyAgg)
- val call = streamUtil
- .tEnv
- .functionCatalog
- .lookupFunction("udag", Seq())
- .asInstanceOf[AggFunctionCall]
-
- val typeInfo = call.accTypeInfo
- assertTrue(typeInfo.isInstanceOf[CaseClassTypeInfo[_]])
- assertEquals(2, typeInfo.getTotalFields)
- val caseTypeInfo = typeInfo.asInstanceOf[CaseClassTypeInfo[_]]
- assertEquals(Types.LONG, caseTypeInfo.getTypeAt(0))
- assertEquals(Types.LONG, caseTypeInfo.getTypeAt(1))
-
- streamUtil.addFunction("udag2", new MyAgg2)
- val call2 = streamUtil
- .tEnv
- .functionCatalog
- .lookupFunction("udag2", Seq())
- .asInstanceOf[AggFunctionCall]
-
- val typeInfo2 = call2.accTypeInfo
- assertTrue(s"actual type: $typeInfo2", typeInfo2.isInstanceOf[RowTypeInfo])
- assertEquals(2, typeInfo2.getTotalFields)
- val rowTypeInfo = typeInfo2.asInstanceOf[RowTypeInfo]
- assertEquals(Types.LONG, rowTypeInfo.getTypeAt(0))
- assertEquals(Types.INT, rowTypeInfo.getTypeAt(1))
- }
-}
-
-case class MyAccumulator(var sum: Long, var count: Long)
-
-class MyAgg extends AggregateFunction[Long, MyAccumulator] {
-
- //Overloaded accumulate method
- def accumulate(acc: MyAccumulator, value: Long): Unit = {
- }
-
- override def createAccumulator(): MyAccumulator = MyAccumulator(0, 0)
-
- override def getValue(accumulator: MyAccumulator): Long = 1L
-}
-
-class MyAgg2 extends AggregateFunction[Long, Row] {
-
- def accumulate(acc: Row, value: Long): Unit = {}
-
- override def createAccumulator(): Row = new Row(2)
-
- override def getValue(accumulator: Row): Long = 1L
-
- def getAccumulatorType: TypeInformation[_] = new RowTypeInfo(Types.LONG, Types.INT)
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala
new file mode 100644
index 0000000..af9ce74
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/ExpressionReductionTest.scala
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ )
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "*" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+}
[24/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala
deleted file mode 100644
index 408db25..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/AggregationsITCase.scala
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class AggregationsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testAggregationTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1.sum, '_1.sum0, '_1.min, '_1.max, '_1.count, '_1.avg)
-
- val results = t.toDataSet[Row].collect()
- val expected = "231,231,1,21,21,11"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testWorkingAggregationDataTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
- .select('_1.avg, '_2.avg, '_3.avg, '_4.avg, '_5.avg, '_6.avg, '_7.count)
-
- val expected = "1,1,1,1,1.5,1.5,2"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements(
- (1: Byte, 1: Short),
- (2: Byte, 2: Short)).toTable(tEnv)
- .select('_1.avg, '_1.sum, '_1.count, '_2.avg, '_2.sum)
-
- val expected = "1,3,2,1,3"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationWithArithmetic(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
- .select(('_1 + 2).avg + 2, '_2.count + 5)
-
- val expected = "5.5,7"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationWithTwoCount(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
- .select('_1.count, '_2.count)
-
- val expected = "2,2"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationAfterProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
- .select('_1, '_2, '_3)
- .select('_1.avg, '_2.sum, '_3.count)
-
- val expected = "1,3,2"
- val result = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testSQLStyleAggregations(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select(
- """Sum( a) as a1, a.sum as a2,
- |Min (a) as b1, a.min as b2,
- |Max (a ) as c1, a.max as c2,
- |Avg ( a ) as d1, a.avg as d2,
- |Count(a) as e1, a.count as e2
- """.stripMargin)
-
- val expected = "231,231,1,1,21,21,11,11,21,21"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testPojoAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val input = env.fromElements(
- WC("hello", 1),
- WC("hello", 1),
- WC("ciao", 1),
- WC("hola", 1),
- WC("hola", 1))
- val expr = input.toTable(tEnv)
- val result = expr
- .groupBy('word)
- .select('word, 'frequency.sum as 'frequency)
- .filter('frequency === 2)
- .toDataSet[WC]
-
- val mappedResult = result.map(w => (w.word, w.frequency * 10)).collect()
- val expected = "(hello,20)\n" + "(hola,20)"
- TestBaseUtils.compareResultAsText(mappedResult.asJava, expected)
- }
-
- @Test
- def testDistinct(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val distinct = ds.select('b).distinct()
-
- val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
- val results = distinct.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDistinctAfterAggregate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- val distinct = ds.groupBy('a, 'e).select('e).distinct()
-
- val expected = "1\n" + "2\n" + "3\n"
- val results = distinct.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val countFun = new CountAggFunction
- val wAvgFun = new WeightedAvgWithMergeAndReset
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('b, 'a.sum, countFun('c), wAvgFun('b, 'a), wAvgFun('a, 'a))
-
- val expected = "1,1,1,1,1\n" + "2,5,2,2,2\n" + "3,15,3,3,5\n" + "4,34,4,4,8\n" +
- "5,65,5,5,13\n" + "6,111,6,6,18\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupingKeyForwardIfNotUsed(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('a.sum)
-
- val expected = "1\n" + "5\n" + "15\n" + "34\n" + "65\n" + "111\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupNoAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('a.sum as 'd, 'b)
- .groupBy('b, 'd)
- .select('b)
-
- val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithLongKeys(): Unit = {
- // This uses very long keys to force serialized comparison.
- // With short keys, the normalized key is sufficient.
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = env.fromElements(
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
- ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2))
- .rebalance().setParallelism(2).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('a, 'b)
- .select('c.sum)
-
- val expected = "10\n" + "8\n"
- val results = ds.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithConstant1(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a, 4 as 'four, 'b)
- .groupBy('four, 'a)
- .select('four, 'b.sum)
-
- val expected = "4,2\n" + "4,3\n" + "4,5\n" + "4,5\n" + "4,5\n" + "4,6\n" +
- "4,6\n" + "4,6\n" + "4,3\n" + "4,4\n" + "4,6\n" + "4,1\n" + "4,4\n" +
- "4,4\n" + "4,5\n" + "4,6\n" + "4,2\n" + "4,3\n" + "4,4\n" + "4,5\n" + "4,6\n"
- val results = t.toDataSet[Row].collect()
-
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithConstant2(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('b, 4 as 'four, 'a)
- .groupBy('b, 'four)
- .select('four, 'a.sum)
-
- val expected = "4,1\n" + "4,5\n" + "4,15\n" + "4,34\n" + "4,65\n" + "4,111\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithExpression(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .groupBy('e, 'b % 3)
- .select('c.min, 'e, 'a.avg, 'd.count)
-
- val expected = "0,1,1,1\n" + "3,2,3,3\n" + "7,1,4,2\n" + "14,2,5,1\n" +
- "5,3,4,2\n" + "2,1,3,2\n" + "1,2,3,3\n" + "12,3,5,1"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedAggregateWithFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('b, 'a.sum)
- .where('b === 2)
-
- val expected = "2,5\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAnalyticAggregation(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val ds = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, BigDecimal.ONE),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, new BigDecimal(2))).toTable(tEnv)
- val res = ds.select(
- '_1.stddevPop, '_2.stddevPop, '_3.stddevPop, '_4.stddevPop, '_5.stddevPop,
- '_6.stddevPop, '_7.stddevPop,
- '_1.stddevSamp, '_2.stddevSamp, '_3.stddevSamp, '_4.stddevSamp, '_5.stddevSamp,
- '_6.stddevSamp, '_7.stddevSamp,
- '_1.varPop, '_2.varPop, '_3.varPop, '_4.varPop, '_5.varPop,
- '_6.varPop, '_7.varPop,
- '_1.varSamp, '_2.varSamp, '_3.varSamp, '_4.varSamp, '_5.varSamp,
- '_6.varSamp, '_7.varSamp)
- val expected =
- "0,0,0," +
- "0,0.5,0.5,0.5," +
- "1,1,1," +
- "1,0.70710677,0.7071067811865476,0.7071067811865476," +
- "0,0,0," +
- "0,0.25,0.25,0.25," +
- "1,1,1," +
- "1,0.5,0.5,0.5"
- val results = res.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
-
-case class WC(word: String, frequency: Long)
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala
deleted file mode 100644
index 72e74c4..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CalcITCase.scala
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import java.sql.{Date, Time, Timestamp}
-import java.util
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class CalcITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSimpleSelectAll(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).select('_1, '_2, '_3)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectAllWithAs(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('a, 'b, 'c)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectWithNaming(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
- .select('a, 'b)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
- "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectRenameAll(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1 as 'a, '_2 as 'b, '_3 as 'c)
- .select('a, 'b)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
- "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectStar(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('*)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(false) )
-
- val expected = "\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(true) )
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
- "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
- "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
- "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
- "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
- "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnStringTupleField(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val filterDs = ds.filter( 'c.like("%world%") )
-
- val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnIntegerTupleField(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 === 0 )
-
- val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
- "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
- "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
- "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testNotEquals(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 !== 0)
- val expected = "1,1,Hi\n" + "3,2,Hello world\n" +
- "5,3,I am fine.\n" + "7,4,Comment#1\n" + "9,4,Comment#3\n" +
- "11,5,Comment#5\n" + "13,5,Comment#7\n" + "15,5,Comment#9\n" +
- "17,6,Comment#11\n" + "19,6,Comment#13\n" + "21,6,Comment#15\n"
- val results = filterDs.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDisjunctivePredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a < 2 || 'a > 20)
- val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
- val results = filterDs.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testConsecutiveFilters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter('a % 2 !== 0).filter('b % 2 === 0)
- val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
- "9,4,Comment#3\n" + "17,6,Comment#11\n" +
- "19,6,Comment#13\n" + "21,6,Comment#15\n"
- val results = filterDs.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterBasicType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.getStringDataSet(env)
-
- val filterDs = ds.toTable(tEnv, 'a).filter( 'a.like("H%") )
-
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hello world, how are you?\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnCustomType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.getCustomTypeDataSet(env)
- val filterDs = ds.toTable(tEnv, 'myInt as 'i, 'myLong as 'l, 'myString as 's)
- .filter( 's.like("%a%") )
-
- val expected = "3,3,Hello world, how are you?\n" + "3,4,I am fine.\n" + "3,5,Luke Skywalker\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleCalc(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1, '_2, '_3)
- .where('_1 < 7)
- .select('_1, '_3)
-
- val expected = "1,Hi\n" + "2,Hello\n" + "3,Hello world\n" +
- "4,Hello world, how are you?\n" + "5,I am fine.\n" + "6,Luke Skywalker\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCalcWithTwoFilters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1, '_2, '_3)
- .where('_1 < 7 && '_2 === 3)
- .select('_1, '_3)
- .where('_1 === 4)
- .select('_1)
-
- val expected = "4\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCalcWithAggregation(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1, '_2, '_3)
- .where('_1 < 15)
- .groupBy('_2)
- .select('_1.min, '_2.count as 'cnt)
- .where('cnt > 3)
-
- val expected = "7,4\n" + "11,4\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCalcJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.select('a, 'b).join(ds2).where('b === 'e).select('a, 'b, 'd, 'e, 'f)
- .where('b > 1).select('a, 'd).where('d === 2)
-
- val expected = "2,2\n" + "3,2\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAdvancedDataTypes(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env
- .fromElements((
- BigDecimal("78.454654654654654").bigDecimal,
- BigDecimal("4E+9999").bigDecimal,
- Date.valueOf("1984-07-12"),
- Time.valueOf("14:34:24"),
- Timestamp.valueOf("1984-07-12 14:34:24")))
- .toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .select('a, 'b, 'c, 'd, 'e, BigDecimal("11.2"), BigDecimal("11.2").bigDecimal,
- Date.valueOf("1984-07-12"), Time.valueOf("14:34:24"),
- Timestamp.valueOf("1984-07-12 14:34:24"))
-
- val expected = "78.454654654654654,4E+9999,1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
- "11.2,11.2,1984-07-12,14:34:24,1984-07-12 14:34:24.0"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedScalarFunction() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- tableEnv.registerFunction("hashCode", OldHashCode)
- tableEnv.registerFunction("hashCode", HashCode)
- val table = env.fromElements("a", "b", "c").toTable(tableEnv, 'text)
- val result = table.select("text.hashCode()")
- val results = result.toDataSet[Row].collect()
- val expected = "97\n98\n99"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
-
-object CalcITCase {
-
- @Parameterized.Parameters(name = "Table config = {0}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](
- Array(TableProgramsTestBase.DEFAULT),
- Array(TableProgramsTestBase.NO_NULL)).asJava
- }
-}
-
-object HashCode extends ScalarFunction {
- def eval(s: String): Int = s.hashCode
-}
-
-object OldHashCode extends ScalarFunction {
- def eval(s: String): Int = -1
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala
deleted file mode 100644
index dbc233b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/CastingITCase.scala
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.Types._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.TestBaseUtils.compareResultAsText
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class CastingITCase(configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testNumericAutocastInArithmetic() {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements(
- (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d, 1L, 1001.1)).toTable(tableEnv)
- .select('_1 + 1, '_2 + 1, '_3 + 1L, '_4 + 1.0f,
- '_5 + 1.0d, '_6 + 1, '_7 + 1.0d, '_8 + '_1)
-
- val results = table.toDataSet[Row].collect()
- val expected = "2,2,2,2.0,2.0,2.0,2.0,1002.1"
- compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @throws[Exception]
- def testNumericAutocastInComparison() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements(
- (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d),
- (2.toByte, 2.toShort, 2, 2L, 2.0f, 2.0d))
- .toTable(tableEnv, 'a, 'b, 'c, 'd, 'e, 'f)
- .filter('a > 1 && 'b > 1 && 'c > 1L && 'd > 1.0f && 'e > 1.0d && 'f > 1)
-
- val results = table.toDataSet[Row].collect()
- val expected: String = "2,2,2,2,2.0,2.0"
- compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @throws[Exception]
- def testCasting() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements((1, 0.0, 1L, true)).toTable(tableEnv)
- .select(
- // * -> String
- '_1.cast(STRING), '_2.cast(STRING), '_3.cast(STRING), '_4.cast(STRING),
- // NUMERIC TYPE -> Boolean
- '_1.cast(BOOLEAN), '_2.cast(BOOLEAN), '_3.cast(BOOLEAN),
- // NUMERIC TYPE -> NUMERIC TYPE
- '_1.cast(DOUBLE), '_2.cast(INT), '_3.cast(SHORT),
- // Boolean -> NUMERIC TYPE
- '_4.cast(DOUBLE),
- // identity casting
- '_1.cast(INT), '_2.cast(DOUBLE), '_3.cast(LONG), '_4.cast(BOOLEAN))
-
- val results = table.toDataSet[Row].collect()
- val expected = "1,0.0,1,true," + "true,false,true," +
- "1.0,0,1," + "1.0," + "1,0.0,1,true\n"
- compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @throws[Exception]
- def testCastFromString() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements(("1", "true", "2.0")).toTable(tableEnv)
- .select('_1.cast(BYTE), '_1.cast(SHORT), '_1.cast(INT), '_1.cast(LONG),
- '_3.cast(DOUBLE), '_3.cast(FLOAT), '_2.cast(BOOLEAN))
-
- val results = table.toDataSet[Row].collect()
- val expected = "1,1,1,1,2.0,2.0,true\n"
- compareResultAsText(results.asJava, expected)
- }
-}
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala
deleted file mode 100644
index 2350e8a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetCalcITCase.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.expressions.utils.{RichFunc1, RichFunc2, RichFunc3}
-import org.apache.flink.table.utils._
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class DataSetCalcITCase(
- mode: TestExecutionMode,
- configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- @Test
- def testUserDefinedScalarFunctionWithParameter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
-
- val ds = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT c FROM t1 where RichFunc2(c)='ABC#Hello'"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedScalarFunctionWithDistributedCache(): Unit = {
- val words = "Hello\nWord"
- val filePath = UserDefinedFunctionTestUtils.writeCacheFile("test_words", words)
- val env = ExecutionEnvironment.getExecutionEnvironment
- env.registerCachedFile(filePath, "words")
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc3", new RichFunc3)
-
- val ds = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT c FROM t1 where RichFunc3(c)=true"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMultipleUserDefinedScalarFunctions(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- tEnv.registerFunction("RichFunc1", new RichFunc1)
- tEnv.registerFunction("RichFunc2", new RichFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
-
- val ds = CollectionDataSets.getSmall3TupleDataSet(env)
- tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT c FROM t1 where " +
- "RichFunc2(c)='Abc#Hello' or RichFunc1(a)=3 and b=2"
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "Hello\nHello world"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala
deleted file mode 100644
index 611f521..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetUserDefinedFunctionITCase.scala
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.runtime.dataset.table
-
-import java.sql.{Date, Timestamp}
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.java.utils.UserDefinedTableFunctions.JavaTableFunc0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.expressions.utils.{Func1, Func13, Func18, RichFunc2}
-import org.apache.flink.table.utils._
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-@RunWith(classOf[Parameterized])
-class DataSetUserDefinedFunctionITCase(
- mode: TestExecutionMode,
- configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- @Test
- def testCrossJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val func1 = new TableFunc1
- val result = in.join(func1('c) as 's).select('c, 's).toDataSet[Row]
- val results = result.collect()
- val expected = "Jack#22,Jack\n" + "Jack#22,22\n" + "John#19,John\n" + "John#19,19\n" +
- "Anna#44,Anna\n" + "Anna#44,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
-
- // with overloading
- val result2 = in.join(func1('c, "$") as 's).select('c, 's).toDataSet[Row]
- val results2 = result2.collect()
- val expected2 = "Jack#22,$Jack\n" + "Jack#22,$22\n" + "John#19,$John\n" +
- "John#19,$19\n" + "Anna#44,$Anna\n" + "Anna#44,$44\n"
- TestBaseUtils.compareResultAsText(results2.asJava, expected2)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val func2 = new TableFunc2
- val result = in.leftOuterJoin(func2('c) as ('s, 'l)).select('c, 's, 'l).toDataSet[Row]
- val results = result.collect()
- val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
- "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n" + "nosharp,null,null"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testWithFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = in
- .join(func0('c) as ('name, 'age))
- .select('c, 'name, 'age)
- .filter('age > 20)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCustomReturnType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func2 = new TableFunc2
-
- val result = in
- .join(func2('c) as ('name, 'len))
- .select('c, 'name, 'len)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
- "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testHierarchyType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val hierarchy = new HierarchyTableFunction
- val result = in
- .join(hierarchy('c) as ('name, 'adult, 'len))
- .select('c, 'name, 'adult, 'len)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,true,22\n" + "John#19,John,false,19\n" +
- "Anna#44,Anna,true,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testPojoType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val pojo = new PojoTableFunc()
- val result = in
- .join(pojo('c))
- .where('age > 20)
- .select('c, 'name, 'age)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func1 = new TableFunc1
-
- val result = in
- .join(func1('c.substring(2)) as 's)
- .select('c, 's)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,ack\n" + "Jack#22,22\n" + "John#19,ohn\n" + "John#19,19\n" +
- "Anna#44,nna\n" + "Anna#44,44\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunctionInCondition(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func0 = new TableFunc0
-
- val result = in
- .join(func0('c))
- .where(Func18('name, "J") && (Func1('a) < 3) && Func1('age) > 20)
- .select('c, 'name, 'age)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "Jack#22,Jack,22"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLongAndTemporalTypes(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func0 = new JavaTableFunc0
-
- val result = in
- .where('a === 1)
- .select(Date.valueOf("1990-10-14") as 'x,
- 1000L as 'y,
- Timestamp.valueOf("1990-10-14 12:10:10") as 'z)
- .join(func0('x, 'y, 'z) as 's)
- .select('s)
- .toDataSet[Row]
-
- val results = result.collect()
- val expected = "1000\n" + "655906210000\n" + "7591\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithParameter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val richTableFunc1 = new RichTableFunc1
- tEnv.registerFunction("RichTableFunc1", richTableFunc1)
- UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> "#"))
-
- val result = testData(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(richTableFunc1('c) as 's)
- .select('a, 's)
-
- val expected = "1,Jack\n" + "1,22\n" + "2,John\n" + "2,19\n" + "3,Anna\n" + "3,44"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedTableFunctionWithScalarFunctionWithParameters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val richTableFunc1 = new RichTableFunc1
- tEnv.registerFunction("RichTableFunc1", richTableFunc1)
- val richFunc2 = new RichFunc2
- tEnv.registerFunction("RichFunc2", richFunc2)
- UserDefinedFunctionTestUtils.setJobParameters(
- env,
- Map("word_separator" -> "#", "string.value" -> "test"))
-
- val result = CollectionDataSets.getSmall3TupleDataSet(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .join(richTableFunc1(richFunc2('c)) as 's)
- .select('a, 's)
-
- val expected = "1,Hi\n1,test\n2,Hello\n2,test\n3,Hello world\n3,test"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableFunctionConstructorWithParams(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
- val func30 = new TableFunc3(null)
- val func31 = new TableFunc3("OneConf_")
- val func32 = new TableFunc3("TwoConf_")
-
- val result = in
- .join(func30('c) as('d, 'e))
- .select('c, 'd, 'e)
- .join(func31('c) as ('f, 'g))
- .select('c, 'd, 'e, 'f, 'g)
- .join(func32('c) as ('h, 'i))
- .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
- .toDataSet[Row]
-
- val results = result.collect()
-
- val expected = "Anna#44,Anna,OneConf_Anna,TwoConf_Anna,44,44,44\n" +
- "Jack#22,Jack,OneConf_Jack,TwoConf_Jack,22,22,22\n" +
- "John#19,John,OneConf_John,TwoConf_John,19,19,19\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testScalarFunctionConstructorWithParams(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
-
- val func0 = new Func13("default")
- val func1 = new Func13("Sunny")
- val func2 = new Func13("kevin2")
-
- val result = in.select(func0('c), func1('c),func2('c))
-
- val results = result.collect()
-
- val expected = "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44\n" +
- "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22\n" +
- "default-John#19,Sunny-John#19,kevin2-John#19\n" +
- "default-nosharp,Sunny-nosharp,kevin2-nosharp"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableFunctionWithVariableArguments(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val varArgsFunc0 = new VarArgsFunc0
- tableEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
-
- val result = testData(env)
- .toTable(tableEnv, 'a, 'b, 'c)
- .select('c)
- .join(varArgsFunc0("1", "2", 'c))
-
- val expected = "Anna#44,1\n" +
- "Anna#44,2\n" +
- "Anna#44,Anna#44\n" +
- "Jack#22,1\n" +
- "Jack#22,2\n" +
- "Jack#22,Jack#22\n" +
- "John#19,1\n" +
- "John#19,2\n" +
- "John#19,John#19\n" +
- "nosharp,1\n" +
- "nosharp,2\n" +
- "nosharp,nosharp"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
-
- // Test for empty cases
- val result0 = testData(env)
- .toTable(tableEnv, 'a, 'b, 'c)
- .select('c)
- .join(varArgsFunc0())
- val results0 = result0.toDataSet[Row].collect()
- assertTrue(results0.isEmpty)
- }
-
- private def testData(
- env: ExecutionEnvironment)
- : DataSet[(Int, Long, String)] = {
-
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Jack#22"))
- data.+=((2, 2L, "John#19"))
- data.+=((3, 2L, "Anna#44"))
- data.+=((4, 3L, "nosharp"))
- env.fromCollection(data)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala
deleted file mode 100644
index e28acb8..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/DataSetWindowAggregateITCase.scala
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class DataSetWindowAggregateITCase(
- mode: TestExecutionMode,
- configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- val data = List(
- (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
- (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
- (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
- (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
- (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
- (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"),
- (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"))
-
- @Test(expected = classOf[UnsupportedOperationException])
- def testAllEventTimeTumblingWindowOverCount(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- // Count tumbling non-grouping window on event-time are currently not supported
- table
- .window(Tumble over 2.rows on 'long as 'w)
- .groupBy('w)
- .select('int.count)
- .toDataSet[Row]
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverCount(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.sum, 'int.count, 'int.max, 'int.min, 'int.avg,
- 'double.sum, 'double.count, 'double.max, 'double.min, 'double.avg,
- 'float.sum, 'float.count, 'float.max, 'float.min, 'float.avg,
- 'bigdec.sum, 'bigdec.count, 'bigdec.max, 'bigdec.min, 'bigdec.avg)
-
- val expected = "Hello,7,2,5,2,3,7.0,2,5.0,2.0,3.5,7.0,2,5.0,2.0,3.5,7,2,5,2,3.5\n" +
- "Hello world,7,2,4,3,3,7.0,2,4.0,3.0,3.5,7.0,2,4.0,3.0,3.5,7,2,4,3,3.5\n"
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverTime(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.sum, 'w.start, 'w.end)
-
- val expected = "Hello world,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
- "Hello world,4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n" +
- "Hello,7,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
- "Hallo,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllEventTimeTumblingWindowOverTime(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w)
- .select('int.sum, 'w.start, 'w.end)
-
- val expected = "10,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "6,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
- "4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSessionGroupWindow(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'string.count, 'w.start, 'w.end)
-
- val results = windowedTable.toDataSet[Row].collect()
-
- val expected = "Hallo,1,1970-01-01 00:00:00.002,1970-01-01 00:00:00.009\n" +
- "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.015\n" +
- "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.023\n" +
- "Hello,3,1970-01-01 00:00:00.003,1970-01-01 00:00:00.014\n" +
- "Hi,1,1970-01-01 00:00:00.001,1970-01-01 00:00:00.008"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllEventTimeSessionGroupWindow(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val results =table
- .window(Session withGap 2.milli on 'long as 'w)
- .groupBy('w)
- .select('string.count, 'w.start, 'w.end).toDataSet[Row].collect()
-
- val expected = "4,1970-01-01 00:00:00.001,1970-01-01 00:00:00.006\n" +
- "2,1970-01-01 00:00:00.007,1970-01-01 00:00:00.01\n" +
- "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.018"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMultiGroupWindow(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- .window( Slide over 5.milli every 1.milli on 'int as 'w2)
- .groupBy('w2)
- .select('string)
- .toDataSet[Row]
- }
-
- // ----------------------------------------------------------------------------------------------
- // Sliding windows
- // ----------------------------------------------------------------------------------------------
-
- @Test(expected = classOf[UnsupportedOperationException])
- def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- // Count sliding group window on event-time are currently not supported
- table
- .window(Slide over 2.rows every 2.rows on 'long as 'w)
- .groupBy('w)
- .select('int.count)
- .toDataSet[Row]
- }
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 2.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count, 'w.start, 'w.end)
-
- val expected =
- "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
- "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
- "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019\n" +
- "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
- "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003\n" +
- "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011\n" +
- "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007\n" +
- "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
- "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 10.milli every 5.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
- "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
- "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
- "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02\n" +
- "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025\n" +
- "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
- "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
- "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
- "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 4.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
- "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
- "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
- "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 10.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 3.milli every 10.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala
deleted file mode 100644
index 9743bf6..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/JoinITCase.scala
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.utils.TableFunc2
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class JoinITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithFilter(): Unit = {
-
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e && 'b < 2).select('c, 'g)
-
- val expected = "Hi,Hallo\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithJoinFilter(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e && 'a < 6).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e && 'a < 6 && 'h < 'b).select('c, 'g)
-
- val results = joinT.toDataSet[Row].collect()
- val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).filter('a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
- "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithAggregation(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- // use different table env in order to let tmp table ids are the same
- val tEnv2 = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('a === 'd).select('g.count)
-
- val expected = "6"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithGroupedAggregation(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2)
- .where('a === 'd)
- .groupBy('a, 'd)
- .select('b.sum, 'g.count)
-
- val expected = "6,3\n" + "4,2\n" + "1,1"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinPushThroughJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
- val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'j, 'k, 'l)
-
- val joinT = ds1.join(ds2)
- .where(Literal(true))
- .join(ds3)
- .where('a === 'd && 'e === 'k)
- .select('a, 'f, 'l)
-
- val expected = "2,1,Hello\n" + "2,1,Hello world\n" + "1,0,Hi"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithDisjunctivePred(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).filter('a === 'd && ('b === 'e || 'b === 'e - 10)).select('c, 'g)
-
- val expected = "Hi,Hallo\n" +
- "Hello,Hallo Welt\n" +
- "I am fine.,IJK"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithExpressionPreds(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).filter('b === 'h + 1 && 'a - 1 === 'd + 2).select('c, 'g)
-
- val expected = "I am fine.,Hallo Welt\n" +
- "Luke Skywalker,Hallo Welt wie gehts?\n" +
- "Luke Skywalker,ABC\n" +
- "Comment#2,HIJ\n" +
- "Comment#2,IJK"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLeftJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.leftOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
- "Hello world,ABC\n" + "Hello world, how are you?,null\n" + "I am fine.,HIJ\n" +
- "I am fine.,IJK\n" + "Luke Skywalker,null\n" + "Comment#1,null\n" + "Comment#2,null\n" +
- "Comment#3,null\n" + "Comment#4,null\n" + "Comment#5,null\n" + "Comment#6,null\n" +
- "Comment#7,null\n" + "Comment#8,null\n" + "Comment#9,null\n" + "Comment#10,null\n" +
- "Comment#11,null\n" + "Comment#12,null\n" + "Comment#13,null\n" + "Comment#14,null\n" +
- "Comment#15,null\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.rightOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
- "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
- "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
- "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFullOuterJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.fullOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
- "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
- "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
- "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n" + "Luke Skywalker,null\n" +
- "Comment#1,null\n" + "Comment#2,null\n" + "Comment#3,null\n" + "Comment#4,null\n" +
- "Comment#5,null\n" + "Comment#6,null\n" + "Comment#7,null\n" + "Comment#8,null\n" +
- "Comment#9,null\n" + "Comment#10,null\n" + "Comment#11,null\n" + "Comment#12,null\n" +
- "Comment#13,null\n" + "Comment#14,null\n" + "Comment#15,null\n" +
- "Hello world, how are you?,null\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUDTFJoinOnTuples(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List("hi#world", "how#are#you")
-
- val ds1 = env.fromCollection(data).toTable(tEnv, 'a)
- val func2 = new TableFunc2
-
- val joinDs = ds1.join(func2('a) as ('name, 'len))
-
- val results = joinDs.toDataSet[Row].collect()
- val expected = Seq(
- "hi#world,hi,2",
- "hi#world,world,5",
- "how#are#you,how,3",
- "how#are#you,are,3",
- "how#are#you,you,3").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-}
[06/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetWindowAggregateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetWindowAggregateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetWindowAggregateITCase.scala
deleted file mode 100644
index 77ea66e..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/DataSetWindowAggregateITCase.scala
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class DataSetWindowAggregateITCase(
- mode: TestExecutionMode,
- configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- val data = List(
- (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
- (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
- (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
- (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
- (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
- (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"),
- (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"))
-
- @Test(expected = classOf[UnsupportedOperationException])
- def testAllEventTimeTumblingWindowOverCount(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- // Count tumbling non-grouping window on event-time are currently not supported
- table
- .window(Tumble over 2.rows on 'long as 'w)
- .groupBy('w)
- .select('int.count)
- .toDataSet[Row]
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverCount(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.sum, 'int.count, 'int.max, 'int.min, 'int.avg,
- 'double.sum, 'double.count, 'double.max, 'double.min, 'double.avg,
- 'float.sum, 'float.count, 'float.max, 'float.min, 'float.avg,
- 'bigdec.sum, 'bigdec.count, 'bigdec.max, 'bigdec.min, 'bigdec.avg)
-
- val expected = "Hello,7,2,5,2,3,7.0,2,5.0,2.0,3.5,7.0,2,5.0,2.0,3.5,7,2,5,2,3.5\n" +
- "Hello world,7,2,4,3,3,7.0,2,4.0,3.0,3.5,7.0,2,4.0,3.0,3.5,7,2,4,3,3.5\n"
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverTime(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.sum, 'w.start, 'w.end)
-
- val expected = "Hello world,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
- "Hello world,4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n" +
- "Hello,7,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
- "Hallo,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllEventTimeTumblingWindowOverTime(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w)
- .select('int.sum, 'w.start, 'w.end)
-
- val expected = "10,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "6,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
- "4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSessionGroupWindow(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'string.count, 'w.start, 'w.end)
-
- val results = windowedTable.toDataSet[Row].collect()
-
- val expected = "Hallo,1,1970-01-01 00:00:00.002,1970-01-01 00:00:00.009\n" +
- "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.015\n" +
- "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.023\n" +
- "Hello,3,1970-01-01 00:00:00.003,1970-01-01 00:00:00.014\n" +
- "Hi,1,1970-01-01 00:00:00.001,1970-01-01 00:00:00.008"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllEventTimeSessionGroupWindow(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val results =table
- .window(Session withGap 2.milli on 'long as 'w)
- .groupBy('w)
- .select('string.count, 'w.start, 'w.end).toDataSet[Row].collect()
-
- val expected = "4,1970-01-01 00:00:00.001,1970-01-01 00:00:00.006\n" +
- "2,1970-01-01 00:00:00.007,1970-01-01 00:00:00.01\n" +
- "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.018"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMultiGroupWindow(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- .window( Slide over 5.milli every 1.milli on 'int as 'w2)
- .groupBy('w2)
- .select('string)
- .toDataSet[Row]
- }
-
- // ----------------------------------------------------------------------------------------------
- // Sliding windows
- // ----------------------------------------------------------------------------------------------
-
- @Test(expected = classOf[UnsupportedOperationException])
- def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- // Count sliding group window on event-time are currently not supported
- table
- .window(Slide over 2.rows every 2.rows on 'long as 'w)
- .groupBy('w)
- .select('int.count)
- .toDataSet[Row]
- }
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 2.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count, 'w.start, 'w.end)
-
- val expected =
- "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
- "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
- "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019\n" +
- "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
- "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003\n" +
- "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011\n" +
- "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007\n" +
- "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
- "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 10.milli every 5.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
- "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
- "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
- "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02\n" +
- "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025\n" +
- "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
- "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
- "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
- "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 4.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
- "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
- "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
- "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 5.milli every 10.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
- // please keep this test in sync with the DataStream variant
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env
- .fromCollection(data)
- .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
-
- val windowedTable = table
- .window(Slide over 3.milli every 10.milli on 'long as 'w)
- .groupBy('string, 'w)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected =
- "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003\n" +
- "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003"
-
- val results = windowedTable.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala
new file mode 100644
index 0000000..eb516e7
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/AggregationsITCase.scala
@@ -0,0 +1,394 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.sql
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class AggregationsITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testAggregationTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1), min(_1), max(_1), count(_1), avg(_1) FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231,1,21,21,11"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1) FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDataSetAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1) FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationDataTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), avg(b), avg(c), avg(d), avg(e), avg(f), count(g), " +
+ "min(g), min('Ciao'), max(g), max('Ciao'), sum(CAST(f AS DECIMAL)) FROM MyTable"
+
+ val ds = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'f, 'g)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,1,1,1.5,1.5,2,Ciao,Ciao,Hello,Ciao,3.0"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), sum(a), count(a), avg(b), sum(b) " +
+ "FROM MyTable"
+
+ val ds = env.fromElements((1: Byte, 1: Short), (2: Byte, 2: Short)).toTable(tEnv, 'a, 'b)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,3,2,1,3"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableAggregationWithArithmetic(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a + 2) + 2, count(b) + 5 " +
+ "FROM MyTable"
+
+ val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv, 'a, 'b)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "5.5,7"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationWithTwoCount(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT count(_1), count(_2) FROM MyTable"
+
+ val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "2,2"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+
+ @Test
+ def testAggregationAfterProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM " +
+ "(SELECT _1 as a, _2 as b, _3 as c FROM MyTable)"
+
+ val ds = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,3,2"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDistinctAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT sum(_1) as a, count(distinct _3) as b FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "231,21"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedDistinctAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT _2, avg(distinct _1) as a, count(_3) as b FROM MyTable GROUP BY _2"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected =
+ "6,18,6\n5,13,5\n4,8,4\n3,5,3\n2,2,2\n1,1,1"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupingSetAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery =
+ "SELECT _2, _3, avg(_1) as a, GROUP_ID() as g FROM MyTable GROUP BY GROUPING SETS (_2, _3)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+
+ val expected =
+ "6,null,18,1\n5,null,13,1\n4,null,8,1\n3,null,5,1\n2,null,2,1\n1,null,1,1\n" +
+ "null,Luke Skywalker,6,2\nnull,I am fine.,5,2\nnull,Hi,1,2\n" +
+ "null,Hello world, how are you?,4,2\nnull,Hello world,3,2\nnull,Hello,2,2\n" +
+ "null,Comment#9,15,2\nnull,Comment#8,14,2\nnull,Comment#7,13,2\n" +
+ "null,Comment#6,12,2\nnull,Comment#5,11,2\nnull,Comment#4,10,2\n" +
+ "null,Comment#3,9,2\nnull,Comment#2,8,2\nnull,Comment#15,21,2\n" +
+ "null,Comment#14,20,2\nnull,Comment#13,19,2\nnull,Comment#12,18,2\n" +
+ "null,Comment#11,17,2\nnull,Comment#10,16,2\nnull,Comment#1,7,2"
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testAggregateEmptyDataSets(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT avg(a), sum(a), count(b) " +
+ "FROM MyTable where a = 4 group by a"
+
+ val sqlQuery2 = "SELECT avg(a), sum(a), count(b) " +
+ "FROM MyTable where a = 4"
+
+ val sqlQuery3 = "SELECT avg(a), sum(a), count(b) " +
+ "FROM MyTable"
+
+ val ds = env.fromElements(
+ (1: Byte, 1: Short),
+ (2: Byte, 2: Short))
+ .toTable(tEnv, 'a, 'b)
+
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+ val result2 = tEnv.sql(sqlQuery2)
+ val result3 = tEnv.sql(sqlQuery3)
+
+ val results = result.toDataSet[Row].collect()
+ val expected = Seq.empty
+ val results2 = result2.toDataSet[Row].collect()
+ val expected2 = "null,null,0"
+ val results3 = result3.toDataSet[Row].collect()
+ val expected3 = "1,3,2"
+
+ assert(results.equals(expected),
+ "Empty result is expected for grouped set, but actual: " + results)
+ TestBaseUtils.compareResultAsText(results2.asJava, expected2)
+ TestBaseUtils.compareResultAsText(results3.asJava, expected3)
+ }
+
+ @Test
+ def testTumbleWindowAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.registerFunction("countFun", new CountAggFunction)
+ tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
+
+ val sqlQuery =
+ "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
+ "FROM T " +
+ "GROUP BY b, TUMBLE(ts, INTERVAL '3' SECOND)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ // create timestamps
+ .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
+ tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ val expected = Seq(
+ "1,1,1,1,1",
+ "2,2,1,2,2", "2,3,1,2,3",
+ "3,9,2,3,4", "3,6,1,3,6",
+ "4,15,2,4,7", "4,19,2,4,9",
+ "5,11,1,5,11", "5,39,3,5,13", "5,15,1,5,15",
+ "6,33,2,6,16", "6,57,3,6,19", "6,21,1,6,21"
+ ).mkString("\n")
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testHopWindowAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.registerFunction("countFun", new CountAggFunction)
+ tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
+
+ env.setParallelism(1)
+
+ val sqlQuery =
+ "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
+ "FROM T " +
+ "GROUP BY b, HOP(ts, INTERVAL '2' SECOND, INTERVAL '4' SECOND)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ // create timestamps
+ .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
+ tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ val expected = Seq(
+ "1,1,1,1,1","1,1,1,1,1",
+ "2,5,2,2,2","2,5,2,2,2",
+ "3,9,2,3,4", "3,15,3,3,5", "3,6,1,3,6",
+ "4,7,1,4,7", "4,24,3,4,8", "4,27,3,4,9", "4,10,1,4,10",
+ "5,11,1,5,11", "5,36,3,5,12", "5,54,4,5,13", "5,29,2,5,14",
+ "6,33,2,6,16", "6,70,4,6,17", "6,78,4,6,19", "6,41,2,6,20"
+ ).mkString("\n")
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testSessionWindowAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.registerFunction("countFun", new CountAggFunction)
+ tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
+
+ env.setParallelism(1)
+
+ val sqlQuery =
+ "SELECT MIN(a), MAX(a), SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), " +
+ "wAvgWithMergeAndReset(a, a)" +
+ "FROM T " +
+ "GROUP BY SESSION(ts, INTERVAL '4' SECOND)"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ // create timestamps
+ .filter(x => (x._2 % 2) == 0)
+ .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
+ tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
+
+ val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ val expected = Seq(
+ "2,10,39,6,3,7",
+ "16,21,111,6,6,18"
+ ).mkString("\n")
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala
new file mode 100644
index 0000000..926dc43
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/CalcITCase.scala
@@ -0,0 +1,323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.sql
+
+import java.sql.{Date, Time, Timestamp}
+import java.util
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.table.runtime.dataset.table.OldHashCode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class CalcITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSelectStarFromTable(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectStarFromDataSet(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectAll(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT a, b, c FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectWithNaming(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT _1 as a, _2 as b FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
+ "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidFields(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT a, foo FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ tEnv.sql(sqlQuery)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE false"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE true"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
+ "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
+ "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
+ "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
+ "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
+ "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnString(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE c LIKE '%world%'"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnInteger(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)=0"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
+ "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
+ "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
+ "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDisjunctivePredicate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE a < 2 OR a > 20"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterWithAnd(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)<>0 AND MOD(b,2)=0"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
+ "9,4,Comment#3\n" + "17,6,Comment#11\n" +
+ "19,6,Comment#13\n" + "21,6,Comment#15\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAdvancedDataTypes(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT a, b, c, DATE '1984-07-12', TIME '14:34:24', " +
+ "TIMESTAMP '1984-07-12 14:34:24' FROM MyTable"
+
+ val ds = env.fromElements((
+ Date.valueOf("1984-07-12"),
+ Time.valueOf("14:34:24"),
+ Timestamp.valueOf("1984-07-12 14:34:24")))
+ tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
+ "1984-07-12,14:34:24,1984-07-12 14:34:24.0"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedScalarFunction(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ tEnv.registerFunction("hashCode", OldHashCode)
+ tEnv.registerFunction("hashCode", MyHashCode)
+
+ val ds = env.fromElements("a", "b", "c")
+ tEnv.registerDataSet("MyTable", ds, 'text)
+
+ val result = tEnv.sql("SELECT hashCode(text) FROM MyTable")
+
+ val expected = "97\n98\n99"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
+
+object MyHashCode extends ScalarFunction {
+ def eval(s: String): Int = s.hashCode()
+}
+
+object CalcITCase {
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](
+ Array(TableProgramsTestBase.DEFAULT),
+ Array(TableProgramsTestBase.NO_NULL)).asJava
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala
new file mode 100644
index 0000000..aad4b3b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/JoinITCase.scala
@@ -0,0 +1,521 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class JoinITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND b < 2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi,Hallo\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND a < 6 AND h < b"
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithMultipleKeys(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d AND b = h"
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
+ "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithAlias(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT Table5.c, Table3.c FROM Table3, Table5 WHERE a = d AND a < 4"
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'c)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = "1,Hi\n" + "2,Hello\n" + "1,Hello\n" +
+ "2,Hello world\n" + "2,Hello world\n" + "3,Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDataSetJoinWithAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT COUNT(g), COUNT(b) FROM Table3, Table5 WHERE a = d"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("Table3", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("Table5", ds2, 'd, 'e, 'f, 'g, 'h)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "6,6"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableJoinWithAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT COUNT(b), COUNT(g) FROM Table3, Table5 WHERE a = d"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "6,6"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFullOuterJoin(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
+ "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
+ "null,IJK\n" + "null,JKL\n" + "null,KLM"
+
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val sqlQuery = "SELECT c, g FROM Table5 LEFT OUTER JOIN Table3 ON b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
+ "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
+ "null,IJK\n" + "null,JKL\n" + "null,KLM"
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightOuterJoin(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
+ "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
+ "null,IJK\n" + "null,JKL\n" + "null,KLM"
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCrossJoinWithLeftSingleRowInput(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
+ tEnv.registerTable("A", table)
+
+ val sqlQuery2 = "SELECT * FROM (SELECT count(*) FROM A) CROSS JOIN A"
+ val expected =
+ "3,1,1,Hi\n" +
+ "3,2,2,Hello\n" +
+ "3,3,2,Hello world"
+ val result = tEnv.sql(sqlQuery2).collect()
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testCrossJoinWithRightSingleRowInput(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
+ tEnv.registerTable("A", table)
+
+ val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A)"
+ val expected =
+ "1,1,Hi,3\n" +
+ "2,2,Hello,3\n" +
+ "3,2,Hello world,3"
+ val result = tEnv.sql(sqlQuery1).collect()
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testCrossJoinWithEmptySingleRowInput(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
+ tEnv.registerTable("A", table)
+
+ val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A HAVING count(*) < 0)"
+ val result = tEnv.sql(sqlQuery1).count()
+ Assert.assertEquals(0, result)
+ }
+
+ @Test
+ def testLeftNullRightJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt " +
+ "FROM (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) RIGHT JOIN A ON a < cnt"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,null",
+ "2,null", "2,null",
+ "3,null", "3,null", "3,null",
+ "4,null", "4,null", "4,null", "4,null",
+ "5,null", "5,null", "5,null", "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+
+ @Test
+ def testLeftSingleRightJoinEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt = a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,null", "2,null", "2,null", "3,3", "3,3",
+ "3,3", "4,null", "4,null", "4,null",
+ "4,null", "5,null", "5,null", "5,null",
+ "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLeftSingleRightJoinNotEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt > a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,3", "2,3", "2,3", "3,null", "3,null",
+ "3,null", "4,null", "4,null", "4,null",
+ "4,null", "5,null", "5,null", "5,null",
+ "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightNullLeftJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt " +
+ "FROM A LEFT JOIN (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) ON cnt > a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("A", ds2)
+ tEnv.registerTable("B", ds1)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = Seq(
+ "2,null", "3,null", "1,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt = a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = Seq(
+ "1,null", "2,null", "2,null", "3,3", "3,3",
+ "3,3", "4,null", "4,null", "4,null",
+ "4,null", "5,null", "5,null", "5,null",
+ "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinNotEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt < a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = Seq(
+ "1,null", "2,null", "2,null", "3,null", "3,null",
+ "3,null", "4,3", "4,3", "4,3",
+ "4,3", "5,3", "5,3", "5,3",
+ "5,3", "5,3").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinTwoFields(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt, cnt2 " +
+ "FROM t1 LEFT JOIN (SELECT COUNT(*) AS cnt,COUNT(*) AS cnt2 FROM t2 ) AS x ON a = cnt"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("t1", ds1)
+ tEnv.registerTable("t2", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,null,null",
+ "2,null,null", "2,null,null",
+ "3,3,3", "3,3,3", "3,3,3",
+ "4,null,null", "4,null,null", "4,null,null", "4,null,null",
+ "5,null,null", "5,null,null", "5,null,null", "5,null,null", "5,null,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCrossWithUnnest(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ (1, 1L, Array("Hi", "w")),
+ (2, 2L, Array("Hello", "k")),
+ (3, 2L, Array("Hello world", "x"))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataSet("T", stream, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) as A (s)"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = List("1,Hi", "1,w", "2,Hello", "2,k", "3,Hello world", "3,x")
+ val results = result.toDataSet[Row].collect().toList
+ assertEquals(expected.toString(), results.sortWith(_.toString < _.toString).toString())
+ }
+
+ @Test
+ def testJoinWithUnnestOfTuple(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ (1, Array((12, "45.6"), (2, "45.612"))),
+ (2, Array((13, "41.6"), (1, "45.2136"))),
+ (3, Array((18, "42.6")))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataSet("T", stream, 'a, 'b)
+
+ val sqlQuery = "" +
+ "SELECT a, b, x, y " +
+ "FROM " +
+ " (SELECT a, b FROM T WHERE a < 3) as tf, " +
+ " UNNEST(tf.b) as A (x, y) " +
+ "WHERE x > a"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = List(
+ "1,[(12,45.6), (2,45.612)],12,45.6",
+ "1,[(12,45.6), (2,45.612)],2,45.612",
+ "2,[(13,41.6), (1,45.2136)],13,41.6").mkString(", ")
+ val results = result.toDataSet[Row].collect().map(_.toString)
+ assertEquals(expected, results.sorted.mkString(", "))
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala
new file mode 100644
index 0000000..631ce2b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SetOperatorsITCase.scala
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+import scala.util.Random
+
+@RunWith(classOf[Parameterized])
+class SetOperatorsITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testUnionAll(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 UNION ALL (SELECT f FROM t2)"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 UNION (SELECT f FROM t2)"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnionWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM (" +
+ "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))" +
+ "WHERE b < 2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hallo\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnionWithAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT count(c) FROM (" +
+ "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "18"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testExcept(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 EXCEPT (SELECT c FROM t2)"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = env.fromElements((1, 1L, "Hi"))
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ @Ignore
+ // calcite sql parser doesn't support EXCEPT ALL
+ def testExceptAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 EXCEPT ALL SELECT c FROM t2"
+
+ val data1 = new mutable.MutableList[Int]
+ data1 += (1, 1, 1, 2, 2)
+ val data2 = new mutable.MutableList[Int]
+ data2 += (1, 2, 2, 3)
+ val ds1 = env.fromCollection(data1)
+ val ds2 = env.fromCollection(data2)
+
+ tEnv.registerDataSet("t1", ds1, 'c)
+ tEnv.registerDataSet("t2", ds2, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1\n1"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testExceptWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM (" +
+ "SELECT * FROM t1 EXCEPT (SELECT a, b, c FROM t2))" +
+ "WHERE b < 2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersect(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 INTERSECT SELECT c FROM t2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Hi"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((3, 2L, "Hello world!"))
+ val ds2 = env.fromCollection(Random.shuffle(data))
+
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hello\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ @Ignore
+ // calcite sql parser doesn't support INTERSECT ALL
+ def testIntersectAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 INTERSECT ALL SELECT c FROM t2"
+
+ val data1 = new mutable.MutableList[Int]
+ data1 += (1, 1, 1, 2, 2)
+ val data2 = new mutable.MutableList[Int]
+ data2 += (1, 2, 2, 3)
+ val ds1 = env.fromCollection(data1)
+ val ds2 = env.fromCollection(data2)
+
+ tEnv.registerDataSet("t1", ds1, 'c)
+ tEnv.registerDataSet("t2", ds2, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1\n2\n2"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectWithFilter(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM ((SELECT * FROM t1) INTERSECT (SELECT * FROM t2)) WHERE a > 1"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get3TupleDataSet(env)
+
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala
new file mode 100644
index 0000000..f06517a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/SortITCase.scala
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.sql
+
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.api.scala.{ExecutionEnvironment, _}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.SortTestUtils._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+@RunWith(classOf[Parameterized])
+class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ private def getExecutionEnvironment = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ // set the parallelism explicitly to make sure the query is executed in
+ // a distributed manner
+ env.setParallelism(3)
+ env
+ }
+
+ @Test
+ def testOrderByMultipleFieldsWithSql(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC, _2 DESC"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ (- x.productElement(0).asInstanceOf[Int], - x.productElement(1).asInstanceOf[Long]))
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ def rowOrdering = Ordering.by((r : Row) => {
+ // ordering for this tuple will fall into the previous defined tupleOrdering,
+ // so we just need to return the field by their defining sequence
+ (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
+ })
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(rowOrdering)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByWithOffset(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC OFFSET 2 ROWS"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ - x.productElement(0).asInstanceOf[Int] )
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings, 2, 21)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results.
+ filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByWithOffsetAndFetch(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings, 2, 7)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByLimit(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _2, _1 LIMIT 5"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ (x.productElement(1).asInstanceOf[Long], x.productElement(0).asInstanceOf[Int]) )
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ def rowOrdering = Ordering.by((r : Row) => {
+ // ordering for this tuple will fall into the previous defined tupleOrdering,
+ // so we just need to return the field by their defining sequence
+ (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
+ })
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(rowOrdering)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala
new file mode 100644
index 0000000..e7db602
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableSourceITCase.scala
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.sql
+
+import org.apache.flink.api.scala.ExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.utils.CommonTestData
+import org.apache.flink.test.util.TestBaseUtils
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableSourceITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testCsvTableSource(): Unit = {
+
+ val csvTable = CommonTestData.getCsvTableSource
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ tEnv.registerTableSource("csvTable", csvTable)
+ val results = tEnv.sql(
+ "SELECT id, `first`, `last`, score FROM csvTable").collect()
+
+ val expected = Seq(
+ "1,Mike,Smith,12.3",
+ "2,Bob,Taylor,45.6",
+ "3,Sam,Miller,7.89",
+ "4,Peter,Smith,0.12",
+ "5,Liz,Williams,34.5",
+ "6,Sally,Miller,6.78",
+ "7,Alice,Smith,90.1",
+ "8,Kelly,Williams,2.34").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testNested(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val nestedTable = CommonTestData.getNestedTableSource
+
+ tableEnv.registerTableSource("NestedPersons", nestedTable)
+
+ val result = tableEnv.sql("SELECT NestedPersons.firstName, NestedPersons.lastName," +
+ "NestedPersons.address.street, NestedPersons.address.city AS city " +
+ "FROM NestedPersons " +
+ "WHERE NestedPersons.address.city LIKE 'Dublin'").collect()
+
+ val expected = "Bob,Taylor,Pearse Street,Dublin"
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala
new file mode 100644
index 0000000..b31c1fb
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/sql/TableWithSQLITCase.scala
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.dataset.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableWithSQLITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSQLTable(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE a > 9"
+
+ val result = tEnv.sql(sqlQuery).select('a.avg, 'b.sum, 'c.count)
+
+ val expected = "15,65,12"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableSQLTable(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val t1 = ds.filter('a > 9)
+
+ tEnv.registerTable("MyTable", t1)
+
+ val sqlQuery = "SELECT avg(a) as a1, sum(b) as b1, count(c) as c1 FROM MyTable"
+
+ val result = tEnv.sql(sqlQuery).select('a1 + 1, 'b1 - 5, 'c1)
+
+ val expected = "16,60,12"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMultipleSQLQueries(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val sqlQuery = "SELECT a as aa FROM MyTable WHERE b = 6"
+ val result1 = tEnv.sql(sqlQuery)
+ tEnv.registerTable("ResTable", result1)
+
+ val sqlQuery2 = "SELECT count(aa) FROM ResTable"
+ val result2 = tEnv.sql(sqlQuery2)
+
+ val expected = "6"
+ val results = result2.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectWithCompositeType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT MyTable.a2, MyTable.a1._2 FROM MyTable"
+
+ val ds = env.fromElements(((12, true), "Hello")).toTable(tEnv).as('a1, 'a2)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello,true\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
[35/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala
deleted file mode 100644
index a446c84..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.sources.{DefinedProctimeAttribute, DefinedRowtimeAttribute, StreamTableSource}
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil.{term, unaryNode}
-import org.apache.flink.types.Row
-import org.junit.Test
-
-class TableSourceTest extends TableTestBase {
-
- @Test
- def testRowTimeTableSourceSimple(): Unit = {
- val util = streamTestUtil()
- util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
-
- val t = util.tableEnv.scan("rowTimeT").select("addTime, id, name, val")
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
- term("select", "TIME_MATERIALIZATION(addTime) AS addTime", "id", "name", "val")
- )
- util.verifyTable(t, expected)
- }
-
- @Test
- def testRowTimeTableSourceGroupWindow(): Unit = {
- val util = streamTestUtil()
- util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
-
- val t = util.tableEnv.scan("rowTimeT")
- .filter("val > 100")
- .window(Tumble over 10.minutes on 'addTime as 'w)
- .groupBy('name, 'w)
- .select('name, 'w.end, 'val.avg)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
- term("select", "name", "val", "addTime"),
- term("where", ">(val, 100)")
- ),
- term("groupBy", "name"),
- term("window", "TumblingGroupWindow('w, 'addTime, 600000.millis)"),
- term("select", "name", "AVG(val) AS TMP_1", "end('w) AS TMP_0")
- ),
- term("select", "name", "TMP_0", "TMP_1")
- )
- util.verifyTable(t, expected)
- }
-
- @Test
- def testProcTimeTableSourceSimple(): Unit = {
- val util = streamTestUtil()
- util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
-
- val t = util.tableEnv.scan("procTimeT").select("pTime, id, name, val")
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
- term("select", "TIME_MATERIALIZATION(pTime) AS pTime", "id", "name", "val")
- )
- util.verifyTable(t, expected)
- }
-
- @Test
- def testProcTimeTableSourceOverWindow(): Unit = {
- val util = streamTestUtil()
- util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
-
- val t = util.tableEnv.scan("procTimeT")
- .window(Over partitionBy 'id orderBy 'pTime preceding 2.hours as 'w)
- .select('id, 'name, 'val.sum over 'w as 'valSum)
- .filter('valSum > 100)
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamOverAggregate",
- "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
- term("partitionBy", "id"),
- term("orderBy", "pTime"),
- term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
- term("select", "id", "val", "name", "pTime", "SUM(val) AS w0$o0")
- ),
- term("select", "id", "name", "w0$o0 AS valSum"),
- term("where", ">(w0$o0, 100)")
- )
- util.verifyTable(t, expected)
- }
-
-
-}
-
-class TestRowtimeSource(timeField: String)
- extends StreamTableSource[Row] with DefinedRowtimeAttribute {
-
- override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
-
- override def getRowtimeAttribute: String = timeField
-
- override def getReturnType: TypeInformation[Row] = {
- new RowTypeInfo(
- Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
- Array("id", "val", "name"))
- }
-}
-
-class TestProctimeSource(timeField: String)
- extends StreamTableSource[Row] with DefinedProctimeAttribute {
-
- override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
-
- override def getProctimeAttribute: String = timeField
-
- override def getReturnType: TypeInformation[Row] = {
- new RowTypeInfo(
- Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
- Array("id", "val", "name"))
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala
deleted file mode 100644
index bb9877b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils._
-import org.junit.Test
-
-class UserDefinedTableFunctionTest extends TableTestBase {
-
- @Test
- def testCrossJoin(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("func1", new TableFunc1)
-
- val result1 = table.join(function('c) as 's).select('c, 's)
-
- val expected1 = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "s")
- )
-
- util.verifyTable(result1, expected1)
-
- // test overloading
-
- val result2 = table.join(function('c, "$") as 's).select('c, 's)
-
- val expected2 = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2, '$$')"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "s")
- )
-
- util.verifyTable(result2, expected2)
- }
-
- @Test
- def testLeftOuterJoin(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("func1", new TableFunc1)
-
- val result = table.leftOuterJoin(function('c) as 's).select('c, 's)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
- term("joinType", "LEFT")
- ),
- term("select", "c", "s")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testCustomType(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("func2", new TableFunc2)
-
- val result = table.join(function('c) as ('name, 'len)).select('c, 'name, 'len)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
- "VARCHAR(2147483647) name, INTEGER len)"),
- term("joinType", "INNER")
- ),
- term("select", "c", "name", "len")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testHierarchyType(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("hierarchy", new HierarchyTableFunction)
-
- val result = table.join(function('c) as ('name, 'adult, 'len))
-
- val expected = unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
- " VARCHAR(2147483647) name, BOOLEAN adult, INTEGER len)"),
- term("joinType", "INNER")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testPojoType(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("pojo", new PojoTableFunc)
-
- val result = table.join(function('c))
-
- val expected = unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
- "INTEGER age, VARCHAR(2147483647) name)"),
- term("joinType", "INNER")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testFilter(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("func2", new TableFunc2)
-
- val result = table
- .join(function('c) as ('name, 'len))
- .select('c, 'name, 'len)
- .filter('len > 2)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}($$2)"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
- "VARCHAR(2147483647) name, INTEGER len)"),
- term("joinType", "INNER"),
- term("condition", ">($1, 2)")
- ),
- term("select", "c", "name", "len")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testScalarFunction(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val function = util.addFunction("func1", new TableFunc1)
-
- val result = table.join(function('c.substring(2)) as 's)
-
- val expected = unaryNode(
- "DataStreamCorrelate",
- streamTableNode(0),
- term("invocation", s"${function.functionIdentifier}(SUBSTRING($$2, 2, CHAR_LENGTH($$2)))"),
- term("function", function),
- term("rowType",
- "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) s)"),
- term("joinType", "INNER")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala
deleted file mode 100644
index b558193..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class CalcStringExpressionTest extends TableTestBase {
-
- @Test
- def testSimpleSelect(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]()
-
- val resScala = t.select('_1, '_2)
- val resJava = t.select("_1, _2")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testSelectStar(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t.select('*)
- val resJava = t.select("*")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testSelectWithWhere(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
- val resScala = t.where('string === "true").select('int)
- val resJava = t.where("string === 'true'").select("int")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testSimpleSelectWithNaming(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t.select('int, 'string)
- val resJava = t.select("int, string")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testSimpleSelectWithAlias(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
- val resScala = t.select('int as 'myInt, 'string as 'myString)
- val resJava = t.select("int as myInt, string as myString")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testSimpleFilter(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t.filter('int === 3).select('int as 'myInt, 'string)
- val resJava = t.filter("int === 3").select("int as myInt, string")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t.filter(Literal(false)).select('int as 'myInt, 'string)
- val resJava = t.filter("false").select("int as myInt, string")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t.filter(Literal(true)).select('int as 'myInt, 'string)
- val resJava = t.filter("true").select("int as myInt, string")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testNotEqualsFilter(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t.filter('int !== 2).filter('string.like("%world%")).select('int, 'string)
- val resJava = t.filter("int !== 2").filter("string.like('%world%')").select("int, string")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testFilterWithExpression(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t.filter('int % 2 === 0).select('int, 'string)
- val resJava = t.filter("int % 2 === 0").select("int, string")
- verifyTableEquals(resJava, resScala)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala
deleted file mode 100644
index fb23f09..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
-import org.junit.Test
-
-class GroupAggregationsStringExpressionTest extends TableTestBase {
-
- @Test
- def testGroupedAggregate(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- // Expression / Scala API
- val resScala = t
- .groupBy('string)
- .select('int.count as 'cnt, weightAvgFun('long, 'int))
-
- // String / Java API
- val resJava = t
- .groupBy("string")
- .select("int.count as cnt, weightAvgFun(long, int)")
-
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testNonGroupedAggregate(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- // Expression / Scala API
- val resScala = t.select('int.count as 'cnt, 'long.sum)
-
- // String / Java API
- val resJava = t.select("int.count as cnt, long.sum")
-
- verifyTableEquals(resJava, resScala)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
deleted file mode 100644
index bb0b121..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
-import org.apache.flink.table.api.java.{Slide => JSlide, Session => JSession, Tumble => JTumble}
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-
-class GroupWindowStringExpressionTest extends TableTestBase {
-
- @Test
- def testRowTimeSlide(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'rowtime.rowtime)
-
- val myCountFun = new CountAggFunction
- util.tableEnv.registerFunction("myCountFun", myCountFun)
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- // Expression / Scala API
- val resScala = t
- .window(Slide over 4.hours every 2.hours on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select(
- 'string,
- myCountFun('string),
- 'int.sum,
- weightAvgFun('long, 'int),
- weightAvgFun('int, 'int) * 2,
- 'w.start,
- 'w.end)
-
- // String / Java API
- val resJava = t
- .window(JSlide.over("4.hours").every("2.hours").on("rowtime").as("w"))
- .groupBy("w, string")
- .select(
- "string, " +
- "myCountFun(string), " +
- "int.sum, " +
- "weightAvgFun(long, int), " +
- "weightAvgFun(int, int) * 2, " +
- "start(w)," +
- "end(w)")
-
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testRowTimeTumble(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, Long, String)]('int, 'long, 'rowtime.rowtime, 'string)
-
- val myCountFun = new CountAggFunction
- util.tableEnv.registerFunction("myCountFun", myCountFun)
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- // Expression / Scala API
- val resScala = t
- .window(Tumble over 4.hours on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select(
- 'string,
- myCountFun('string),
- 'int.sum,
- weightAvgFun('long, 'int),
- weightAvgFun('int, 'int) * 2,
- 'w.start,
- 'w.end)
-
- // String / Java API
- val resJava = t
- .window(JTumble.over("4.hours").on("rowtime").as("w"))
- .groupBy("w, string")
- .select(
- "string, " +
- "myCountFun(string), " +
- "int.sum, " +
- "weightAvgFun(long, int), " +
- "weightAvgFun(int, int) * 2, " +
- "start(w)," +
- "end(w)")
-
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testRowTimeSession(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'rowtime.rowtime)
-
- val myCountFun = new CountAggFunction
- util.tableEnv.registerFunction("myCountFun", myCountFun)
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- // Expression / Scala API
- val resScala = t
- .window(Session withGap 4.hours on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select(
- 'string,
- myCountFun('string),
- 'int.sum,
- weightAvgFun('long, 'int),
- weightAvgFun('int, 'int) * 2,
- 'w.start)
-
- // String / Java API
- val resJava = t
- .window(JSession.withGap("4.hours").on("rowtime").as("w"))
- .groupBy("w, string")
- .select(
- "string, " +
- "myCountFun(string), " +
- "int.sum, " +
- "weightAvgFun(long, int), " +
- "weightAvgFun(int, int) * 2, " +
- "start(w)"
- )
-
- verifyTableEquals(resJava, resScala)
- }
- @Test
- def testProcTimeSlide(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'proctime.proctime)
-
- val myCountFun = new CountAggFunction
- util.tableEnv.registerFunction("myCountFun", myCountFun)
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- // Expression / Scala API
- val resScala = t
- .window(Slide over 4.hours every 2.hours on 'proctime as 'w)
- .groupBy('w)
- .select(
- myCountFun('string),
- 'int.sum,
- weightAvgFun('long, 'int),
- weightAvgFun('int, 'int) * 2,
- 'w.start,
- 'w.end)
-
- // String / Java API
- val resJava = t
- .window(JSlide.over("4.hours").every("2.hours").on("proctime").as("w"))
- .groupBy("w")
- .select(
- "myCountFun(string), " +
- "int.sum, " +
- "weightAvgFun(long, int), " +
- "weightAvgFun(int, int) * 2, " +
- "start(w)," +
- "end(w)")
-
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testProcTimeTumble(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long,'string, 'proctime.proctime)
-
- val myCountFun = new CountAggFunction
- util.tableEnv.registerFunction("myCountFun", myCountFun)
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- // Expression / Scala API
- val resScala = t
- .window(Tumble over 4.hours on 'proctime as 'w)
- .groupBy('w)
- .select(
- myCountFun('string),
- 'int.sum,
- weightAvgFun('long, 'int),
- weightAvgFun('int, 'int) * 2,
- 'w.start,
- 'w.end)
-
- // String / Java API
- val resJava = t
- .window(JTumble.over("4.hours").on("proctime").as("w"))
- .groupBy("w")
- .select(
- "myCountFun(string), " +
- "int.sum, " +
- "weightAvgFun(long, int), " +
- "weightAvgFun(int, int) * 2, " +
- "start(w)," +
- "end(w)")
-
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testProcTimeSession(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'proctime.proctime)
-
- val myCountFun = new CountAggFunction
- util.tableEnv.registerFunction("myCountFun", myCountFun)
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- // Expression / Scala API
- val resScala = t
- .window(Session withGap 4.hours on 'proctime as 'w)
- .groupBy('w)
- .select(
- myCountFun('string),
- 'int.sum,
- weightAvgFun('long, 'int),
- weightAvgFun('int, 'int) * 2,
- 'w.start,
- 'w.end)
-
- // String / Java API
- val resJava = t
- .window(JSession.withGap("4.hours").on("proctime").as("w"))
- .groupBy("w")
- .select(
- "myCountFun(string), " +
- "int.sum, " +
- "weightAvgFun(long, int), " +
- "weightAvgFun(int, int) * 2, " +
- "start(w), " +
- "end(w)"
- )
-
- verifyTableEquals(resJava, resScala)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala
deleted file mode 100644
index 9430514..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithRetract
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
-import org.apache.flink.table.api.java.{Over => JOver}
-import org.apache.flink.table.api.scala.{Over => SOver, _}
-import org.apache.flink.table.expressions.utils.Func1
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class OverWindowStringExpressionTest extends TableTestBase {
-
- @Test
- def testPartitionedUnboundedOverRow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_ROW as 'w)
- .select('a, 'b.sum over 'w as 'cnt, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_row").as("w"))
- .select("a, SUM(b) OVER w as cnt, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testUnboundedOverRow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver orderBy 'rowtime preceding UNBOUNDED_ROW following CURRENT_ROW as 'w)
- .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(JOver.orderBy("rowtime").preceding("unbounded_row").following("current_row").as("w"))
- .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testPartitionedBoundedOverRow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver partitionBy('a, 'd) orderBy 'rowtime preceding 10.rows as 'w)
- .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(JOver.partitionBy("a, d").orderBy("rowtime").preceding("10.rows").as("w"))
- .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testBoundedOverRow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver orderBy 'rowtime preceding 10.rows following CURRENT_ROW as 'w)
- .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(JOver.orderBy("rowtime").preceding("10.rows").following("current_row").as("w"))
- .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testPartitionedUnboundedOverRange(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_RANGE as 'w)
- .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_range").as("w"))
- .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testUnboundedOverRange(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver orderBy 'rowtime preceding UNBOUNDED_RANGE following CURRENT_RANGE as 'w)
- .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(
- JOver.orderBy("rowtime").preceding("unbounded_range").following("current_range").as("w"))
- .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testPartitionedBoundedOverRange(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver partitionBy('a, 'c) orderBy 'rowtime preceding 10.minutes as 'w)
- .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(JOver.partitionBy("a, c").orderBy("rowtime").preceding("10.minutes").as("w"))
- .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testBoundedOverRange(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightAvgFun = new WeightedAvg
- util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
-
- val resScala = t
- .window(SOver orderBy 'rowtime preceding 4.hours following CURRENT_RANGE as 'w)
- .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
- val resJava = t
- .window(JOver.orderBy("rowtime").preceding("4.hours").following("current_range").as("w"))
- .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
-
- verifyTableEquals(resScala, resJava)
- }
-
- @Test
- def testScalarFunctionsOnOverWindow(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
-
- val weightedAvg = new WeightedAvgWithRetract
- val plusOne = Func1
- util.addFunction("plusOne", plusOne)
- util.addFunction("weightedAvg", weightedAvg)
-
- val resScala = t
- .window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_ROW as 'w)
- .select(
- array('a.sum over 'w, 'a.count over 'w),
- plusOne('b.sum over 'w as 'wsum) as 'd,
- ('a.count over 'w).exp(),
- (weightedAvg('a, 'b) over 'w) + 1,
- "AVG:".toExpr + (weightedAvg('a, 'b) over 'w))
-
- val resJava = t
- .window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_row").as("w"))
- .select(
- s"""
- |ARRAY(SUM(a) OVER w, COUNT(a) OVER w),
- |plusOne(SUM(b) OVER w AS wsum) AS d,
- |EXP(COUNT(a) OVER w),
- |(weightedAvg(a, b) OVER w) + 1,
- |'AVG:' + (weightedAvg(a, b) OVER w)
- """.stripMargin)
-
- verifyTableEquals(resScala, resJava)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala
deleted file mode 100644
index dc2e92f..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.stringexpr
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class UnionStringExpressionTest extends TableTestBase {
-
- @Test
- def testUnionAll(): Unit = {
- val util = streamTestUtil()
- val t1 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
- val t2 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
-
- val resScala = t1.unionAll(t2).select('int)
- val resJava = t1.unionAll(t2).select("int")
- verifyTableEquals(resJava, resScala)
- }
-
- @Test
- def testUnionAllWithFilter(): Unit = {
- val util = streamTestUtil()
- val t1 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
- val t2 = util.addTable[(Int, Long, Double, String)]('int, 'long, 'double, 'string)
-
- val resScala = t1.unionAll(t2.select('int, 'long, 'string)).filter('int < 2).select('int)
- val resJava = t1.unionAll(t2.select("int, long, string")).filter("int < 2").select("int")
- verifyTableEquals(resJava, resScala)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
deleted file mode 100644
index 2f0c57c..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.stringexpr
-
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api._
-import org.apache.flink.table.utils._
-import org.apache.flink.types.Row
-import org.junit.Test
-
-class UserDefinedTableFunctionStringExpressionTest extends TableTestBase {
-
- @Test
- def testJoin(): Unit = {
-
- val util = streamTestUtil()
- val sTab = util.addTable[(Int, Long, String)]('a, 'b, 'c)
- val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
- val jTab = util.addJavaTable[Row](typeInfo,"MyTab","a, b, c")
-
- // test cross join
- val func1 = new TableFunc1
- util.javaTableEnv.registerFunction("func1", func1)
- var scalaTable = sTab.join(func1('c) as 's).select('c, 's)
- var javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c).as(s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test left outer join
- scalaTable = sTab.leftOuterJoin(func1('c) as 's).select('c, 's)
- javaTable = jTab.leftOuterJoin(new Table(util.javaTableEnv, "func1(c)").as("s")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test overloading
- scalaTable = sTab.join(func1('c, "$") as 's).select('c, 's)
- javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test custom result type
- val func2 = new TableFunc2
- util.javaTableEnv.registerFunction("func2", func2)
- scalaTable = sTab.join(func2('c) as ('name, 'len)).select('c, 'name, 'len)
- javaTable = jTab.join(
- new Table(util.javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
- verifyTableEquals(scalaTable, javaTable)
-
- // test hierarchy generic type
- val hierarchy = new HierarchyTableFunction
- util.javaTableEnv.registerFunction("hierarchy", hierarchy)
- scalaTable = sTab.join(hierarchy('c) as ('name, 'adult, 'len)).select('c, 'name, 'len, 'adult)
- javaTable = jTab.join(new Table(util.javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
- .select("c, name, len, adult")
- verifyTableEquals(scalaTable, javaTable)
-
- // test pojo type
- val pojo = new PojoTableFunc
- util.javaTableEnv.registerFunction("pojo", pojo)
- scalaTable = sTab.join(pojo('c)).select('c, 'name, 'age)
- javaTable = jTab.join(new Table(util.javaTableEnv, "pojo(c)")).select("c, name, age")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with filter
- scalaTable = sTab.join(func2('c) as ('name, 'len)).select('c, 'name, 'len).filter('len > 2)
- javaTable = jTab.join(new Table(util.javaTableEnv, "func2(c) as (name, len)"))
- .select("c, name, len").filter("len > 2")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with scalar function
- scalaTable = sTab.join(func1('c.substring(2)) as 's).select('a, 'c, 's)
- javaTable = jTab.join(
- new Table(util.javaTableEnv, "func1(substring(c, 2)) as (s)")).select("a, c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala
deleted file mode 100644
index 879fca3..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.api.TableException
-import org.apache.flink.types.Row
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-import scala.collection.mutable
-
-class CalcValidationTest extends TableTestBase {
-
- @Test(expected = classOf[TableException])
- def testAsWithToManyFields(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("no")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test(expected = classOf[TableException])
- def testAsWithAmbiguousFields(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'b)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("no")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test(expected = classOf[TableException])
- def testOnlyFieldRefInAs(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b as 'c, 'd)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("no")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala
deleted file mode 100644
index 5cec6fc..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class GroupAggregationsValidationTest extends TableTestBase {
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
- val overAgg = new OverAgg0
- table.select(overAgg('a, 'b))
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupingOnNonExistentField(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val ds = table
- // must fail. '_foo is not a valid field
- .groupBy('_foo)
- .select('a.avg)
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupingInvalidSelection(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val ds = table
- .groupBy('a, 'b)
- // must fail. 'c is not a grouping key or aggregation
- .select('c)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala
deleted file mode 100644
index e046986..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class GroupWindowAggregationsValidationTest extends TableTestBase {
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val overAgg = new OverAgg0
- table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select(overAgg('long, 'int))
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowProperty(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .groupBy('string)
- .select('string, 'string.start) // property in non windowed table
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupByWithoutWindowAlias(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidRowTimeRef(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
- .groupBy('w2)
- .select('string)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidTumblingSize(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Tumble over "WRONG" on 'long as 'w) // string is not a valid interval
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testTumbleUdAggWithInvalidArgs(): Unit = {
- val util = streamTestUtil()
- val weightedAvg = new WeightedAvgWithMerge
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Tumble over 2.hours on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidSlidingSize(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Slide over "WRONG" every "WRONG" on 'long as 'w) // string is not a valid interval
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidSlidingSlide(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- // row and time intervals may not be mixed
- .window(Slide over 12.rows every 1.minute on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testSlideUdAggWithInvalidArgs(): Unit = {
- val util = streamTestUtil()
- val weightedAvg = new WeightedAvgWithMerge
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Slide over 2.hours every 30.minutes on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidSessionGap(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- // row interval is not valid for session windows
- .window(Session withGap 10.rows on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowAlias1(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Session withGap 100.milli on 'long as 1 + 1) // expression instead of a symbol
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowAlias2(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- // field name "string" is already present
- .window(Session withGap 100.milli on 'long as 'string)
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testSessionUdAggWithInvalidArgs(): Unit = {
- val util = streamTestUtil()
- val weightedAvg = new WeightedAvgWithMerge
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- table
- .window(Session withGap 2.hours on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowPropertyOnRowCountsTumblingWindow(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowPropertyOnRowCountsSlidingWindow(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- table
- .window(Slide over 10.rows every 5.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala
deleted file mode 100644
index cb84ae4..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithRetract
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{Table, ValidationException}
-import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
-import org.junit.Test
-
-class OverWindowValidationTest extends TableTestBase {
- private val streamUtil: StreamTableTestUtil = streamTestUtil()
- val table: Table = streamUtil.addTable[(Int, String, Long)]("MyTable",
- 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowAlias(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
- .select('c, 'b.count over 'x)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testOrderBy(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'abc preceding 2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPrecedingAndFollowingUsingIsLiteral(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2 following "xx" as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPrecedingAndFollowingUsingSameType(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_RANGE as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPartitionByWithUnresolved(): Unit = {
- val result = table
- .window(Over partitionBy 'a + 'b orderBy 'rowtime preceding 2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPartitionByWithNotKeyType(): Unit = {
- val table2 = streamUtil.addTable[(Int, String, Either[Long, String])]("MyTable2", 'a, 'b, 'c)
-
- val result = table2
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPrecedingValue(): Unit = {
- val result = table
- .window(Over orderBy 'rowtime preceding -1.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testFollowingValue(): Unit = {
- val result = table
- .window(Over orderBy 'rowtime preceding 1.rows following -2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUdAggWithInvalidArgs(): Unit = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
- .select('c, weightedAvg('b, 'a) over 'w)
- streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test
- def testAccessesWindowProperties(): Unit = {
- thrown.expect(classOf[ValidationException])
- thrown.expectMessage("Window start and end properties are not available for Over windows.")
-
- table
- .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
- .select('c, 'a.count over 'w, 'w.start, 'w.end)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala
deleted file mode 100644
index 72fb0b6..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.runtime.datastream.table.{TestAppendSink, TestUpsertSink}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class TableSinksValidationTest extends TableTestBase {
-
- @Test(expected = classOf[TableException])
- def testAppendSinkOnUpdatingTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'id, 'num, 'text)
-
- t.groupBy('text)
- .select('text, 'id.count, 'num.sum)
- .writeToSink(new TestAppendSink)
-
- // must fail because table is not append-only
- env.execute()
- }
-
- @Test(expected = classOf[TableException])
- def testUpsertSinkOnUpdatingTableWithoutFullKey(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env)
- .assignAscendingTimestamps(_._1.toLong)
- .toTable(tEnv, 'id, 'num, 'text)
-
- t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
- .groupBy('len, 'cTrue)
- .select('len, 'id.count, 'num.sum)
- .writeToSink(new TestUpsertSink(Array("len", "cTrue"), false))
-
- // must fail because table is updating table without full key
- env.execute()
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala
deleted file mode 100644
index bcfa146..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.table.api.TableException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.table.{TestProctimeSource, TestRowtimeSource}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class TableSourceValidationTest extends TableTestBase {
-
- @Test(expected = classOf[TableException])
- def testRowtimeTableSourceWithEmptyName(): Unit = {
- val util = streamTestUtil()
- util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource(" "))
-
- val t = util.tableEnv.scan("rowTimeT")
- .select('id)
-
- util.tableEnv.optimize(t.getRelNode, false)
- }
-
- @Test(expected = classOf[TableException])
- def testProctimeTableSourceWithEmptyName(): Unit = {
- val util = streamTestUtil()
- util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource(" "))
-
- val t = util.tableEnv.scan("procTimeT")
- .select('id)
-
- util.tableEnv.optimize(t.getRelNode, false)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala
deleted file mode 100644
index 7a684d1..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import java.math.BigDecimal
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.scala.{Tumble, _}
-import org.apache.flink.table.api.{TableEnvironment, TableException, ValidationException}
-import org.apache.flink.table.runtime.datastream.table.TimeAttributesITCase._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class TimeAttributesValidationTest extends TableTestBase {
-
- val data = List(
- (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
- (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
- (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
- (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
- (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
- (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
- (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
-
- @Test(expected = classOf[TableException])
- def testInvalidTimeCharacteristic(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidUseOfRowtime(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- .select('rowtime.rowtime)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidUseOfRowtime2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val stream = env
- .fromCollection(data)
- .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
- stream
- .toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
- .window(Tumble over 2.millis on 'rowtime as 'w)
- .groupBy('w)
- .select('w.end.rowtime, 'int.count as 'int) // no rowtime on non-window reference
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala
deleted file mode 100644
index 1767d9f..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.types.Row
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-import scala.collection.mutable
-
-class UnionValidationTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testUnionFieldsNameNotOverlap1(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
-
- val unionDs = ds1.unionAll(ds2)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- assertEquals(true, StreamITCase.testResults.isEmpty)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnionFieldsNameNotOverlap2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .select('a, 'b, 'c)
-
- val unionDs = ds1.unionAll(ds2)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- assertEquals(true, StreamITCase.testResults.isEmpty)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnionTablesFromDifferentEnv(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env)
- val tEnv2 = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv1, 'a, 'b, 'c)
- val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv2, 'a, 'b, 'c)
-
- // Must fail. Tables are bound to different TableEnvironments.
- ds1.unionAll(ds2)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala
deleted file mode 100644
index d2fddca..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnsupportedOpsValidationTest.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.junit.Test
-
-class UnsupportedOpsValidationTest extends StreamingMultipleProgramsTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testSort(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).orderBy('_1.desc)
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoin(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.join(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.union(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testIntersect(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.intersect(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testIntersectAll(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.intersectAll(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMinus(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.minus(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMinusAll(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.minusAll(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testLimit(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.limit(0,5)
- }
-}
[16/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentITCase.scala
deleted file mode 100644
index 9e6dd33..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentITCase.scala
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch
-
-import java.util
-
-import org.apache.flink.api.java.typeutils.GenericTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit.Assert.assertTrue
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class TableEnvironmentITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSimpleRegister(): Unit = {
-
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet(tableName, ds)
- val t = tEnv.scan(tableName).select('_1, '_2, '_3)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRegisterWithFields(): Unit = {
-
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet(tableName, ds, 'a, 'b, 'c)
- val t = tEnv.scan(tableName).select('a, 'b)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" +
- "7,4\n" + "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
- "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[TableException])
- def testRegisterExistingDataSet(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds1)
- val ds2 = CollectionDataSets.get5TupleDataSet(env)
- // Must fail. Name is already in use.
- tEnv.registerDataSet("MyTable", ds2)
- }
-
- @Test(expected = classOf[TableException])
- def testScanUnregisteredTable(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- // Must fail. No table registered under that name.
- tEnv.scan("someTable")
- }
-
- @Test
- def testTableRegister(): Unit = {
-
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- tEnv.registerTable(tableName, t)
-
- val regT = tEnv.scan(tableName).select('a, 'b).filter('a > 8)
-
- val expected = "9,4\n" + "10,4\n" +
- "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
- "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" +
- "19,6\n" + "20,6\n" + "21,6\n"
-
- val results = regT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[TableException])
- def testRegisterExistingTable(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", t1)
- val t2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
- // Must fail. Name is already in use.
- tEnv.registerDataSet("MyTable", t2)
- }
-
- @Test(expected = classOf[TableException])
- def testRegisterTableFromOtherEnv(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env, config)
- val tEnv2 = TableEnvironment.getTableEnvironment(env, config)
-
- val t1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv1)
- // Must fail. Table is bound to different TableEnvironment.
- tEnv2.registerTable("MyTable", t1)
- }
-
- @Test
- def testToTable(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .select('a, 'b, 'c)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testToTableFromCaseClass(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- SomeCaseClass("Peter", 28, 4000.00, "Sales"),
- SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
- SomeCaseClass("Lucy", 42, 6000.00, "HR"))
-
- val t = env.fromCollection(data)
- .toTable(tEnv, 'a, 'b, 'c, 'd)
- .select('a, 'b, 'c, 'd)
-
- val expected: String =
- "Peter,28,4000.0,Sales\n" +
- "Anna,56,10000.0,Engineering\n" +
- "Lucy,42,6000.0,HR\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testToTableFromAndToCaseClass(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- SomeCaseClass("Peter", 28, 4000.00, "Sales"),
- SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
- SomeCaseClass("Lucy", 42, 6000.00, "HR"))
-
- val t = env.fromCollection(data)
- .toTable(tEnv, 'a, 'b, 'c, 'd)
- .select('a, 'b, 'c, 'd)
-
- val expected: String =
- "SomeCaseClass(Peter,28,4000.0,Sales)\n" +
- "SomeCaseClass(Anna,56,10000.0,Engineering)\n" +
- "SomeCaseClass(Lucy,42,6000.0,HR)\n"
- val results = t.toDataSet[SomeCaseClass].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithToManyFields(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- CollectionDataSets.get3TupleDataSet(env)
- // Must fail. Number of fields does not match.
- .toTable(tEnv, 'a, 'b, 'c, 'd)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithAmbiguousFields(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- CollectionDataSets.get3TupleDataSet(env)
- // Must fail. Field names not unique.
- .toTable(tEnv, 'a, 'b, 'b)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithNonFieldReference1(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // Must fail. as() can only have field references
- CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a + 1, 'b, 'c)
- }
-
- @Test(expected = classOf[TableException])
- def testToTableWithNonFieldReference2(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // Must fail. as() can only have field references
- CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a as 'foo, 'b, 'c)
- }
-
- @Test(expected = classOf[TableException])
- def testGenericRow() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // use null value the enforce GenericType
- val dataSet = env.fromElements(Row.of(null))
- assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
- assertTrue(dataSet.getType().getTypeClass == classOf[Row])
-
- // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
- tableEnv.fromDataSet(dataSet)
- }
-
- @Test(expected = classOf[TableException])
- def testGenericRowWithAlias() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
-
- // use null value the enforce GenericType
- val dataSet = env.fromElements(Row.of(null))
- assertTrue(dataSet.getType().isInstanceOf[GenericTypeInfo[_]])
- assertTrue(dataSet.getType().getTypeClass == classOf[Row])
-
- // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
- tableEnv.fromDataSet(dataSet, "nullField")
- }
-}
-
-object TableEnvironmentITCase {
-
- @Parameterized.Parameters(name = "Table config = {0}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](
- Array(TableProgramsTestBase.DEFAULT)
- ).asJava
- }
-}
-
-case class SomeCaseClass(name: String, age: Int, salary: Double, department: String) {
- def this() { this("", 0, 0.0, "") }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala
new file mode 100644
index 0000000..f492995
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableEnvironmentTest.scala
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.batch
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo._
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.{GenericTypeInfo, RowTypeInfo, TupleTypeInfo, TypeExtractor}
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.{Alias, UnresolvedFieldReference}
+import org.apache.flink.table.runtime.types.CRowTypeInfo
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{MockTableEnvironment, TableTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class TableEnvironmentTest extends TableTestBase {
+
+ val tEnv = new MockTableEnvironment
+
+ val tupleType = new TupleTypeInfo(
+ INT_TYPE_INFO,
+ STRING_TYPE_INFO,
+ DOUBLE_TYPE_INFO)
+
+ val rowType = new RowTypeInfo(INT_TYPE_INFO, STRING_TYPE_INFO,DOUBLE_TYPE_INFO)
+
+ val cRowType = new CRowTypeInfo(rowType)
+
+ val caseClassType: TypeInformation[CClass] = implicitly[TypeInformation[CClass]]
+
+ val pojoType: TypeInformation[PojoClass] = TypeExtractor.createTypeInfo(classOf[PojoClass])
+
+ val atomicType = INT_TYPE_INFO
+
+ val genericRowType = new GenericTypeInfo[Row](classOf[Row])
+
+ @Test
+ def testGetFieldInfoRow(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(rowType)
+
+ fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoRowNames(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ rowType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTuple(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(tupleType)
+
+ fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClass(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(caseClassType)
+
+ fieldInfo._1.zip(Array("cf1", "cf2", "cf3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojo(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(pojoType)
+
+ fieldInfo._1.zip(Array("pf1", "pf2", "pf3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoAtomic(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(atomicType)
+
+ fieldInfo._1.zip(Array("f0")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTupleNames(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClassNames(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojoNames2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ UnresolvedFieldReference("pf3"),
+ UnresolvedFieldReference("pf1"),
+ UnresolvedFieldReference("pf2")
+ ))
+
+ fieldInfo._1.zip(Array("pf3", "pf1", "pf2")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoAtomicName1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ atomicType,
+ Array(UnresolvedFieldReference("name")))
+
+ fieldInfo._1.zip(Array("name")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTupleAlias1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ Alias(UnresolvedFieldReference("f0"), "name1"),
+ Alias(UnresolvedFieldReference("f1"), "name2"),
+ Alias(UnresolvedFieldReference("f2"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTupleAlias2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ Alias(UnresolvedFieldReference("f2"), "name1"),
+ Alias(UnresolvedFieldReference("f0"), "name2"),
+ Alias(UnresolvedFieldReference("f1"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClassAlias1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ Alias(UnresolvedFieldReference("cf1"), "name1"),
+ Alias(UnresolvedFieldReference("cf2"), "name2"),
+ Alias(UnresolvedFieldReference("cf3"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClassAlias2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ Alias(UnresolvedFieldReference("cf3"), "name1"),
+ Alias(UnresolvedFieldReference("cf1"), "name2"),
+ Alias(UnresolvedFieldReference("cf2"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojoAlias1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ Alias(UnresolvedFieldReference("pf1"), "name1"),
+ Alias(UnresolvedFieldReference("pf2"), "name2"),
+ Alias(UnresolvedFieldReference("pf3"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojoAlias2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ Alias(UnresolvedFieldReference("pf3"), "name1"),
+ Alias(UnresolvedFieldReference("pf1"), "name2"),
+ Alias(UnresolvedFieldReference("pf2"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testSqlWithoutRegisteringForBatchTables(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
+
+ val sqlTable = util.tableEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a, b, c"),
+ term("where", ">(b, 12)"))
+
+ util.verifyTable(sqlTable, expected)
+
+ val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
+
+ val sqlTable2 = util.tableEnv.sql(s"SELECT d, e, f FROM $table, $table2 WHERE c = d")
+
+ val join = unaryNode(
+ "DataSetJoin",
+ binaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ batchTableNode(1),
+ term("select", "c")),
+ term("where", "=(c, d)"),
+ term("join", "c, d, e, f"),
+ term("joinType", "InnerJoin"))
+
+ val expected2 = unaryNode(
+ "DataSetCalc",
+ join,
+ term("select", "d, e, f"))
+
+ util.verifyTable(sqlTable2, expected2)
+ }
+
+ @Test
+ def testSqlWithoutRegisteringForStreamTables(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
+
+ val sqlTable = util.tableEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a, b, c"),
+ term("where", ">(b, 12)"))
+
+ util.verifyTable(sqlTable, expected)
+
+ val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
+
+ val sqlTable2 = util.tableEnv.sql(s"SELECT d, e, f FROM $table2 " +
+ s"UNION ALL SELECT a, b, c FROM $table")
+
+ val expected2 = binaryNode(
+ "DataStreamUnion",
+ streamTableNode(1),
+ streamTableNode(0),
+ term("union all", "d, e, f"))
+
+ util.verifyTable(sqlTable2, expected2)
+ }
+
+}
+
+case class CClass(cf1: Int, cf2: String, cf3: Double)
+
+class PojoClass(var pf1: Int, var pf2: String, var pf3: Double) {
+ def this() = this(0, "", 0.0)
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala
new file mode 100644
index 0000000..57e32ad
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSchemaTest.scala
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Assert.{assertEquals, assertTrue}
+import org.junit.Test
+
+class TableSchemaTest extends TableTestBase {
+
+ @Test
+ def testBatchTableSchema(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
+ val schema = table.getSchema
+
+ assertEquals("a", schema.getColumnNames.apply(0))
+ assertEquals("b", schema.getColumnNames.apply(1))
+
+ assertEquals(Types.INT, schema.getTypes.apply(0))
+ assertEquals(Types.STRING, schema.getTypes.apply(1))
+
+ val expectedString = "root\n" +
+ " |-- a: Integer\n" +
+ " |-- b: String\n"
+ assertEquals(expectedString, schema.toString)
+
+ assertTrue(schema.getColumnName(3).isEmpty)
+ assertTrue(schema.getType(-1).isEmpty)
+ assertTrue(schema.getType("c").isEmpty)
+ }
+
+ @Test
+ def testStreamTableSchema(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
+ val schema = table.getSchema
+
+ assertEquals("a", schema.getColumnNames.apply(0))
+ assertEquals("b", schema.getColumnNames.apply(1))
+
+ assertEquals(Types.INT, schema.getTypes.apply(0))
+ assertEquals(Types.STRING, schema.getTypes.apply(1))
+
+ val expectedString = "root\n" +
+ " |-- a: Integer\n" +
+ " |-- b: String\n"
+ assertEquals(expectedString, schema.toString)
+
+ assertTrue(schema.getColumnName(3).isEmpty)
+ assertTrue(schema.getType(-1).isEmpty)
+ assertTrue(schema.getType("c").isEmpty)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSinkITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSinkITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSinkITCase.scala
deleted file mode 100644
index 8fca992..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSinkITCase.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch
-
-import java.io.File
-
-import org.apache.flink.api.scala.{ExecutionEnvironment, _}
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.sinks.CsvTableSink
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-
-@RunWith(classOf[Parameterized])
-class TableSinkITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testBatchTableSink(): Unit = {
-
- val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
- tmpFile.deleteOnExit()
- val path = tmpFile.toURI.toString
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- env.setParallelism(4)
-
- val input = CollectionDataSets.get3TupleDataSet(env)
- .map(x => x).setParallelism(4) // increase DOP to 4
-
- val results = input.toTable(tEnv, 'a, 'b, 'c)
- .where('a < 5 || 'a > 17)
- .select('c, 'b)
- .writeToSink(new CsvTableSink(path, fieldDelim = "|"))
-
- env.execute()
-
- val expected = Seq(
- "Hi|1", "Hello|2", "Hello world|2", "Hello world, how are you?|3",
- "Comment#12|6", "Comment#13|6", "Comment#14|6", "Comment#15|6").mkString("\n")
-
- TestBaseUtils.compareResultsByLinesInMemory(expected, path)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSourceITCase.scala
deleted file mode 100644
index 6ed2cf1..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/TableSourceITCase.scala
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch
-
-import org.apache.flink.api.scala.ExecutionEnvironment
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.utils.{CommonTestData, TestFilterableTableSource}
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class TableSourceITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testCsvTableSource(): Unit = {
-
- val csvTable = CommonTestData.getCsvTableSource
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- tEnv.registerTableSource("csvTable", csvTable)
- val results = tEnv.sql(
- "SELECT id, `first`, `last`, score FROM csvTable").collect()
-
- val expected = Seq(
- "1,Mike,Smith,12.3",
- "2,Bob,Taylor,45.6",
- "3,Sam,Miller,7.89",
- "4,Peter,Smith,0.12",
- "5,Liz,Williams,34.5",
- "6,Sally,Miller,6.78",
- "7,Alice,Smith,90.1",
- "8,Kelly,Williams,2.34").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCsvTableSourceWithProjection(): Unit = {
- val csvTable = CommonTestData.getCsvTableSource
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- tEnv.registerTableSource("csvTable", csvTable)
-
- val results = tEnv
- .scan("csvTable")
- .where('score < 20)
- .select('last, 'id.floor(), 'score * 2)
- .collect()
-
- val expected = Seq(
- "Smith,1,24.6",
- "Miller,3,15.78",
- "Smith,4,0.24",
- "Miller,6,13.56",
- "Williams,8,4.68").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testNestedBatchTableSourceSQL(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- val nestedTable = CommonTestData.getNestedTableSource
-
- tableEnv.registerTableSource("NestedPersons", nestedTable)
-
- val result = tableEnv.sql("SELECT NestedPersons.firstName, NestedPersons.lastName," +
- "NestedPersons.address.street, NestedPersons.address.city AS city " +
- "FROM NestedPersons " +
- "WHERE NestedPersons.address.city LIKE 'Dublin'").collect()
-
- val expected = "Bob,Taylor,Pearse Street,Dublin"
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testTableSourceWithFilterable(): Unit = {
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- tableEnv.registerTableSource(tableName, new TestFilterableTableSource)
- val results = tableEnv
- .scan(tableName)
- .where("amount > 4 && price < 9")
- .select("id, name")
- .collect()
-
- val expected = Seq(
- "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsITCase.scala
deleted file mode 100644
index 8368817..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsITCase.scala
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-import java.sql.Timestamp
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMergeAndReset
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class AggregationsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testAggregationTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1), min(_1), max(_1), count(_1), avg(_1) FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231,1,21,21,11"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1) FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDataSetAggregation(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1) FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationDataTypes(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), avg(b), avg(c), avg(d), avg(e), avg(f), count(g), " +
- "min(g), min('Ciao'), max(g), max('Ciao'), sum(CAST(f AS DECIMAL)) FROM MyTable"
-
- val ds = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'f, 'g)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,1,1,1.5,1.5,2,Ciao,Ciao,Hello,Ciao,3.0"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), sum(a), count(a), avg(b), sum(b) " +
- "FROM MyTable"
-
- val ds = env.fromElements((1: Byte, 1: Short), (2: Byte, 2: Short)).toTable(tEnv, 'a, 'b)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,3,2,1,3"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableAggregationWithArithmetic(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a + 2) + 2, count(b) + 5 " +
- "FROM MyTable"
-
- val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv, 'a, 'b)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "5.5,7"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAggregationWithTwoCount(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT count(_1), count(_2) FROM MyTable"
-
- val ds = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "2,2"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-
- @Test
- def testAggregationAfterProjection(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM " +
- "(SELECT _1 as a, _2 as b, _3 as c FROM MyTable)"
-
- val ds = env.fromElements(
- (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
- (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,3,2"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDistinctAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT sum(_1) as a, count(distinct _3) as b FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "231,21"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupedDistinctAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT _2, avg(distinct _1) as a, count(_3) as b FROM MyTable GROUP BY _2"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected =
- "6,18,6\n5,13,5\n4,8,4\n3,5,3\n2,2,2\n1,1,1"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testGroupingSetAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery =
- "SELECT _2, _3, avg(_1) as a, GROUP_ID() as g FROM MyTable GROUP BY GROUPING SETS (_2, _3)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
-
- val expected =
- "6,null,18,1\n5,null,13,1\n4,null,8,1\n3,null,5,1\n2,null,2,1\n1,null,1,1\n" +
- "null,Luke Skywalker,6,2\nnull,I am fine.,5,2\nnull,Hi,1,2\n" +
- "null,Hello world, how are you?,4,2\nnull,Hello world,3,2\nnull,Hello,2,2\n" +
- "null,Comment#9,15,2\nnull,Comment#8,14,2\nnull,Comment#7,13,2\n" +
- "null,Comment#6,12,2\nnull,Comment#5,11,2\nnull,Comment#4,10,2\n" +
- "null,Comment#3,9,2\nnull,Comment#2,8,2\nnull,Comment#15,21,2\n" +
- "null,Comment#14,20,2\nnull,Comment#13,19,2\nnull,Comment#12,18,2\n" +
- "null,Comment#11,17,2\nnull,Comment#10,16,2\nnull,Comment#1,7,2"
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testAggregateEmptyDataSets(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT avg(a), sum(a), count(b) " +
- "FROM MyTable where a = 4 group by a"
-
- val sqlQuery2 = "SELECT avg(a), sum(a), count(b) " +
- "FROM MyTable where a = 4"
-
- val sqlQuery3 = "SELECT avg(a), sum(a), count(b) " +
- "FROM MyTable"
-
- val ds = env.fromElements(
- (1: Byte, 1: Short),
- (2: Byte, 2: Short))
- .toTable(tEnv, 'a, 'b)
-
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
- val result2 = tEnv.sql(sqlQuery2)
- val result3 = tEnv.sql(sqlQuery3)
-
- val results = result.toDataSet[Row].collect()
- val expected = Seq.empty
- val results2 = result2.toDataSet[Row].collect()
- val expected2 = "null,null,0"
- val results3 = result3.toDataSet[Row].collect()
- val expected3 = "1,3,2"
-
- assert(results.equals(expected),
- "Empty result is expected for grouped set, but actual: " + results)
- TestBaseUtils.compareResultAsText(results2.asJava, expected2)
- TestBaseUtils.compareResultAsText(results3.asJava, expected3)
- }
-
- @Test
- def testTumbleWindowAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.registerFunction("countFun", new CountAggFunction)
- tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
-
- val sqlQuery =
- "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
- "FROM T " +
- "GROUP BY b, TUMBLE(ts, INTERVAL '3' SECOND)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- // create timestamps
- .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
- tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- val expected = Seq(
- "1,1,1,1,1",
- "2,2,1,2,2", "2,3,1,2,3",
- "3,9,2,3,4", "3,6,1,3,6",
- "4,15,2,4,7", "4,19,2,4,9",
- "5,11,1,5,11", "5,39,3,5,13", "5,15,1,5,15",
- "6,33,2,6,16", "6,57,3,6,19", "6,21,1,6,21"
- ).mkString("\n")
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testHopWindowAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.registerFunction("countFun", new CountAggFunction)
- tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
-
- env.setParallelism(1)
-
- val sqlQuery =
- "SELECT b, SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), wAvgWithMergeAndReset(a, a)" +
- "FROM T " +
- "GROUP BY b, HOP(ts, INTERVAL '2' SECOND, INTERVAL '4' SECOND)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- // create timestamps
- .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
- tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- val expected = Seq(
- "1,1,1,1,1","1,1,1,1,1",
- "2,5,2,2,2","2,5,2,2,2",
- "3,9,2,3,4", "3,15,3,3,5", "3,6,1,3,6",
- "4,7,1,4,7", "4,24,3,4,8", "4,27,3,4,9", "4,10,1,4,10",
- "5,11,1,5,11", "5,36,3,5,12", "5,54,4,5,13", "5,29,2,5,14",
- "6,33,2,6,16", "6,70,4,6,17", "6,78,4,6,19", "6,41,2,6,20"
- ).mkString("\n")
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-
- @Test
- def testSessionWindowAggregate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.registerFunction("countFun", new CountAggFunction)
- tEnv.registerFunction("wAvgWithMergeAndReset", new WeightedAvgWithMergeAndReset)
-
- env.setParallelism(1)
-
- val sqlQuery =
- "SELECT MIN(a), MAX(a), SUM(a), countFun(c), wAvgWithMergeAndReset(b, a), " +
- "wAvgWithMergeAndReset(a, a)" +
- "FROM T " +
- "GROUP BY SESSION(ts, INTERVAL '4' SECOND)"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- // create timestamps
- .filter(x => (x._2 % 2) == 0)
- .map(x => (x._1, x._2, x._3, new Timestamp(x._1 * 1000)))
- tEnv.registerDataSet("T", ds, 'a, 'b, 'c, 'ts)
-
- val result = tEnv.sql(sqlQuery).toDataSet[Row].collect()
- val expected = Seq(
- "2,10,39,6,3,7",
- "16,21,111,6,6,18"
- ).mkString("\n")
-
- TestBaseUtils.compareResultAsText(result.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala
index bf150c3..b987e40 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/AggregationsTest.scala
@@ -18,26 +18,145 @@
package org.apache.flink.table.api.scala.batch.sql
import org.apache.flink.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
import org.apache.flink.table.api.scala._
import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
import org.junit.Test
+/**
+ * Test for testing aggregate plans.
+ */
class AggregationsTest extends TableTestBase {
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
+ @Test
+ def testAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable"
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ batchTableNode(0),
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testAggregateWithFilter(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1"
+
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", "=(a, 1)")
+ )
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ calcNode,
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testGroupAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable GROUP BY a"
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "a"),
+ term("select",
+ "a",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ val expected = unaryNode(
+ "DataSetCalc",
+ aggregate,
+ term("select",
+ "EXPR$0",
+ "EXPR$1",
+ "EXPR$2")
+ )
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testGroupAggregateWithFilter(): Unit = {
val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("T", 'a, 'b, 'c)
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
- util.addFunction("overAgg", new OverAgg0)
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1 GROUP BY a"
- val sqlQuery = "SELECT overAgg(b, a) FROM T"
- util.tEnv.sql(sqlQuery)
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select","a", "b", "c") ,
+ term("where","=(a, 1)")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ calcNode,
+ term("groupBy", "a"),
+ term("select",
+ "a",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ val expected = unaryNode(
+ "DataSetCalc",
+ aggregate,
+ term("select",
+ "EXPR$0",
+ "EXPR$1",
+ "EXPR$2")
+ )
+ util.verifySql(sqlQuery, expected)
}
+
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CalcITCase.scala
deleted file mode 100644
index 00f4782..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CalcITCase.scala
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.sql
-
-
-import java.sql.{Date, Time, Timestamp}
-import java.util
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.sql.FilterITCase.MyHashCode
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class CalcITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSelectStarFromTable(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectStarFromDataSet(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectAll(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT a, b, c FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectWithNaming(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT _1 as a, _2 as b FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
- "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
-
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidFields(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT a, foo FROM MyTable"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- tEnv.sql(sqlQuery)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE false"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE true"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
- "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
- "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
- "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
- "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
- "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnString(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE c LIKE '%world%'"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnInteger(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)=0"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
- "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
- "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
- "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDisjunctivePredicate(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE a < 2 OR a > 20"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterWithAnd(): Unit = {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)<>0 AND MOD(b,2)=0"
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", ds)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
- "9,4,Comment#3\n" + "17,6,Comment#11\n" +
- "19,6,Comment#13\n" + "21,6,Comment#15\n"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAdvancedDataTypes(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val sqlQuery = "SELECT a, b, c, DATE '1984-07-12', TIME '14:34:24', " +
- "TIMESTAMP '1984-07-12 14:34:24' FROM MyTable"
-
- val ds = env.fromElements((
- Date.valueOf("1984-07-12"),
- Time.valueOf("14:34:24"),
- Timestamp.valueOf("1984-07-12 14:34:24")))
- tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery)
-
- val expected = "1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
- "1984-07-12,14:34:24,1984-07-12 14:34:24.0"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedScalarFunction(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- tEnv.registerFunction("hashCode",
- org.apache.flink.table.api.scala.batch.table.OldHashCode)
- tEnv.registerFunction("hashCode", MyHashCode)
-
- val ds = env.fromElements("a", "b", "c")
- tEnv.registerDataSet("MyTable", ds, 'text)
-
- val result = tEnv.sql("SELECT hashCode(text) FROM MyTable")
-
- val expected = "97\n98\n99"
- val results = result.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
-
-object FilterITCase {
- object MyHashCode extends ScalarFunction {
- def eval(s: String): Int = s.hashCode()
- }
-}
-
-object CalcITCase {
-
- @Parameterized.Parameters(name = "Table config = {0}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](
- Array(TableProgramsTestBase.DEFAULT),
- Array(TableProgramsTestBase.NO_NULL)).asJava
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala
new file mode 100644
index 0000000..6ae48f8
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/CompositeFlatteningTest.scala
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.batch.sql
+
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+
+class CompositeFlatteningTest extends TableTestBase {
+
+ @Test
+ def testMultipleFlattening(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "a._1 AS _1",
+ "a._2 AS _2",
+ "c",
+ "b._1 AS _10",
+ "b._2 AS _20"
+ )
+ )
+
+ util.verifySql(
+ "SELECT MyTable.a.*, c, MyTable.b.* FROM MyTable",
+ expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala
new file mode 100644
index 0000000..5d5d7f0
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/sql/ExpressionReductionTest.scala
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "(3+4)+a, " +
+ "b+(1+2), " +
+ "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
+ "TRIM(BOTH ' STRING '), " +
+ "'test' || 'string', " +
+ "NULLIF(1, 1), " +
+ "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
+ "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
+ "1 IS NULL, " +
+ "'TEST' LIKE '%EST', " +
+ "FLOOR(2.5), " +
+ "'TEST' IN ('west', 'TEST', 'rest'), " +
+ "CAST(TRUE AS VARCHAR) || 'X'" +
+ "FROM MyTable"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "+(7, a) AS EXPR$0",
+ "+(b, 3) AS EXPR$1",
+ "'b' AS EXPR$2",
+ "'STRING' AS EXPR$3",
+ "'teststring' AS EXPR$4",
+ "null AS EXPR$5",
+ "1990-10-24 23:00:01.123 AS EXPR$6",
+ "19 AS EXPR$7",
+ "false AS EXPR$8",
+ "true AS EXPR$9",
+ "2 AS EXPR$10",
+ "true AS EXPR$11",
+ "'trueX' AS EXPR$12"
+ )
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT " +
+ "*" +
+ "FROM MyTable WHERE a>(1+7)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+}
[17/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
[FLINK-6617][table] Improve JAVA and SCALA logical plans consistent test
This closes #3943.
Project: http://git-wip-us.apache.org/repos/asf/flink/repo
Commit: http://git-wip-us.apache.org/repos/asf/flink/commit/ecde7bc1
Tree: http://git-wip-us.apache.org/repos/asf/flink/tree/ecde7bc1
Diff: http://git-wip-us.apache.org/repos/asf/flink/diff/ecde7bc1
Branch: refs/heads/master
Commit: ecde7bc13c992e81a50d4f9b897ba4840709629c
Parents: 9bfc927
Author: sunjincheng121 <su...@gmail.com>
Authored: Thu May 18 13:02:24 2017 +0800
Committer: twalthr <tw...@apache.org>
Committed: Thu Jul 13 12:17:41 2017 +0200
----------------------------------------------------------------------
.../table/api/java/stream/sql/SqlITCase.java | 4 +-
.../apache/flink/table/AggregationTest.scala | 263 -----
.../flink/table/CalciteConfigBuilderTest.scala | 403 --------
.../flink/table/CompositeFlatteningTest.scala | 147 ---
.../flink/table/ExpressionReductionTest.scala | 8 +-
.../flink/table/ExternalCatalogTest.scala | 194 ----
.../flink/table/TableEnvironmentTest.scala | 394 --------
.../apache/flink/table/TableSchemaTest.scala | 82 --
.../apache/flink/table/TableSourceTest.scala | 421 --------
.../table/api/scala/batch/ExplainTest.scala | 123 ---
.../scala/batch/TableEnvironmentITCase.scala | 291 ------
.../api/scala/batch/TableEnvironmentTest.scala | 318 ++++++
.../table/api/scala/batch/TableSchemaTest.scala | 73 ++
.../table/api/scala/batch/TableSinkITCase.scala | 69 --
.../api/scala/batch/TableSourceITCase.scala | 121 ---
.../scala/batch/sql/AggregationsITCase.scala | 394 --------
.../api/scala/batch/sql/AggregationsTest.scala | 141 ++-
.../table/api/scala/batch/sql/CalcITCase.scala | 327 -------
.../batch/sql/CompositeFlatteningTest.scala | 52 +
.../batch/sql/ExpressionReductionTest.scala | 136 +++
.../table/api/scala/batch/sql/JoinITCase.scala | 700 --------------
.../batch/sql/QueryDecorrelationTest.scala | 18 +-
.../scala/batch/sql/SetOperatorsITCase.scala | 264 -----
.../table/api/scala/batch/sql/SortITCase.scala | 199 ----
.../scala/batch/sql/TableWithSQLITCase.scala | 116 ---
.../scala/batch/sql/WindowAggregateTest.scala | 82 +-
.../validation/AggregationsValidationTest.scala | 43 +
.../sql/validation/CalcValidationTest.scala | 38 +
.../sql/validation/JoinValidationTest.scala | 149 +++
.../sql/validation/SortValidationTest.scala | 38 +
.../WindowAggregateValidationTest.scala | 96 ++
.../scala/batch/table/AggregationsITCase.scala | 379 --------
.../scala/batch/table/AggregationsTest.scala | 132 +++
.../api/scala/batch/table/CalcITCase.scala | 381 --------
.../api/scala/batch/table/CastingITCase.scala | 110 ---
.../batch/table/CompositeFlatteningTest.scala | 116 +++
.../api/scala/batch/table/ExplainTest.scala | 123 +++
.../batch/table/ExpressionReductionTest.scala | 119 +++
.../scala/batch/table/FieldProjectionTest.scala | 79 +-
.../api/scala/batch/table/GroupWindowTest.scala | 151 +--
.../api/scala/batch/table/JoinITCase.scala | 371 -------
.../scala/batch/table/SetOperatorsITCase.scala | 228 -----
.../api/scala/batch/table/SortITCase.scala | 226 -----
.../table/UserDefinedTableFunctionTest.scala | 86 +-
.../AggregationsStringExpressionTest.scala | 136 +--
.../stringexpr/CalcStringExpressionTest.scala | 131 +--
.../CastingStringExpressionTest.scala | 4 +-
.../stringexpr/JoinStringExpressionTest.scala | 107 +--
...finedTableFunctionStringExpressionTest.scala | 90 ++
.../validation/AggregationsValidationTest.scala | 187 ++--
.../table/validation/CalcValidationTest.scala | 68 +-
.../CompositeFlatteningValidationTest.scala | 36 +
.../validation/GroupWindowValidationTest.scala | 185 ++++
.../table/validation/JoinValidationTest.scala | 178 ++--
.../validation/SetOperatorsValidationTest.scala | 35 +-
.../table/validation/SortValidationTest.scala | 23 +-
.../utils/TableProgramsClusterTestBase.scala | 3 +-
.../TableEnvironmentValidationTest.scala | 244 +++++
.../api/scala/stream/ExplainStreamTest.scala | 74 --
.../api/scala/stream/RetractionITCase.scala | 194 ----
.../stream/StreamTableEnvironmentTest.scala | 171 ----
.../api/scala/stream/TableEnvironmentTest.scala | 120 +++
.../api/scala/stream/TableSchemaTest.scala | 50 +
.../api/scala/stream/TableSinkITCase.scala | 63 --
.../api/scala/stream/TableSourceITCase.scala | 105 --
.../api/scala/stream/TableSourceTest.scala | 176 ----
.../api/scala/stream/sql/AggregationsTest.scala | 141 ---
.../stream/sql/ExpressionReductionTest.scala | 136 +++
.../api/scala/stream/sql/OverWindowITCase.scala | 864 -----------------
.../table/api/scala/stream/sql/SqlITCase.scala | 319 ------
.../scala/stream/sql/WindowAggregateTest.scala | 67 +-
.../validation/AggregationsValidationTest.scala | 141 +++
.../validation/OverWindowValidationTest.scala | 45 +
.../WindowAggregateValidationTest.scala | 90 ++
.../api/scala/stream/table/CalcITCase.scala | 270 ------
.../api/scala/stream/table/ExplainTest.scala | 74 ++
.../stream/table/ExpressionReductionTest.scala | 119 +++
.../stream/table/FieldProjectionTest.scala | 98 ++
.../stream/table/GroupAggregationsITCase.scala | 157 ---
.../stream/table/GroupAggregationsTest.scala | 75 +-
.../table/GroupWindowAggregationsITCase.scala | 2 +-
.../table/GroupWindowAggregationsTest.scala | 785 +++++++++++++++
.../scala/stream/table/GroupWindowTest.scala | 963 -------------------
.../scala/stream/table/OverWindowITCase.scala | 347 -------
.../api/scala/stream/table/OverWindowTest.scala | 93 +-
.../scala/stream/table/TableSourceTest.scala | 156 +++
.../api/scala/stream/table/UnionITCase.scala | 124 ---
.../scala/stream/table/UnsupportedOpsTest.scala | 98 --
.../table/UserDefinedTableFunctionTest.scala | 264 -----
.../stringexpr/CalcStringExpressionTest.scala | 126 +++
.../GroupAggregationsStringExpressionTest.scala | 63 ++
.../GroupWindowStringExpressionTest.scala | 199 +++-
.../OverWindowStringExpressionTest.scala | 59 +-
.../stringexpr/UnionStringExpressionTest.scala | 48 +
...finedTableFunctionStringExpressionTest.scala | 91 ++
.../table/validation/CalcValidationTest.scala | 84 ++
.../GroupAggregationsValidationTest.scala | 63 ++
.../GroupWindowAggregationsValidationTest.scala | 207 ++++
.../validation/OverWindowValidationTest.scala | 117 +++
.../validation/TableSinksValidationTest.scala | 64 ++
.../validation/TableSourceValidationTest.scala | 50 +
.../TimeAttributesValidationTest.scala | 79 ++
.../table/validation/UnionValidationTest.scala | 84 ++
.../UnsupportedOpsValidationTest.scala | 98 ++
...UserDefinedTableFunctionValidationTest.scala | 199 ++++
.../api/scala/stream/utils/StreamITCase.scala | 83 --
.../utils/StreamingWithStateTestBase.scala | 40 -
.../TableEnvironmentValidationTest.scala | 78 ++
.../validation/TableSchemaValidationTest.scala | 35 +
.../calcite/CalciteConfigBuilderTest.scala | 402 ++++++++
.../calcite/RelTimeIndicatorConverterTest.scala | 398 --------
.../sql/RelTimeIndicatorConverterTest.scala | 146 +++
.../table/RelTimeIndicatorConverterTest.scala | 286 ++++++
.../catalog/batch/sql/ExternalCatalogTest.scala | 56 ++
.../batch/table/ExternalCatalogTest.scala | 94 ++
.../stream/sql/ExternalCatalogTest.scala | 57 ++
.../stream/table/ExternalCatalogTest.scala | 65 ++
.../catalog/utils/ExternalCatalogTestBase.scala | 38 +
.../flink/table/expressions/ArrayTypeTest.scala | 112 +--
.../table/expressions/CompositeAccessTest.scala | 91 +-
.../flink/table/expressions/MapTypeTest.scala | 41 +-
.../table/expressions/ScalarFunctionsTest.scala | 103 +-
.../table/expressions/ScalarOperatorsTest.scala | 72 +-
.../batch/sql/ExpressionReductionTest.scala | 154 +++
.../batch/table/ExpressionReductionTest.scala | 119 +++
.../stream/sql/ExpressionReductionTest.scala | 154 +++
.../stream/table/ExpressionReductionTest.scala | 137 +++
.../expressions/utils/ArrayTypeTestBase.scala | 65 ++
.../utils/CompositeAccessTestBase.scala | 79 ++
.../expressions/utils/MapTypeTestBase.scala | 53 +
.../utils/ScalarFunctionsTestBase.scala | 105 ++
.../utils/ScalarOperatorsTestBase.scala | 69 ++
.../validation/ArrayTypeValidationTest.scala | 91 ++
.../CompositeAccessValidationTest.scala | 60 ++
.../validation/MapTypeValidationTest.scala | 31 +
.../ScalarFunctionsValidationTest.scala | 44 +
.../ScalarOperatorsValidationTest.scala | 48 +
.../plan/rules/NormalizationRulesTest.scala | 4 +-
.../table/plan/rules/RetractionRulesTest.scala | 4 +-
.../runtime/dataset/DataSetCalcITCase.scala | 105 --
.../DataSetUserDefinedFunctionITCase.scala | 346 -------
.../dataset/DataSetWindowAggregateITCase.scala | 357 -------
.../dataset/sql/AggregationsITCase.scala | 394 ++++++++
.../table/runtime/dataset/sql/CalcITCase.scala | 323 +++++++
.../table/runtime/dataset/sql/JoinITCase.scala | 521 ++++++++++
.../dataset/sql/SetOperatorsITCase.scala | 264 +++++
.../table/runtime/dataset/sql/SortITCase.scala | 186 ++++
.../runtime/dataset/sql/TableSourceITCase.scala | 81 ++
.../dataset/sql/TableWithSQLITCase.scala | 116 +++
.../dataset/table/AggregationsITCase.scala | 379 ++++++++
.../runtime/dataset/table/CalcITCase.scala | 381 ++++++++
.../runtime/dataset/table/CastingITCase.scala | 110 +++
.../dataset/table/DataSetCalcITCase.scala | 105 ++
.../DataSetUserDefinedFunctionITCase.scala | 346 +++++++
.../table/DataSetWindowAggregateITCase.scala | 357 +++++++
.../runtime/dataset/table/JoinITCase.scala | 298 ++++++
.../dataset/table/SetOperatorsITCase.scala | 228 +++++
.../runtime/dataset/table/SortITCase.scala | 226 +++++
.../dataset/table/TableEnvironmentITCase.scala | 179 ++++
.../runtime/dataset/table/TableSinkITCase.scala | 69 ++
.../dataset/table/TableSourceITCase.scala | 79 ++
.../datastream/DataStreamAggregateITCase.scala | 262 -----
.../datastream/DataStreamCalcITCase.scala | 81 --
.../DataStreamUserDefinedFunctionITCase.scala | 245 -----
.../table/runtime/datastream/StreamITCase.scala | 82 ++
.../datastream/StreamingWithStateTestBase.scala | 39 +
.../datastream/TimeAttributesITCase.scala | 444 ---------
.../datastream/sql/OverWindowITCase.scala | 838 ++++++++++++++++
.../runtime/datastream/sql/SqlITCase.scala | 319 ++++++
.../datastream/sql/TableSourceITCase.scala | 61 ++
.../runtime/datastream/table/CalcITCase.scala | 269 ++++++
.../table/GroupAggregationsITCase.scala | 158 +++
.../table/GroupWindowAggregationsITCase.scala | 446 +++++++++
.../datastream/table/OverWindowITCase.scala | 347 +++++++
.../datastream/table/RetractionITCase.scala | 193 ++++
.../datastream/table/TableSinksITCase.scala | 510 ++++++++++
.../datastream/table/TableSourceITCase.scala | 80 ++
.../datastream/table/TimeAttributesITCase.scala | 407 ++++++++
.../runtime/datastream/table/UnionITCase.scala | 75 ++
.../table/UserDefinedFunctionITCase.scala | 246 +++++
.../table/sinks/StreamTableSinksITCase.scala | 511 ----------
.../validation/TableSinksValidationTest.scala | 45 +
.../flink/table/sources/TableSourceTest.scala | 84 ++
.../table/sources/TableSourceTestBase.scala | 61 ++
.../table/sources/batch/TableSourceTest.scala | 421 ++++++++
.../sources/stream/sql/TableSourceTest.scala | 45 +
.../sources/stream/table/TableSourceTest.scala | 91 ++
.../validation/TableSourceBalidationTest.scala | 52 +
.../flink/table/utils/TableTestBase.scala | 82 +-
189 files changed, 18022 insertions(+), 14980 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java
index 4f32382..68719b8d 100644
--- a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/api/java/stream/sql/SqlITCase.java
@@ -30,7 +30,7 @@ import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.TableEnvironment;
import org.apache.flink.table.api.java.StreamTableEnvironment;
import org.apache.flink.table.api.java.stream.utils.StreamTestData;
-import org.apache.flink.table.api.scala.stream.utils.StreamITCase;
+import org.apache.flink.table.runtime.datastream.StreamITCase;
import org.apache.flink.types.Row;
import org.junit.Test;
@@ -38,6 +38,8 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
+
+
/**
* Integration tests for streaming SQL.
*/
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/AggregationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/AggregationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/AggregationTest.scala
deleted file mode 100644
index aad3403..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/AggregationTest.scala
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for testing aggregate plans.
- */
-class AggregationTest extends TableTestBase {
-
- @Test
- def testAggregateQueryBatchSQL(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable"
-
- val setValues = unaryNode(
- "DataSetValues",
- batchTableNode(0),
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- util.verifySql(sqlQuery, aggregate)
- }
-
- @Test
- def testAggregateWithFilterQueryBatchSQL(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1"
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", "=(a, 1)")
- )
-
- val setValues = unaryNode(
- "DataSetValues",
- calcNode,
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
-
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- util.verifySql(sqlQuery, aggregate)
- }
-
- @Test
- def testAggregateGroupQueryBatchSQL(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable GROUP BY a"
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- batchTableNode(0),
- term("groupBy", "a"),
- term("select",
- "a",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- val expected = unaryNode(
- "DataSetCalc",
- aggregate,
- term("select",
- "EXPR$0",
- "EXPR$1",
- "EXPR$2")
- )
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testAggregateGroupWithFilterQueryBatchSQL(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1 GROUP BY a"
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select","a", "b", "c") ,
- term("where","=(a, 1)")
- )
-
- val aggregate = unaryNode(
- "DataSetAggregate",
- calcNode,
- term("groupBy", "a"),
- term("select",
- "a",
- "AVG(a) AS EXPR$0",
- "SUM(b) AS EXPR$1",
- "COUNT(c) AS EXPR$2")
- )
- val expected = unaryNode(
- "DataSetCalc",
- aggregate,
- term("select",
- "EXPR$0",
- "EXPR$1",
- "EXPR$2")
- )
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testAggregateGroupWithFilterTableApi(): Unit = {
-
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val resultTable = sourceTable.groupBy('a)
- .select('a, 'a.avg, 'b.sum, 'c.count)
- .where('a === 1)
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", "=(a, 1)")
- )
-
- val expected = unaryNode(
- "DataSetAggregate",
- calcNode,
- term("groupBy", "a"),
- term("select",
- "a",
- "AVG(a) AS TMP_0",
- "SUM(b) AS TMP_1",
- "COUNT(c) AS TMP_2")
- )
-
- util.verifyTable(resultTable,expected)
- }
-
- @Test
- def testAggregateTableApi(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
- val resultTable = sourceTable.select('a.avg,'b.sum,'c.count)
-
- val setValues = unaryNode(
- "DataSetValues",
- batchTableNode(0),
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val expected = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS TMP_0",
- "SUM(b) AS TMP_1",
- "COUNT(c) AS TMP_2")
- )
- util.verifyTable(resultTable, expected)
- }
-
- @Test
- def testAggregateWithFilterTableApi(): Unit = {
- val util = batchTestUtil()
- val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
-
- val resultTable = sourceTable.select('a,'b,'c).where('a === 1)
- .select('a.avg,'b.sum,'c.count)
-
- val calcNode = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- // ReduceExpressionsRule will add cast for Project node by force
- // if the input of the Project node has constant expression.
- term("select", "CAST(1) AS a", "b", "c"),
- term("where", "=(a, 1)")
- )
-
- val setValues = unaryNode(
- "DataSetValues",
- calcNode,
- tuples(List(null,null,null)),
- term("values","a","b","c")
- )
-
- val union = unaryNode(
- "DataSetUnion",
- setValues,
- term("union","a","b","c")
- )
-
- val expected = unaryNode(
- "DataSetAggregate",
- union,
- term("select",
- "AVG(a) AS TMP_0",
- "SUM(b) AS TMP_1",
- "COUNT(c) AS TMP_2")
- )
-
- util.verifyTable(resultTable, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CalciteConfigBuilderTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CalciteConfigBuilderTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CalciteConfigBuilderTest.scala
deleted file mode 100644
index 0c337e0..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CalciteConfigBuilderTest.scala
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table
-
-import org.apache.calcite.rel.rules._
-import org.apache.calcite.sql.fun.{OracleSqlOperatorTable, SqlStdOperatorTable}
-import org.apache.calcite.tools.RuleSets
-import org.apache.flink.table.calcite.{CalciteConfig, CalciteConfigBuilder}
-import org.apache.flink.table.plan.rules.datastream.DataStreamRetractionRules
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.JavaConverters._
-
-class CalciteConfigBuilderTest {
-
- @Test
- def testDefaultRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder().build()
-
- assertFalse(cc.replacesNormRuleSet)
- assertFalse(cc.getNormRuleSet.isDefined)
-
- assertFalse(cc.replacesLogicalOptRuleSet)
- assertFalse(cc.getLogicalOptRuleSet.isDefined)
-
- assertFalse(cc.replacesPhysicalOptRuleSet)
- assertFalse(cc.getPhysicalOptRuleSet.isDefined)
-
- assertFalse(cc.replacesDecoRuleSet)
- assertFalse(cc.getDecoRuleSet.isDefined)
- }
-
- @Test
- def testRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
- .replaceLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .replacePhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .replaceDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- .build()
-
- assertFalse(cc.replacesNormRuleSet)
- assertTrue(cc.getNormRuleSet.isDefined)
-
- assertTrue(cc.replacesLogicalOptRuleSet)
- assertTrue(cc.getLogicalOptRuleSet.isDefined)
-
- assertTrue(cc.replacesPhysicalOptRuleSet)
- assertTrue(cc.getPhysicalOptRuleSet.isDefined)
-
- assertTrue(cc.replacesDecoRuleSet)
- assertTrue(cc.getDecoRuleSet.isDefined)
- }
-
- @Test
- def testReplaceNormalizationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesNormRuleSet)
- assertTrue(cc.getNormRuleSet.isDefined)
- val cSet = cc.getNormRuleSet.get.iterator().asScala.toSet
- assertEquals(1, cSet.size)
- assertTrue(cSet.contains(ReduceExpressionsRule.FILTER_INSTANCE))
- }
-
- @Test
- def testReplaceNormalizationAddRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
- .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.PROJECT_INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesNormRuleSet)
- assertTrue(cc.getNormRuleSet.isDefined)
- val cSet = cc.getNormRuleSet.get.iterator().asScala.toSet
- assertEquals(2, cSet.size)
- assertTrue(cSet.contains(ReduceExpressionsRule.FILTER_INSTANCE))
- assertTrue(cSet.contains(ReduceExpressionsRule.PROJECT_INSTANCE))
- }
-
- @Test
- def testAddNormalizationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
- .build()
-
- assertEquals(false, cc.replacesNormRuleSet)
- assertTrue(cc.getNormRuleSet.isDefined)
- val cSet = cc.getNormRuleSet.get.iterator().asScala.toSet
- assertEquals(1, cSet.size)
- assertTrue(cSet.contains(ReduceExpressionsRule.FILTER_INSTANCE))
- }
-
- @Test
- def testAddAddNormalizationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.FILTER_INSTANCE))
- .addNormRuleSet(RuleSets.ofList(ReduceExpressionsRule.PROJECT_INSTANCE,
- ReduceExpressionsRule.CALC_INSTANCE))
- .build()
-
- assertEquals(false, cc.replacesNormRuleSet)
- assertTrue(cc.getNormRuleSet.isDefined)
- val cList = cc.getNormRuleSet.get.iterator().asScala.toList
- assertEquals(3, cList.size)
- assertEquals(cList.head, ReduceExpressionsRule.FILTER_INSTANCE)
- assertEquals(cList(1), ReduceExpressionsRule.PROJECT_INSTANCE)
- assertEquals(cList(2), ReduceExpressionsRule.CALC_INSTANCE)
- }
-
- @Test
- def testReplaceLogicalOptimizationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesLogicalOptRuleSet)
- assertTrue(cc.getLogicalOptRuleSet.isDefined)
- val cSet = cc.getLogicalOptRuleSet.get.iterator().asScala.toSet
- assertEquals(1, cSet.size)
- assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
- }
-
- @Test
- def testReplaceLogicalOptimizationAddRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .addLogicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesLogicalOptRuleSet)
- assertTrue(cc.getLogicalOptRuleSet.isDefined)
- val cSet = cc.getLogicalOptRuleSet.get.iterator().asScala.toSet
- assertEquals(3, cSet.size)
- assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
- }
-
- @Test
- def testAddLogicalOptimizationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addLogicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .addLogicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
- .build()
-
- assertEquals(false, cc.replacesLogicalOptRuleSet)
- assertTrue(cc.getLogicalOptRuleSet.isDefined)
- val cSet = cc.getLogicalOptRuleSet.get.iterator().asScala.toSet
- assertEquals(3, cSet.size)
- assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
- }
-
- @Test
- def testReplacePhysicalOptimizationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replacePhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesPhysicalOptRuleSet)
- assertTrue(cc.getPhysicalOptRuleSet.isDefined)
- val cSet = cc.getPhysicalOptRuleSet.get.iterator().asScala.toSet
- assertEquals(1, cSet.size)
- assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
- }
-
- @Test
- def testReplacePhysicalOptimizationAddRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replacePhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .addPhysicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesPhysicalOptRuleSet)
- assertTrue(cc.getPhysicalOptRuleSet.isDefined)
- val cSet = cc.getPhysicalOptRuleSet.get.iterator().asScala.toSet
- assertEquals(3, cSet.size)
- assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
- }
-
- @Test
- def testAddPhysicalOptimizationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addPhysicalOptRuleSet(RuleSets.ofList(FilterMergeRule.INSTANCE))
- .addPhysicalOptRuleSet(RuleSets.ofList(CalcMergeRule.INSTANCE, CalcSplitRule.INSTANCE))
- .build()
-
- assertEquals(false, cc.replacesPhysicalOptRuleSet)
- assertTrue(cc.getPhysicalOptRuleSet.isDefined)
- val cSet = cc.getPhysicalOptRuleSet.get.iterator().asScala.toSet
- assertEquals(3, cSet.size)
- assertTrue(cSet.contains(FilterMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcMergeRule.INSTANCE))
- assertTrue(cSet.contains(CalcSplitRule.INSTANCE))
- }
-
- @Test
- def testReplaceDecorationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesDecoRuleSet)
- assertTrue(cc.getDecoRuleSet.isDefined)
- val cSet = cc.getDecoRuleSet.get.iterator().asScala.toSet
- assertEquals(1, cSet.size)
- assertTrue(cSet.contains(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- }
-
- @Test
- def testReplaceDecorationAddRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE))
- .build()
-
- assertEquals(true, cc.replacesDecoRuleSet)
- assertTrue(cc.getDecoRuleSet.isDefined)
- val cSet = cc.getDecoRuleSet.get.iterator().asScala.toSet
- assertEquals(2, cSet.size)
- assertTrue(cSet.contains(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- assertTrue(cSet.contains(DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE))
- }
-
- @Test
- def testAddDecorationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- .build()
-
- assertEquals(false, cc.replacesDecoRuleSet)
- assertTrue(cc.getDecoRuleSet.isDefined)
- val cSet = cc.getDecoRuleSet.get.iterator().asScala.toSet
- assertEquals(1, cSet.size)
- assertTrue(cSet.contains(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- }
-
- @Test
- def testAddAddDecorationRules(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE))
- .addDecoRuleSet(RuleSets.ofList(DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE,
- DataStreamRetractionRules.ACCMODE_INSTANCE))
- .build()
-
- assertEquals(false, cc.replacesDecoRuleSet)
- assertTrue(cc.getDecoRuleSet.isDefined)
- val cList = cc.getDecoRuleSet.get.iterator().asScala.toList
- assertEquals(3, cList.size)
- assertEquals(cList.head, DataStreamRetractionRules.DEFAULT_RETRACTION_INSTANCE)
- assertEquals(cList(1), DataStreamRetractionRules.UPDATES_AS_RETRACTION_INSTANCE)
- assertEquals(cList(2), DataStreamRetractionRules.ACCMODE_INSTANCE)
- }
-
- @Test
- def testDefaultOperatorTable(): Unit = {
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .build()
-
- assertEquals(false, cc.replacesSqlOperatorTable)
- assertFalse(cc.getSqlOperatorTable.isDefined)
- }
-
- @Test
- def testReplaceOperatorTable(): Unit = {
-
- val oracleTable = new OracleSqlOperatorTable
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceSqlOperatorTable(oracleTable)
- .build()
-
- val oracleOps = oracleTable.getOperatorList.asScala
-
- assertEquals(true, cc.replacesSqlOperatorTable)
- assertTrue(cc.getSqlOperatorTable.isDefined)
- val ops = cc.getSqlOperatorTable.get.getOperatorList
- .asScala.toSet
- assertEquals(oracleOps.size, ops.size)
- for (o <- oracleOps) {
- assertTrue(ops.contains(o))
- }
- }
-
- @Test
- def testReplaceAddOperatorTable(): Unit = {
-
- val oracleTable = new OracleSqlOperatorTable
- val stdTable = new SqlStdOperatorTable
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .replaceSqlOperatorTable(oracleTable)
- .addSqlOperatorTable(stdTable)
- .build()
-
- val oracleOps = oracleTable.getOperatorList.asScala
- val stdOps = stdTable.getOperatorList.asScala
-
- assertEquals(true, cc.replacesSqlOperatorTable)
- assertTrue(cc.getSqlOperatorTable.isDefined)
- val ops = cc.getSqlOperatorTable.get.getOperatorList
- .asScala.toSet
- assertEquals(oracleOps.size + stdOps.size, ops.size)
- for (o <- oracleOps) {
- assertTrue(ops.contains(o))
- }
- for (o <- stdOps) {
- assertTrue(ops.contains(o))
- }
-
- }
-
- @Test
- def testAddOperatorTable(): Unit = {
-
- val oracleTable = new OracleSqlOperatorTable
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addSqlOperatorTable(oracleTable)
- .build()
-
- val oracleOps = oracleTable.getOperatorList.asScala
-
- assertEquals(false, cc.replacesSqlOperatorTable)
- assertTrue(cc.getSqlOperatorTable.isDefined)
- val ops = cc.getSqlOperatorTable.get.getOperatorList
- .asScala.toSet
- assertEquals(oracleOps.size, ops.size)
- for (o <- oracleOps) {
- assertTrue(ops.contains(o))
- }
- }
-
- @Test
- def testAddAddOperatorTable(): Unit = {
-
- val oracleTable = new OracleSqlOperatorTable
- val stdTable = new SqlStdOperatorTable
-
- val cc: CalciteConfig = new CalciteConfigBuilder()
- .addSqlOperatorTable(oracleTable)
- .addSqlOperatorTable(stdTable)
- .build()
-
- val oracleOps = oracleTable.getOperatorList.asScala
- val stdOps = stdTable.getOperatorList.asScala
-
- assertEquals(false, cc.replacesSqlOperatorTable)
- assertTrue(cc.getSqlOperatorTable.isDefined)
- val ops = cc.getSqlOperatorTable.get.getOperatorList
- .asScala.toSet
- assertEquals(oracleOps.size + stdOps.size, ops.size)
- for (o <- oracleOps) {
- assertTrue(ops.contains(o))
- }
- for (o <- stdOps) {
- assertTrue(ops.contains(o))
- }
-
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CompositeFlatteningTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CompositeFlatteningTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CompositeFlatteningTest.scala
deleted file mode 100644
index f5f5ff1..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/CompositeFlatteningTest.scala
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.scala.createTypeInformation
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.CompositeFlatteningTest.{TestCaseClass, giveMeCaseClass}
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-
-class CompositeFlatteningTest extends TableTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testDuplicateFlattening(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
-
- table.select('a.flatten(), 'a.flatten())
- }
-
- @Test
- def testMultipleFlatteningsTable(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
-
- val result = table.select('a.flatten(), 'c, 'b.flatten())
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "a._1 AS a$_1",
- "a._2 AS a$_2",
- "c",
- "b._1 AS b$_1",
- "b._2 AS b$_2"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testMultipleFlatteningsSql(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "a._1 AS _1",
- "a._2 AS _2",
- "c",
- "b._1 AS _10",
- "b._2 AS _20"
- )
- )
-
- util.verifySql(
- "SELECT MyTable.a.*, c, MyTable.b.* FROM MyTable",
- expected)
- }
-
- @Test
- def testNestedFlattenings(): Unit = {
- val util = batchTestUtil()
- val table = util
- .addTable[((((String, TestCaseClass), Boolean), String), String)]("MyTable", 'a, 'b)
-
- val result = table.select('a.flatten(), 'b.flatten())
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "a._1 AS a$_1",
- "a._2 AS a$_2",
- "b"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testScalarFunctionAccess(): Unit = {
- val util = batchTestUtil()
- val table = util
- .addTable[(String, Int)]("MyTable", 'a, 'b)
-
- val result = table.select(
- giveMeCaseClass().get("my"),
- giveMeCaseClass().get("clazz"),
- giveMeCaseClass().flatten())
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- s"${giveMeCaseClass.functionIdentifier}().my AS _c0",
- s"${giveMeCaseClass.functionIdentifier}().clazz AS _c1",
- s"${giveMeCaseClass.functionIdentifier}().my AS _c2",
- s"${giveMeCaseClass.functionIdentifier}().clazz AS _c3"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
-}
-
-object CompositeFlatteningTest {
-
- case class TestCaseClass(my: String, clazz: Int)
-
- object giveMeCaseClass extends ScalarFunction {
- def eval(): TestCaseClass = {
- TestCaseClass("hello", 42)
- }
-
- override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
- createTypeInformation[TestCaseClass]
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala
index 2e9ee46..9bc3e51 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala
@@ -429,9 +429,9 @@ class ExpressionReductionTest extends TableTestBase {
util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val newTable = util.tEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
+ val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
- util.tEnv.registerTable("NewTable", newTable)
+ util.tableEnv.registerTable("NewTable", newTable)
val sqlQuery = "SELECT a FROM NewTable"
@@ -447,9 +447,9 @@ class ExpressionReductionTest extends TableTestBase {
util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val newTable = util.tEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
+ val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
- util.tEnv.registerTable("NewTable", newTable)
+ util.tableEnv.registerTable("NewTable", newTable)
val sqlQuery = "SELECT a FROM NewTable"
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExternalCatalogTest.scala
deleted file mode 100644
index 27dd8d8..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExternalCatalogTest.scala
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table
-
-import org.apache.flink.table.utils.{CommonTestData, TableTestBase}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for external catalog query plan.
- */
-class ExternalCatalogTest extends TableTestBase {
- private val table1Path: Array[String] = Array("test", "db1", "tb1")
- private val table1TopLevelPath: Array[String] = Array("test", "tb1")
- private val table1ProjectedFields: Array[String] = Array("a", "b", "c")
- private val table2Path: Array[String] = Array("test", "db2", "tb2")
- private val table2ProjectedFields: Array[String] = Array("d", "e", "g")
-
- @Test
- def testBatchTableApi(): Unit = {
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val table1 = tEnv.scan("test", "db1", "tb1")
- val table2 = tEnv.scan("test", "db2", "tb2")
- val result = table2
- .select('d * 2, 'e, 'g.upperCase())
- .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
-
- val expected = binaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
- ),
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
- ),
- term("union", "_c0", "e", "_c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchSQL(): Unit = {
- val util = batchTestUtil()
-
- util.tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
- "(SELECT a * 2, b, c FROM test.db1.tb1)"
-
- val expected = binaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS EXPR$0", "e", "g"),
- term("where", "<(d, 3)")),
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS EXPR$0", "b", "c")
- ),
- term("union", "EXPR$0", "e", "g"))
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testStreamTableApi(): Unit = {
- val util = streamTestUtil()
- val tEnv = util.tEnv
-
- util.tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val table1 = tEnv.scan("test", "db1", "tb1")
- val table2 = tEnv.scan("test", "db2", "tb2")
-
- val result = table2.where("d < 3")
- .select('d * 2, 'e, 'g.upperCase())
- .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
-
- val expected = binaryNode(
- "DataStreamUnion",
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2"),
- term("where", "<(d, 3)")
- ),
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
- ),
- term("union all", "_c0", "e", "_c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testStreamSQL(): Unit = {
- val util = streamTestUtil()
-
- util.tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
- "(SELECT a * 2, b, c FROM test.db1.tb1)"
-
- val expected = binaryNode(
- "DataStreamUnion",
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS EXPR$0", "e", "g"),
- term("where", "<(d, 3)")),
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS EXPR$0", "b", "c")
- ),
- term("union all", "EXPR$0", "e", "g"))
-
- util.verifySql(sqlQuery, expected)
- }
-
-
- @Test
- def testTopLevelTable(): Unit = {
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val table1 = tEnv.scan("test", "tb1")
- val table2 = tEnv.scan("test", "db2", "tb2")
- val result = table2
- .select('d * 2, 'e, 'g.upperCase())
- .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
-
- val expected = binaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
- ),
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table1TopLevelPath, table1ProjectedFields),
- term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
- ),
- term("union", "_c0", "e", "_c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- def sourceBatchTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
- s"BatchTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
- s"fields=[${fields.mkString(", ")}])"
- }
-
- def sourceStreamTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
- s"StreamTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
- s"fields=[${fields.mkString(", ")}])"
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableEnvironmentTest.scala
deleted file mode 100644
index 98a8edb..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableEnvironmentTest.scala
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo._
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.java.typeutils.{GenericTypeInfo, RowTypeInfo, TupleTypeInfo, TypeExtractor}
-import org.apache.flink.table.api.TableException
-import org.apache.flink.table.expressions.{Alias, UnresolvedFieldReference}
-import org.apache.flink.table.runtime.types.CRowTypeInfo
-import org.apache.flink.table.utils.{MockTableEnvironment, TableTestBase}
-import org.apache.flink.table.utils.TableTestUtil.{batchTableNode, binaryNode, streamTableNode, term, unaryNode}
-import org.apache.flink.types.Row
-import org.junit.Test
-import org.junit.Assert.assertEquals
-
-class TableEnvironmentTest extends TableTestBase {
-
- val tEnv = new MockTableEnvironment
-
- val tupleType = new TupleTypeInfo(
- INT_TYPE_INFO,
- STRING_TYPE_INFO,
- DOUBLE_TYPE_INFO)
-
- val rowType = new RowTypeInfo(INT_TYPE_INFO, STRING_TYPE_INFO,DOUBLE_TYPE_INFO)
-
- val cRowType = new CRowTypeInfo(rowType)
-
- val caseClassType: TypeInformation[CClass] = implicitly[TypeInformation[CClass]]
-
- val pojoType: TypeInformation[PojoClass] = TypeExtractor.createTypeInfo(classOf[PojoClass])
-
- val atomicType = INT_TYPE_INFO
-
- val genericRowType = new GenericTypeInfo[Row](classOf[Row])
-
- @Test
- def testGetFieldInfoRow(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(rowType)
-
- fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoRowNames(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- rowType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoTuple(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(tupleType)
-
- fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoCClass(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(caseClassType)
-
- fieldInfo._1.zip(Array("cf1", "cf2", "cf3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoPojo(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(pojoType)
-
- fieldInfo._1.zip(Array("pf1", "pf2", "pf3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoAtomic(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(atomicType)
-
- fieldInfo._1.zip(Array("f0")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoGenericRow(): Unit = {
- tEnv.getFieldInfo(genericRowType)
- }
-
- @Test
- def testGetFieldInfoTupleNames(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- tupleType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoCClassNames(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- caseClassType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoPojoNames1(): Unit = {
- tEnv.getFieldInfo(
- pojoType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2"),
- UnresolvedFieldReference("name3")
- ))
- }
-
- @Test
- def testGetFieldInfoPojoNames2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- pojoType,
- Array(
- UnresolvedFieldReference("pf3"),
- UnresolvedFieldReference("pf1"),
- UnresolvedFieldReference("pf2")
- ))
-
- fieldInfo._1.zip(Array("pf3", "pf1", "pf2")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoAtomicName1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- atomicType,
- Array(UnresolvedFieldReference("name")))
-
- fieldInfo._1.zip(Array("name")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoAtomicName2(): Unit = {
- tEnv.getFieldInfo(
- atomicType,
- Array(
- UnresolvedFieldReference("name1"),
- UnresolvedFieldReference("name2")
- ))
- }
-
- @Test
- def testGetFieldInfoTupleAlias1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- tupleType,
- Array(
- Alias(UnresolvedFieldReference("f0"), "name1"),
- Alias(UnresolvedFieldReference("f1"), "name2"),
- Alias(UnresolvedFieldReference("f2"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoTupleAlias2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- tupleType,
- Array(
- Alias(UnresolvedFieldReference("f2"), "name1"),
- Alias(UnresolvedFieldReference("f0"), "name2"),
- Alias(UnresolvedFieldReference("f1"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoTupleAlias3(): Unit = {
- tEnv.getFieldInfo(
- tupleType,
- Array(
- Alias(UnresolvedFieldReference("xxx"), "name1"),
- Alias(UnresolvedFieldReference("yyy"), "name2"),
- Alias(UnresolvedFieldReference("zzz"), "name3")
- ))
- }
-
- @Test
- def testGetFieldInfoCClassAlias1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- caseClassType,
- Array(
- Alias(UnresolvedFieldReference("cf1"), "name1"),
- Alias(UnresolvedFieldReference("cf2"), "name2"),
- Alias(UnresolvedFieldReference("cf3"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoCClassAlias2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- caseClassType,
- Array(
- Alias(UnresolvedFieldReference("cf3"), "name1"),
- Alias(UnresolvedFieldReference("cf1"), "name2"),
- Alias(UnresolvedFieldReference("cf2"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoCClassAlias3(): Unit = {
- tEnv.getFieldInfo(
- caseClassType,
- Array(
- Alias(UnresolvedFieldReference("xxx"), "name1"),
- Alias(UnresolvedFieldReference("yyy"), "name2"),
- Alias(UnresolvedFieldReference("zzz"), "name3")
- ))
- }
-
- @Test
- def testGetFieldInfoPojoAlias1(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- pojoType,
- Array(
- Alias(UnresolvedFieldReference("pf1"), "name1"),
- Alias(UnresolvedFieldReference("pf2"), "name2"),
- Alias(UnresolvedFieldReference("pf3"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test
- def testGetFieldInfoPojoAlias2(): Unit = {
- val fieldInfo = tEnv.getFieldInfo(
- pojoType,
- Array(
- Alias(UnresolvedFieldReference("pf3"), "name1"),
- Alias(UnresolvedFieldReference("pf1"), "name2"),
- Alias(UnresolvedFieldReference("pf2"), "name3")
- ))
-
- fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
- fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoPojoAlias3(): Unit = {
- tEnv.getFieldInfo(
- pojoType,
- Array(
- Alias(UnresolvedFieldReference("xxx"), "name1"),
- Alias(UnresolvedFieldReference("yyy"), "name2"),
- Alias(UnresolvedFieldReference("zzz"), "name3")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoAtomicAlias(): Unit = {
- tEnv.getFieldInfo(
- atomicType,
- Array(
- Alias(UnresolvedFieldReference("name1"), "name2")
- ))
- }
-
- @Test(expected = classOf[TableException])
- def testGetFieldInfoGenericRowAlias(): Unit = {
- tEnv.getFieldInfo(
- genericRowType,
- Array(UnresolvedFieldReference("first")))
- }
-
- @Test
- def testSqlWithoutRegisteringForBatchTables(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
-
- val sqlTable = util.tEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a, b, c"),
- term("where", ">(b, 12)"))
-
- util.verifyTable(sqlTable, expected)
-
- val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
-
- val sqlTable2 = util.tEnv.sql(s"SELECT d, e, f FROM $table, $table2 WHERE c = d")
-
- val join = unaryNode(
- "DataSetJoin",
- binaryNode(
- "DataSetCalc",
- batchTableNode(0),
- batchTableNode(1),
- term("select", "c")),
- term("where", "=(c, d)"),
- term("join", "c, d, e, f"),
- term("joinType", "InnerJoin"))
-
- val expected2 = unaryNode(
- "DataSetCalc",
- join,
- term("select", "d, e, f"))
-
- util.verifyTable(sqlTable2, expected2)
- }
-
- @Test
- def testSqlWithoutRegisteringForStreamTables(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
-
- val sqlTable = util.tEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a, b, c"),
- term("where", ">(b, 12)"))
-
- util.verifyTable(sqlTable, expected)
-
- val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
-
- val sqlTable2 = util.tEnv.sql(s"SELECT d, e, f FROM $table2 " +
- s"UNION ALL SELECT a, b, c FROM $table")
-
- val expected2 = binaryNode(
- "DataStreamUnion",
- streamTableNode(1),
- streamTableNode(0),
- term("union all", "d, e, f"))
-
- util.verifyTable(sqlTable2, expected2)
- }
-
-}
-
-case class CClass(cf1: Int, cf2: String, cf3: Double)
-
-class PojoClass(var pf1: Int, var pf2: String, var pf3: Double) {
- def this() = this(0, "", 0.0)
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSchemaTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSchemaTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSchemaTest.scala
deleted file mode 100644
index 39c4c16..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSchemaTest.scala
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table
-
-import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{TableException, TableSchema, Types}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Assert.{assertEquals, assertTrue}
-import org.junit.Test
-
-class TableSchemaTest extends TableTestBase {
-
- @Test
- def testBatchTableSchema(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
- val schema = table.getSchema
-
- assertEquals("a", schema.getColumnNames.apply(0))
- assertEquals("b", schema.getColumnNames.apply(1))
-
- assertEquals(Types.INT, schema.getTypes.apply(0))
- assertEquals(Types.STRING, schema.getTypes.apply(1))
-
- val expectedString = "root\n" +
- " |-- a: Integer\n" +
- " |-- b: String\n"
- assertEquals(expectedString, schema.toString)
-
- assertTrue(schema.getColumnName(3).isEmpty)
- assertTrue(schema.getType(-1).isEmpty)
- assertTrue(schema.getType("c").isEmpty)
- }
-
- @Test
- def testStreamTableSchema(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
- val schema = table.getSchema
-
- assertEquals("a", schema.getColumnNames.apply(0))
- assertEquals("b", schema.getColumnNames.apply(1))
-
- assertEquals(Types.INT, schema.getTypes.apply(0))
- assertEquals(Types.STRING, schema.getTypes.apply(1))
-
- val expectedString = "root\n" +
- " |-- a: Integer\n" +
- " |-- b: String\n"
- assertEquals(expectedString, schema.toString)
-
- assertTrue(schema.getColumnName(3).isEmpty)
- assertTrue(schema.getType(-1).isEmpty)
- assertTrue(schema.getType("c").isEmpty)
- }
-
- @Test(expected = classOf[TableException])
- def testInvalidSchema() {
- val fieldNames = Array("a", "b", "c")
- val typeInfos: Array[TypeInformation[_]] = Array(
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO)
- new TableSchema(fieldNames, typeInfos)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSourceTest.scala
deleted file mode 100644
index 24a32de..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/TableSourceTest.scala
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table
-
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.sources.{CsvTableSource, TableSource}
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.expressions.utils._
-import org.apache.flink.table.utils.{CommonTestData, TableTestBase, TestFilterableTableSource}
-import org.junit.{Assert, Test}
-
-class TableSourceTest extends TableTestBase {
-
- private val projectedFields: Array[String] = Array("last", "id", "score")
- private val noCalcFields: Array[String] = Array("id", "score", "first")
-
- @Test
- def testTableSourceScanToString(): Unit = {
- val (tableSource1, _) = filterableTableSource
- val (tableSource2, _) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource("table1", tableSource1)
- tEnv.registerTableSource("table2", tableSource2)
-
- val table1 = tEnv.scan("table1").where("amount > 2")
- val table2 = tEnv.scan("table2").where("amount > 2")
- val result = table1.unionAll(table2)
-
- val expected = binaryNode(
- "DataSetUnion",
- batchFilterableSourceTableNode(
- "table1",
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- batchFilterableSourceTableNode(
- "table2",
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("union", "name, id, amount, price")
- )
- util.verifyTable(result, expected)
- }
-
- // batch plan
-
- @Test
- def testBatchProjectableSourceScanPlanTableApi(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('last.upperCase(), 'id.floor(), 'score * 2)
-
- val expected = unaryNode(
- "DataSetCalc",
- batchSourceTableNode(tableName, projectedFields),
- term("select", "UPPER(last) AS _c0", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchProjectableSourceScanPlanSQL(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = batchTestUtil()
-
- util.tEnv.registerTableSource(tableName, tableSource)
-
- val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testBatchProjectableSourceScanNoIdentityCalc(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('id, 'score, 'first)
-
- val expected = batchSourceTableNode(tableName, noCalcFields)
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableWithoutPushDown(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("price * 2 < 32")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price")),
- term("select", "price", "id", "amount"),
- term("where", "<(*(price, 2), 32)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterablePartialPushDown(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .where("amount > 2 && price * 2 < 32")
- .select('price, 'name.lowerCase(), 'amount)
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "LOWER(name) AS _c1", "amount"),
- term("where", "<(*(price, 2), 32)")
- )
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableFullyPushedDown(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && amount < 32")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2 && 'amount < 32"),
- term("select", "price", "id", "amount")
- )
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableWithUnconvertedExpression(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && (amount < 32 || amount.cast(LONG) > 10)") // cast can not be converted
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "id", "amount"),
- term("where", "OR(<(amount, 32), >(CAST(amount), 10))")
- )
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableWithUDF(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
- val func = Func0
- tEnv.registerFunction("func0", func)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && func0(amount) < 32")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "id", "amount"),
- term("where", s"<(${func.functionIdentifier}(amount), 32)")
- )
-
- util.verifyTable(result, expected)
- }
-
- // stream plan
-
- @Test
- def testStreamProjectableSourceScanPlanTableApi(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('last, 'id.floor(), 'score * 2)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testStreamProjectableSourceScanPlanSQL(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
-
- util.tEnv.registerTableSource(tableName, tableSource)
-
- val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testStreamProjectableSourceScanNoIdentityCalc(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('id, 'score, 'first)
-
- val expected = streamSourceTableNode(tableName, noCalcFields)
- util.verifyTable(result, expected)
- }
-
- @Test
- def testStreamFilterableSourceScanPlanTableApi(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = streamTestUtil()
- val tEnv = util.tEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && price * 2 < 32")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "id", "amount"),
- term("where", "<(*(price, 2), 32)")
- )
-
- util.verifyTable(result, expected)
- }
-
- // csv builder
-
- @Test
- def testCsvTableSourceBuilder(): Unit = {
- val source1 = CsvTableSource.builder()
- .path("/path/to/csv")
- .field("myfield", Types.STRING)
- .field("myfield2", Types.INT)
- .quoteCharacter(';')
- .fieldDelimiter("#")
- .lineDelimiter("\r\n")
- .commentPrefix("%%")
- .ignoreFirstLine()
- .ignoreParseErrors()
- .build()
-
- val source2 = new CsvTableSource(
- "/path/to/csv",
- Array("myfield", "myfield2"),
- Array(Types.STRING, Types.INT),
- "#",
- "\r\n",
- ';',
- true,
- "%%",
- true)
-
- Assert.assertEquals(source1, source2)
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithNullPath(): Unit = {
- CsvTableSource.builder()
- .field("myfield", Types.STRING)
- // should fail, path is not defined
- .build()
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithDuplicateFieldName(): Unit = {
- CsvTableSource.builder()
- .path("/path/to/csv")
- .field("myfield", Types.STRING)
- // should fail, field name must no be duplicate
- .field("myfield", Types.INT)
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithEmptyField(): Unit = {
- CsvTableSource.builder()
- .path("/path/to/csv")
- // should fail, field can be empty
- .build()
- }
-
- // utils
-
- def filterableTableSource:(TableSource[_], String) = {
- val tableSource = new TestFilterableTableSource
- (tableSource, "filterableTable")
- }
-
- def csvTable: (CsvTableSource, String) = {
- val csvTable = CommonTestData.getCsvTableSource
- val tableName = "csvTable"
- (csvTable, tableName)
- }
-
- def batchSourceTableNode(sourceName: String, fields: Array[String]): String = {
- s"BatchTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
- }
-
- def streamSourceTableNode(sourceName: String, fields: Array[String] ): String = {
- s"StreamTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
- }
-
- def batchFilterableSourceTableNode(
- sourceName: String,
- fields: Array[String],
- exp: String): String = {
- "BatchTableSourceScan(" +
- s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
- }
-
- def streamFilterableSourceTableNode(
- sourceName: String,
- fields: Array[String],
- exp: String): String = {
- "StreamTableSourceScan(" +
- s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/ExplainTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/ExplainTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/ExplainTest.scala
deleted file mode 100644
index 10af4d7..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/ExplainTest.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.test.util.MultipleProgramsTestBase
-import org.junit.Assert.assertEquals
-import org.junit._
-
-class ExplainTest
- extends MultipleProgramsTestBase(MultipleProgramsTestBase.TestExecutionMode.CLUSTER) {
-
- val testFilePath = ExplainTest.this.getClass.getResource("/").getFile
-
- @Test
- def testFilterWithoutExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements((1, "hello"))
- .toTable(tEnv, 'a, 'b)
- .filter("a % 2 = 0")
-
- val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testFilter0.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testFilterWithExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements((1, "hello"))
- .toTable(tEnv, 'a, 'b)
- .filter("a % 2 = 0")
-
- val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testFilter1.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testJoinWithoutExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
- val table = table1.join(table2).where("b = d").select("a, c")
-
- val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testJoin0.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testJoinWithExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
- val table = table1.join(table2).where("b = d").select("a, c")
-
- val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testJoin1.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testUnionWithoutExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table = table1.unionAll(table2)
-
- val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testUnion0.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
- @Test
- def testUnionWithExtended() : Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
- val table = table1.unionAll(table2)
-
- val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
- val source = scala.io.Source.fromFile(testFilePath +
- "../../src/test/scala/resources/testUnion1.out").mkString.replaceAll("\\r\\n", "\n")
- assertEquals(source, result)
- }
-
-}
[31/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala
deleted file mode 100644
index fab6c08..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/batch/table/ExternalCatalogTest.scala
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.catalog.batch.table
-
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
-import org.apache.flink.table.utils.CommonTestData
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for external catalog query plan.
- */
-class ExternalCatalogTest extends ExternalCatalogTestBase {
-
- @Test
- def test(): Unit = {
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val table1 = tEnv.scan("test", "db1", "tb1")
- val table2 = tEnv.scan("test", "db2", "tb2")
- val result = table2
- .select('d * 2, 'e, 'g.upperCase())
- .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
-
- val expected = binaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
- ),
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
- ),
- term("union", "_c0", "e", "_c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testTopLevelTable(): Unit = {
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val table1 = tEnv.scan("test", "tb1")
- val table2 = tEnv.scan("test", "db2", "tb2")
- val result = table2
- .select('d * 2, 'e, 'g.upperCase())
- .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
-
- val expected = binaryNode(
- "DataSetUnion",
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
- ),
- unaryNode(
- "DataSetCalc",
- sourceBatchTableNode(table1TopLevelPath, table1ProjectedFields),
- term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
- ),
- term("union", "_c0", "e", "_c2")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala
deleted file mode 100644
index 786c4a1..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/sql/ExternalCatalogTest.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.catalog.stream.sql
-
-import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
-import org.apache.flink.table.utils.CommonTestData
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for external catalog query plan.
- */
-class ExternalCatalogTest extends ExternalCatalogTestBase {
-
- @Test
- def test(): Unit = {
- val util = streamTestUtil()
-
- util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
- "(SELECT a * 2, b, c FROM test.db1.tb1)"
-
- val expected = binaryNode(
- "DataStreamUnion",
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS EXPR$0", "e", "g"),
- term("where", "<(d, 3)")),
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS EXPR$0", "b", "c")
- ),
- term("union all", "EXPR$0", "e", "g"))
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala
deleted file mode 100644
index 79d3f99..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/stream/table/ExternalCatalogTest.scala
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.catalog.stream.table
-
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.catalog.utils.ExternalCatalogTestBase
-import org.apache.flink.table.utils.CommonTestData
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-/**
- * Test for external catalog query plan.
- */
-class ExternalCatalogTest extends ExternalCatalogTestBase {
-
- @Test
- def testStreamTableApi(): Unit = {
- val util = streamTestUtil()
- val tEnv = util.tableEnv
-
- util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
-
- val table1 = tEnv.scan("test", "db1", "tb1")
- val table2 = tEnv.scan("test", "db2", "tb2")
-
- val result = table2.where("d < 3")
- .select('d * 2, 'e, 'g.upperCase())
- .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
-
- val expected = binaryNode(
- "DataStreamUnion",
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table2Path, table2ProjectedFields),
- term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2"),
- term("where", "<(d, 3)")
- ),
- unaryNode(
- "DataStreamCalc",
- sourceStreamTableNode(table1Path, table1ProjectedFields),
- term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
- ),
- term("union all", "_c0", "e", "_c2")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala
deleted file mode 100644
index 19fbd36..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/catalog/utils/ExternalCatalogTestBase.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.catalog.utils
-
-import org.apache.flink.table.utils.TableTestBase
-
-class ExternalCatalogTestBase extends TableTestBase {
- protected val table1Path: Array[String] = Array("test", "db1", "tb1")
- protected val table1TopLevelPath: Array[String] = Array("test", "tb1")
- protected val table1ProjectedFields: Array[String] = Array("a", "b", "c")
- protected val table2Path: Array[String] = Array("test", "db2", "tb2")
- protected val table2ProjectedFields: Array[String] = Array("d", "e", "g")
-
- def sourceBatchTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
- s"BatchTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
- s"fields=[${fields.mkString(", ")}])"
- }
-
- def sourceStreamTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
- s"StreamTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
- s"fields=[${fields.mkString(", ")}])"
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
index 558e5b3..bd1c199 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/CompositeAccessTest.scala
@@ -19,10 +19,10 @@
package org.apache.flink.table.expressions
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.CompositeAccessTestBase
+import org.apache.flink.table.expressions.utils.CompositeTypeTestBase
import org.junit.Test
-class CompositeAccessTest extends CompositeAccessTestBase {
+class CompositeAccessTest extends CompositeTypeTestBase {
@Test
def testGetField(): Unit = {
@@ -120,7 +120,6 @@ class CompositeAccessTest extends CompositeAccessTestBase {
testTableApi('f5.flatten(), "f5.flatten()", "13")
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
index 7b09733..b2b8016 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/MapTypeTest.scala
@@ -31,5 +31,4 @@ class MapTypeTest extends MapTypeTestBase {
testSqlApi("f3[1]", "null")
testSqlApi("f3[12]", "a")
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/NonDeterministicTests.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/NonDeterministicTests.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/NonDeterministicTests.scala
index bcc53af..d3b606b 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/NonDeterministicTests.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/NonDeterministicTests.scala
@@ -82,7 +82,7 @@ class NonDeterministicTests extends ExpressionTestBase {
// ----------------------------------------------------------------------------------------------
- override def testData: Any = new Row(0)
+ override def testData: Row = new Row(0)
override def typeInfo: TypeInformation[Any] =
new RowTypeInfo().asInstanceOf[TypeInformation[Any]]
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/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 ef021b7..02745b5 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
@@ -20,10 +20,10 @@ package org.apache.flink.table.expressions
import org.apache.flink.table.api.Types
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.ScalarFunctionsTestBase
+import org.apache.flink.table.expressions.utils.ScalarTypesTestBase
import org.junit.Test
-class ScalarFunctionsTest extends ScalarFunctionsTestBase {
+class ScalarFunctionsTest extends ScalarTypesTestBase {
// ----------------------------------------------------------------------------------------------
// String functions
@@ -347,7 +347,6 @@ class ScalarFunctionsTest extends ScalarFunctionsTestBase {
"mod(44, 3)",
"MOD(44, 3)",
"2")
-
}
@Test
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
index 30f8a4c..738413e 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/ScalarOperatorsTest.scala
@@ -18,9 +18,13 @@
package org.apache.flink.table.expressions
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
import org.apache.flink.table.api.Types
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.{ScalarOperatorsTestBase, ShouldNotExecuteFunc}
+import org.apache.flink.table.expressions.utils.{ExpressionTestBase, ScalarOperatorsTestBase, ShouldNotExecuteFunc}
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.types.Row
import org.junit.Test
class ScalarOperatorsTest extends ScalarOperatorsTestBase {
@@ -211,5 +215,4 @@ class ScalarOperatorsTest extends ScalarOperatorsTestBase {
"trueX")
testTableApi(12.isNull, "12.isNull", "false")
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/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 5cc8bd1..c631212 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
@@ -114,6 +114,7 @@ class SqlExpressionTest extends ExpressionTestBase {
testSqlApi("SIGN(-1.1)", "-1")
testSqlApi("ROUND(-12.345, 2)", "-12.35")
testSqlApi("PI", "3.141592653589793")
+ testSqlApi("E()", "2.718281828459045")
}
@Test
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/TemporalTypesTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/TemporalTypesTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/TemporalTypesTest.scala
index 4f47fd5..1d761c3 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/TemporalTypesTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/TemporalTypesTest.scala
@@ -540,7 +540,7 @@ class TemporalTypesTest extends ExpressionTestBase {
// ----------------------------------------------------------------------------------------------
- def testData = {
+ def testData: Row = {
val testData = new Row(11)
testData.setField(0, Date.valueOf("1990-10-14"))
testData.setField(1, Time.valueOf("10:20:45"))
@@ -556,7 +556,7 @@ class TemporalTypesTest extends ExpressionTestBase {
testData
}
- def typeInfo = {
+ def typeInfo: TypeInformation[Any] = {
new RowTypeInfo(
Types.SQL_DATE,
Types.SQL_TIME,
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/UserDefinedScalarFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/UserDefinedScalarFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/UserDefinedScalarFunctionTest.scala
index f0432cf..9b3407e 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/UserDefinedScalarFunctionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/UserDefinedScalarFunctionTest.scala
@@ -25,9 +25,9 @@ import org.apache.flink.api.common.typeinfo.{BasicArrayTypeInfo, TypeInformation
import org.apache.flink.api.java.typeutils.RowTypeInfo
import org.apache.flink.types.Row
import org.apache.flink.table.api.{Types, ValidationException}
-import org.apache.flink.table.api.java.utils.UserDefinedScalarFunctions._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedScalarFunctions._
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils._
+import org.apache.flink.table.expressions.utils.{ExpressionTestBase, _}
import org.apache.flink.table.functions.ScalarFunction
import org.junit.Test
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala
deleted file mode 100644
index c132335..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/sql/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.expressions.batch.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- )
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "*" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testNestedTablesReduction(): Unit = {
- val util = batchTestUtil()
-
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
-
- util.tableEnv.registerTable("NewTable", newTable)
-
- val sqlQuery = "SELECT a FROM NewTable"
-
- // 1+1 should be normalized to 2
- val expected = unaryNode("DataSetCalc", batchTableNode(0), term("select", "+(2, a) AS a"))
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala
deleted file mode 100644
index 595063a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/batch/table/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.expressions.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala
deleted file mode 100644
index 0a22d8c..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/sql/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.expressions.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- )
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "*" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testNestedTablesReduction(): Unit = {
- val util = streamTestUtil()
-
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
-
- util.tableEnv.registerTable("NewTable", newTable)
-
- val sqlQuery = "SELECT a FROM NewTable"
-
- // 1+1 should be normalized to 2
- val expected = unaryNode("DataStreamCalc", streamTableNode(0), term("select", "+(2, a) AS a"))
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala
deleted file mode 100644
index a62bcd3..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/stream/table/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.expressions.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpression(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceProjectExpression(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceFilterExpression(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testNestedTablesReduction(): Unit = {
- val util = streamTestUtil()
-
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
-
- util.tableEnv.registerTable("NewTable", newTable)
-
- val sqlQuery = "SELECT a FROM NewTable"
-
- // 1+1 should be normalized to 2
- val expected = unaryNode("DataStreamCalc", streamTableNode(0), term("select", "+(2, a) AS a"))
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala
deleted file mode 100644
index 7243f1d..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeAccessTestBase.scala
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.expressions.utils
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.{RowTypeInfo, TupleTypeInfo, TypeExtractor}
-import org.apache.flink.api.scala.createTypeInformation
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.expressions.utils.CompositeAccessTestBase.{MyCaseClass, MyCaseClass2, MyPojo}
-import org.apache.flink.types.Row
-
-class CompositeAccessTestBase extends ExpressionTestBase {
-
- def testData = {
- val testData = new Row(8)
- testData.setField(0, MyCaseClass(42, "Bob", booleanField = true))
- testData.setField(1, MyCaseClass2(MyCaseClass(25, "Timo", booleanField = false)))
- testData.setField(2, ("a", "b"))
- testData.setField(3, new org.apache.flink.api.java.tuple.Tuple2[String, String]("a", "b"))
- testData.setField(4, new MyPojo())
- testData.setField(5, 13)
- testData.setField(6, MyCaseClass2(null))
- testData.setField(7, Tuple1(true))
- testData
- }
-
- def typeInfo = {
- new RowTypeInfo(
- createTypeInformation[MyCaseClass],
- createTypeInformation[MyCaseClass2],
- createTypeInformation[(String, String)],
- new TupleTypeInfo(Types.STRING, Types.STRING),
- TypeExtractor.createTypeInfo(classOf[MyPojo]),
- Types.INT,
- createTypeInformation[MyCaseClass2],
- createTypeInformation[Tuple1[Boolean]]
- ).asInstanceOf[TypeInformation[Any]]
- }
-
-}
-
-object CompositeAccessTestBase {
- case class MyCaseClass(intField: Int, stringField: String, booleanField: Boolean)
-
- case class MyCaseClass2(objectField: MyCaseClass)
-
- class MyPojo {
- private var myInt: Int = 0
- private var myString: String = "Hello"
-
- def getMyInt = myInt
-
- def setMyInt(value: Int) = {
- myInt = value
- }
-
- def getMyString = myString
-
- def setMyString(value: String) = {
- myString = myString
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeTypeTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeTypeTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeTypeTestBase.scala
new file mode 100644
index 0000000..8f7360e
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/CompositeTypeTestBase.scala
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.{RowTypeInfo, TupleTypeInfo, TypeExtractor}
+import org.apache.flink.api.scala.createTypeInformation
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.expressions.utils.CompositeTypeTestBase.{MyCaseClass, MyCaseClass2, MyPojo}
+import org.apache.flink.types.Row
+
+class CompositeTypeTestBase extends ExpressionTestBase {
+
+ def testData: Row = {
+ val testData = new Row(8)
+ testData.setField(0, MyCaseClass(42, "Bob", booleanField = true))
+ testData.setField(1, MyCaseClass2(MyCaseClass(25, "Timo", booleanField = false)))
+ testData.setField(2, ("a", "b"))
+ testData.setField(3, new org.apache.flink.api.java.tuple.Tuple2[String, String]("a", "b"))
+ testData.setField(4, new MyPojo())
+ testData.setField(5, 13)
+ testData.setField(6, MyCaseClass2(null))
+ testData.setField(7, Tuple1(true))
+ testData
+ }
+
+ def typeInfo: TypeInformation[Any] = {
+ new RowTypeInfo(
+ createTypeInformation[MyCaseClass],
+ createTypeInformation[MyCaseClass2],
+ createTypeInformation[(String, String)],
+ new TupleTypeInfo(Types.STRING, Types.STRING),
+ TypeExtractor.createTypeInfo(classOf[MyPojo]),
+ Types.INT,
+ createTypeInformation[MyCaseClass2],
+ createTypeInformation[Tuple1[Boolean]]
+ ).asInstanceOf[TypeInformation[Any]]
+ }
+}
+
+object CompositeTypeTestBase {
+ case class MyCaseClass(intField: Int, stringField: String, booleanField: Boolean)
+
+ case class MyCaseClass2(objectField: MyCaseClass)
+
+ class MyPojo {
+ private var myInt: Int = 0
+ private var myString: String = "Hello"
+
+ def getMyInt: Int = myInt
+
+ def setMyInt(value: Int): Unit = {
+ myInt = value
+ }
+
+ def getMyString: String = myString
+
+ def setMyString(value: String): Unit = {
+ myString = myString
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala
index eacf052..d90d9df 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/MapTypeTestBase.scala
@@ -49,5 +49,4 @@ class MapTypeTestBase extends ExpressionTestBase {
new MapTypeInfo(BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO)
).asInstanceOf[TypeInformation[Any]]
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala
deleted file mode 100644
index c526a01..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarFunctionsTestBase.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.expressions.utils
-
-import java.sql.{Date, Time, Timestamp}
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.table.api.Types
-import org.apache.flink.types.Row
-
-class ScalarFunctionsTestBase extends ExpressionTestBase {
-
- def testData = {
- val testData = new Row(33)
- testData.setField(0, "This is a test String.")
- testData.setField(1, true)
- testData.setField(2, 42.toByte)
- testData.setField(3, 43.toShort)
- testData.setField(4, 44.toLong)
- testData.setField(5, 4.5.toFloat)
- testData.setField(6, 4.6)
- testData.setField(7, 3)
- testData.setField(8, " This is a test String. ")
- testData.setField(9, -42.toByte)
- testData.setField(10, -43.toShort)
- testData.setField(11, -44.toLong)
- testData.setField(12, -4.5.toFloat)
- testData.setField(13, -4.6)
- testData.setField(14, -3)
- testData.setField(15, BigDecimal("-1231.1231231321321321111").bigDecimal)
- testData.setField(16, Date.valueOf("1996-11-10"))
- testData.setField(17, Time.valueOf("06:55:44"))
- testData.setField(18, Timestamp.valueOf("1996-11-10 06:55:44.333"))
- testData.setField(19, 1467012213000L) // +16979 07:23:33.000
- testData.setField(20, 25) // +2-01
- testData.setField(21, null)
- testData.setField(22, BigDecimal("2").bigDecimal)
- testData.setField(23, "%This is a test String.")
- testData.setField(24, "*_This is a test String.")
- testData.setField(25, 0.42.toByte)
- testData.setField(26, 0.toShort)
- testData.setField(27, 0.toLong)
- testData.setField(28, 0.45.toFloat)
- testData.setField(29, 0.46)
- testData.setField(30, 1)
- testData.setField(31, BigDecimal("-0.1231231321321321111").bigDecimal)
- testData.setField(32, -1)
- testData
- }
-
- def typeInfo = {
- new RowTypeInfo(
- Types.STRING,
- Types.BOOLEAN,
- Types.BYTE,
- Types.SHORT,
- Types.LONG,
- Types.FLOAT,
- Types.DOUBLE,
- Types.INT,
- Types.STRING,
- Types.BYTE,
- Types.SHORT,
- Types.LONG,
- Types.FLOAT,
- Types.DOUBLE,
- Types.INT,
- Types.DECIMAL,
- Types.SQL_DATE,
- Types.SQL_TIME,
- Types.SQL_TIMESTAMP,
- Types.INTERVAL_MILLIS,
- Types.INTERVAL_MONTHS,
- Types.BOOLEAN,
- Types.DECIMAL,
- Types.STRING,
- Types.STRING,
- Types.BYTE,
- Types.SHORT,
- Types.LONG,
- Types.FLOAT,
- Types.DOUBLE,
- Types.INT,
- Types.DECIMAL,
- Types.INT).asInstanceOf[TypeInformation[Any]]
-
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala
index 0a77d29..2d22843 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarOperatorsTestBase.scala
@@ -26,7 +26,7 @@ import org.apache.flink.types.Row
class ScalarOperatorsTestBase extends ExpressionTestBase {
- def testData = {
+ def testData: Row = {
val testData = new Row(13)
testData.setField(0, 1: Byte)
testData.setField(1, 1: Short)
@@ -44,7 +44,7 @@ class ScalarOperatorsTestBase extends ExpressionTestBase {
testData
}
- def typeInfo = {
+ def typeInfo: TypeInformation[Any] = {
new RowTypeInfo(
Types.BYTE,
Types.SHORT,
@@ -65,5 +65,4 @@ class ScalarOperatorsTestBase extends ExpressionTestBase {
override def functions: Map[String, ScalarFunction] = Map(
"shouldNotExecuteFunc" -> ShouldNotExecuteFunc
)
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/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
new file mode 100644
index 0000000..41fe52c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/ScalarTypesTestBase.scala
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import java.sql.{Date, Time, Timestamp}
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.table.api.Types
+import org.apache.flink.types.Row
+
+class ScalarTypesTestBase extends ExpressionTestBase {
+
+ def testData: Row = {
+ val testData = new Row(34)
+ testData.setField(0, "This is a test String.")
+ testData.setField(1, true)
+ testData.setField(2, 42.toByte)
+ testData.setField(3, 43.toShort)
+ testData.setField(4, 44.toLong)
+ testData.setField(5, 4.5.toFloat)
+ testData.setField(6, 4.6)
+ testData.setField(7, 3)
+ testData.setField(8, " This is a test String. ")
+ testData.setField(9, -42.toByte)
+ testData.setField(10, -43.toShort)
+ testData.setField(11, -44.toLong)
+ testData.setField(12, -4.5.toFloat)
+ testData.setField(13, -4.6)
+ testData.setField(14, -3)
+ testData.setField(15, BigDecimal("-1231.1231231321321321111").bigDecimal)
+ testData.setField(16, Date.valueOf("1996-11-10"))
+ testData.setField(17, Time.valueOf("06:55:44"))
+ testData.setField(18, Timestamp.valueOf("1996-11-10 06:55:44.333"))
+ testData.setField(19, 1467012213000L) // +16979 07:23:33.000
+ testData.setField(20, 25) // +2-01
+ testData.setField(21, null)
+ testData.setField(22, BigDecimal("2").bigDecimal)
+ testData.setField(23, "%This is a test String.")
+ testData.setField(24, "*_This is a test String.")
+ testData.setField(25, 0.42.toByte)
+ testData.setField(26, 0.toShort)
+ testData.setField(27, 0.toLong)
+ testData.setField(28, 0.45.toFloat)
+ testData.setField(29, 0.46)
+ testData.setField(30, 1)
+ testData.setField(31, BigDecimal("-0.1231231321321321111").bigDecimal)
+ testData.setField(32, -1)
+ testData.setField(33, null)
+ testData
+ }
+
+ def typeInfo: TypeInformation[Any] = {
+ new RowTypeInfo(
+ Types.STRING,
+ Types.BOOLEAN,
+ Types.BYTE,
+ Types.SHORT,
+ Types.LONG,
+ Types.FLOAT,
+ Types.DOUBLE,
+ Types.INT,
+ Types.STRING,
+ Types.BYTE,
+ Types.SHORT,
+ Types.LONG,
+ Types.FLOAT,
+ Types.DOUBLE,
+ Types.INT,
+ Types.DECIMAL,
+ Types.SQL_DATE,
+ Types.SQL_TIME,
+ Types.SQL_TIMESTAMP,
+ Types.INTERVAL_MILLIS,
+ Types.INTERVAL_MONTHS,
+ Types.BOOLEAN,
+ Types.DECIMAL,
+ Types.STRING,
+ Types.STRING,
+ Types.BYTE,
+ Types.SHORT,
+ Types.LONG,
+ Types.FLOAT,
+ Types.DOUBLE,
+ Types.INT,
+ Types.DECIMAL,
+ Types.INT,
+ Types.STRING).asInstanceOf[TypeInformation[Any]]
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/UserDefinedScalarFunctions.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/UserDefinedScalarFunctions.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/UserDefinedScalarFunctions.scala
deleted file mode 100644
index 5285569..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/UserDefinedScalarFunctions.scala
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.expressions.utils
-
-import java.sql.{Date, Time, Timestamp}
-
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.functions.{ScalarFunction, FunctionContext}
-import org.junit.Assert
-
-import scala.annotation.varargs
-import scala.collection.mutable
-import scala.io.Source
-
-case class SimplePojo(name: String, age: Int)
-
-object Func0 extends ScalarFunction {
- def eval(index: Int): Int = {
- index
- }
-}
-
-object Func1 extends ScalarFunction {
- def eval(index: Integer): Integer = {
- index + 1
- }
-}
-
-object Func2 extends ScalarFunction {
- def eval(index: Integer, str: String, pojo: SimplePojo): String = {
- s"$index and $str and $pojo"
- }
-}
-
-object Func3 extends ScalarFunction {
- def eval(index: Integer, str: String): String = {
- s"$index and $str"
- }
-}
-
-object Func4 extends ScalarFunction {
- def eval(): Integer = {
- null
- }
-}
-
-object Func5 extends ScalarFunction {
- def eval(): Int = {
- -1
- }
-}
-
-object Func6 extends ScalarFunction {
- def eval(date: Date, time: Time, timestamp: Timestamp): (Date, Time, Timestamp) = {
- (date, time, timestamp)
- }
-}
-
-object Func7 extends ScalarFunction {
- def eval(a: Integer, b: Integer): Integer = {
- a + b
- }
-}
-
-object Func8 extends ScalarFunction {
- def eval(a: Int): String = {
- "a"
- }
-
- def eval(a: Int, b: Int): String = {
- "b"
- }
-
- def eval(a: String, b: String): String = {
- "c"
- }
-}
-
-object Func9 extends ScalarFunction {
- def eval(a: Int, b: Int, c: Long): String = {
- s"$a and $b and $c"
- }
-}
-
-object Func10 extends ScalarFunction {
- def eval(c: Long): Long = {
- c
- }
-
- override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
- Types.SQL_TIMESTAMP
- }
-}
-
-object Func11 extends ScalarFunction {
- def eval(a: Int, b: Long): String = {
- s"$a and $b"
- }
-}
-
-object Func12 extends ScalarFunction {
- def eval(a: Long): Long = {
- a
- }
-
- override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
- Types.INTERVAL_MILLIS
- }
-}
-
-object ShouldNotExecuteFunc extends ScalarFunction {
- def eval(s: String): Boolean = {
- throw new Exception("This func should never be executed")
- }
-}
-
-class RichFunc0 extends ScalarFunction {
- var openCalled = false
- var closeCalled = false
-
- override def open(context: FunctionContext): Unit = {
- super.open(context)
- if (openCalled) {
- Assert.fail("Open called more than once.")
- } else {
- openCalled = true
- }
- if (closeCalled) {
- Assert.fail("Close called before open.")
- }
- }
-
- def eval(index: Int): Int = {
- if (!openCalled) {
- Assert.fail("Open was not called before eval.")
- }
- if (closeCalled) {
- Assert.fail("Close called before eval.")
- }
-
- index + 1
- }
-
- override def close(): Unit = {
- super.close()
- if (closeCalled) {
- Assert.fail("Close called more than once.")
- } else {
- closeCalled = true
- }
- if (!openCalled) {
- Assert.fail("Open was not called before close.")
- }
- }
-}
-
-class RichFunc1 extends ScalarFunction {
- var added = Int.MaxValue
-
- override def open(context: FunctionContext): Unit = {
- added = context.getJobParameter("int.value", "0").toInt
- }
-
- def eval(index: Int): Int = {
- index + added
- }
-
- override def close(): Unit = {
- added = Int.MaxValue
- }
-}
-
-class RichFunc2 extends ScalarFunction {
- var prefix = "ERROR_VALUE"
-
- override def open(context: FunctionContext): Unit = {
- prefix = context.getJobParameter("string.value", "")
- }
-
- def eval(value: String): String = {
- prefix + "#" + value
- }
-
- override def close(): Unit = {
- prefix = "ERROR_VALUE"
- }
-}
-
-class RichFunc3 extends ScalarFunction {
- private val words = mutable.HashSet[String]()
-
- override def open(context: FunctionContext): Unit = {
- val file = context.getCachedFile("words")
- for (line <- Source.fromFile(file.getCanonicalPath).getLines) {
- words.add(line.trim)
- }
- }
-
- def eval(value: String): Boolean = {
- words.contains(value)
- }
-
- override def close(): Unit = {
- words.clear()
- }
-}
-
-class Func13(prefix: String) extends ScalarFunction {
- def eval(a: String): String = {
- s"$prefix-$a"
- }
-}
-
-object Func14 extends ScalarFunction {
-
- @varargs
- def eval(a: Int*): Int = {
- a.sum
- }
-}
-
-object Func15 extends ScalarFunction {
-
- @varargs
- def eval(a: String, b: Int*): String = {
- a + b.length
- }
-
- def eval(a: String): String = {
- a
- }
-}
-
-object Func16 extends ScalarFunction {
-
- def eval(a: Seq[String]): String = {
- a.mkString(", ")
- }
-}
-
-object Func17 extends ScalarFunction {
-
- // Without @varargs, we will throw an exception
- def eval(a: String*): String = {
- a.mkString(", ")
- }
-}
-
-object Func18 extends ScalarFunction {
- def eval(str: String, prefix: String): Boolean = {
- str.startsWith(prefix)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/userDefinedScalarFunctions.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/userDefinedScalarFunctions.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/userDefinedScalarFunctions.scala
new file mode 100644
index 0000000..5285569
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/utils/userDefinedScalarFunctions.scala
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.expressions.utils
+
+import java.sql.{Date, Time, Timestamp}
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.functions.{ScalarFunction, FunctionContext}
+import org.junit.Assert
+
+import scala.annotation.varargs
+import scala.collection.mutable
+import scala.io.Source
+
+case class SimplePojo(name: String, age: Int)
+
+object Func0 extends ScalarFunction {
+ def eval(index: Int): Int = {
+ index
+ }
+}
+
+object Func1 extends ScalarFunction {
+ def eval(index: Integer): Integer = {
+ index + 1
+ }
+}
+
+object Func2 extends ScalarFunction {
+ def eval(index: Integer, str: String, pojo: SimplePojo): String = {
+ s"$index and $str and $pojo"
+ }
+}
+
+object Func3 extends ScalarFunction {
+ def eval(index: Integer, str: String): String = {
+ s"$index and $str"
+ }
+}
+
+object Func4 extends ScalarFunction {
+ def eval(): Integer = {
+ null
+ }
+}
+
+object Func5 extends ScalarFunction {
+ def eval(): Int = {
+ -1
+ }
+}
+
+object Func6 extends ScalarFunction {
+ def eval(date: Date, time: Time, timestamp: Timestamp): (Date, Time, Timestamp) = {
+ (date, time, timestamp)
+ }
+}
+
+object Func7 extends ScalarFunction {
+ def eval(a: Integer, b: Integer): Integer = {
+ a + b
+ }
+}
+
+object Func8 extends ScalarFunction {
+ def eval(a: Int): String = {
+ "a"
+ }
+
+ def eval(a: Int, b: Int): String = {
+ "b"
+ }
+
+ def eval(a: String, b: String): String = {
+ "c"
+ }
+}
+
+object Func9 extends ScalarFunction {
+ def eval(a: Int, b: Int, c: Long): String = {
+ s"$a and $b and $c"
+ }
+}
+
+object Func10 extends ScalarFunction {
+ def eval(c: Long): Long = {
+ c
+ }
+
+ override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
+ Types.SQL_TIMESTAMP
+ }
+}
+
+object Func11 extends ScalarFunction {
+ def eval(a: Int, b: Long): String = {
+ s"$a and $b"
+ }
+}
+
+object Func12 extends ScalarFunction {
+ def eval(a: Long): Long = {
+ a
+ }
+
+ override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
+ Types.INTERVAL_MILLIS
+ }
+}
+
+object ShouldNotExecuteFunc extends ScalarFunction {
+ def eval(s: String): Boolean = {
+ throw new Exception("This func should never be executed")
+ }
+}
+
+class RichFunc0 extends ScalarFunction {
+ var openCalled = false
+ var closeCalled = false
+
+ override def open(context: FunctionContext): Unit = {
+ super.open(context)
+ if (openCalled) {
+ Assert.fail("Open called more than once.")
+ } else {
+ openCalled = true
+ }
+ if (closeCalled) {
+ Assert.fail("Close called before open.")
+ }
+ }
+
+ def eval(index: Int): Int = {
+ if (!openCalled) {
+ Assert.fail("Open was not called before eval.")
+ }
+ if (closeCalled) {
+ Assert.fail("Close called before eval.")
+ }
+
+ index + 1
+ }
+
+ override def close(): Unit = {
+ super.close()
+ if (closeCalled) {
+ Assert.fail("Close called more than once.")
+ } else {
+ closeCalled = true
+ }
+ if (!openCalled) {
+ Assert.fail("Open was not called before close.")
+ }
+ }
+}
+
+class RichFunc1 extends ScalarFunction {
+ var added = Int.MaxValue
+
+ override def open(context: FunctionContext): Unit = {
+ added = context.getJobParameter("int.value", "0").toInt
+ }
+
+ def eval(index: Int): Int = {
+ index + added
+ }
+
+ override def close(): Unit = {
+ added = Int.MaxValue
+ }
+}
+
+class RichFunc2 extends ScalarFunction {
+ var prefix = "ERROR_VALUE"
+
+ override def open(context: FunctionContext): Unit = {
+ prefix = context.getJobParameter("string.value", "")
+ }
+
+ def eval(value: String): String = {
+ prefix + "#" + value
+ }
+
+ override def close(): Unit = {
+ prefix = "ERROR_VALUE"
+ }
+}
+
+class RichFunc3 extends ScalarFunction {
+ private val words = mutable.HashSet[String]()
+
+ override def open(context: FunctionContext): Unit = {
+ val file = context.getCachedFile("words")
+ for (line <- Source.fromFile(file.getCanonicalPath).getLines) {
+ words.add(line.trim)
+ }
+ }
+
+ def eval(value: String): Boolean = {
+ words.contains(value)
+ }
+
+ override def close(): Unit = {
+ words.clear()
+ }
+}
+
+class Func13(prefix: String) extends ScalarFunction {
+ def eval(a: String): String = {
+ s"$prefix-$a"
+ }
+}
+
+object Func14 extends ScalarFunction {
+
+ @varargs
+ def eval(a: Int*): Int = {
+ a.sum
+ }
+}
+
+object Func15 extends ScalarFunction {
+
+ @varargs
+ def eval(a: String, b: Int*): String = {
+ a + b.length
+ }
+
+ def eval(a: String): String = {
+ a
+ }
+}
+
+object Func16 extends ScalarFunction {
+
+ def eval(a: Seq[String]): String = {
+ a.mkString(", ")
+ }
+}
+
+object Func17 extends ScalarFunction {
+
+ // Without @varargs, we will throw an exception
+ def eval(a: String*): String = {
+ a.mkString(", ")
+ }
+}
+
+object Func18 extends ScalarFunction {
+ def eval(str: String, prefix: String): Boolean = {
+ str.startsWith(prefix)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala
index 5542533..829fe65 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/CompositeAccessValidationTest.scala
@@ -20,10 +20,10 @@ package org.apache.flink.table.expressions.validation
import org.apache.flink.table.api.ValidationException
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.CompositeAccessTestBase
+import org.apache.flink.table.expressions.utils.CompositeTypeTestBase
import org.junit.Test
-class CompositeAccessValidationTest extends CompositeAccessTestBase {
+class CompositeAccessValidationTest extends CompositeTypeTestBase {
@Test(expected = classOf[ValidationException])
def testWrongSqlFieldFull(): Unit = {
@@ -54,7 +54,6 @@ class CompositeAccessValidationTest extends CompositeAccessTestBase {
def testWrongStringKeyField2(): Unit = {
testTableApi("fail", "f0.get('fghj')", "fail")
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala
index 819dbbce..deb4518 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarFunctionsValidationTest.scala
@@ -20,10 +20,10 @@ package org.apache.flink.table.expressions.validation
import org.apache.flink.table.api.ValidationException
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils.ScalarFunctionsTestBase
+import org.apache.flink.table.expressions.utils.ScalarTypesTestBase
import org.junit.Test
-class ScalarFunctionsValidationTest extends ScalarFunctionsTestBase {
+class ScalarFunctionsValidationTest extends ScalarTypesTestBase {
// ----------------------------------------------------------------------------------------------
// String functions
@@ -40,5 +40,4 @@ class ScalarFunctionsValidationTest extends ScalarFunctionsTestBase {
// Must fail. Parameter of substring must be an Integer not a String.
testTableApi("test".substring("test".toExpr), "FAIL", "FAIL")
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala
index 68c0b3f..9dcc990 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/expressions/validation/ScalarOperatorsValidationTest.scala
@@ -44,5 +44,4 @@ class ScalarOperatorsValidationTest extends ScalarOperatorsTestBase {
def testInvalidStringComparison2(): Unit = {
testTableApi("w" > 4.toExpr, "FAIL", "FAIL")
}
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AggFunctionTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AggFunctionTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AggFunctionTestBase.scala
deleted file mode 100644
index 39b9ec3..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AggFunctionTestBase.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.functions.aggfunctions
-
-import java.lang.reflect.Method
-import java.math.BigDecimal
-import java.util.{ArrayList => JArrayList, List => JList}
-import org.apache.flink.table.functions.AggregateFunction
-import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils._
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-/**
- * Base class for aggregate function test
- *
- * @tparam T the type for the aggregation result
- */
-abstract class AggFunctionTestBase[T, ACC] {
- def inputValueSets: Seq[Seq[_]]
-
- def expectedResults: Seq[T]
-
- def aggregator: AggregateFunction[T, ACC]
-
- val accType = aggregator.getClass.getMethod("createAccumulator").getReturnType
-
- def accumulateFunc: Method = aggregator.getClass.getMethod("accumulate", accType, classOf[Any])
-
- def retractFunc: Method = null
-
- @Test
- // test aggregate and retract functions without partial merge
- def testAccumulateAndRetractWithoutMerge(): Unit = {
- // iterate over input sets
- for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
- val accumulator = accumulateVals(vals)
- val result = aggregator.getValue(accumulator)
- validateResult[T](expected, result)
-
- if (ifMethodExistInFunction("retract", aggregator)) {
- retractVals(accumulator, vals)
- val expectedAccum = aggregator.createAccumulator()
- //The two accumulators should be exactly same
- validateResult[ACC](expectedAccum, accumulator)
- }
- }
- }
-
- @Test
- def testAggregateWithMerge(): Unit = {
-
- if (ifMethodExistInFunction("merge", aggregator)) {
- val mergeFunc =
- aggregator.getClass.getMethod("merge", accType, classOf[java.lang.Iterable[ACC]])
- // iterate over input sets
- for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
- //equally split the vals sequence into two sequences
- val (firstVals, secondVals) = vals.splitAt(vals.length / 2)
-
- //1. verify merge with accumulate
- val accumulators: JList[ACC] = new JArrayList[ACC]()
- accumulators.add(accumulateVals(secondVals))
-
- val acc = accumulateVals(firstVals)
-
- mergeFunc.invoke(aggregator, acc.asInstanceOf[Object], accumulators)
- val result = aggregator.getValue(acc)
- validateResult[T](expected, result)
-
- //2. verify merge with accumulate & retract
- if (ifMethodExistInFunction("retract", aggregator)) {
- retractVals(acc, vals)
- val expectedAccum = aggregator.createAccumulator()
- //The two accumulators should be exactly same
- validateResult[ACC](expectedAccum, acc)
- }
- }
-
- // iterate over input sets
- for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
- //3. test partial merge with an empty accumulator
- val accumulators: JList[ACC] = new JArrayList[ACC]()
- accumulators.add(aggregator.createAccumulator())
-
- val acc = accumulateVals(vals)
-
- mergeFunc.invoke(aggregator, acc.asInstanceOf[Object], accumulators)
- val result = aggregator.getValue(acc)
- validateResult[T](expected, result)
- }
- }
- }
-
- @Test
- // test aggregate functions with resetAccumulator
- def testResetAccumulator(): Unit = {
-
- if (ifMethodExistInFunction("resetAccumulator", aggregator)) {
- val resetAccFunc = aggregator.getClass.getMethod("resetAccumulator", accType)
- // iterate over input sets
- for ((vals, expected) <- inputValueSets.zip(expectedResults)) {
- val accumulator = accumulateVals(vals)
- resetAccFunc.invoke(aggregator, accumulator.asInstanceOf[Object])
- val expectedAccum = aggregator.createAccumulator()
- //The accumulator after reset should be exactly same as the new accumulator
- validateResult[ACC](expectedAccum, accumulator)
- }
- }
- }
-
- private def validateResult[T](expected: T, result: T): Unit = {
- (expected, result) match {
- case (e: DecimalSumWithRetractAccumulator, r: DecimalSumWithRetractAccumulator) =>
- // BigDecimal.equals() value and scale but we are only interested in value.
- assert(e.f0.compareTo(r.f0) == 0 && e.f1 == r.f1)
- case (e: DecimalAvgAccumulator, r: DecimalAvgAccumulator) =>
- // BigDecimal.equals() value and scale but we are only interested in value.
- assert(e.f0.compareTo(r.f0) == 0 && e.f1 == r.f1)
- case (e: BigDecimal, r: BigDecimal) =>
- // BigDecimal.equals() value and scale but we are only interested in value.
- assert(e.compareTo(r) == 0)
- case _ =>
- assertEquals(expected, result)
- }
- }
-
- private def accumulateVals(vals: Seq[_]): ACC = {
- val accumulator = aggregator.createAccumulator()
- vals.foreach(
- v =>
- accumulateFunc.invoke(aggregator, accumulator.asInstanceOf[Object], v.asInstanceOf[Object])
- )
- accumulator
- }
-
- private def retractVals(accumulator:ACC, vals: Seq[_]) = {
- vals.foreach(
- v => retractFunc.invoke(aggregator, accumulator.asInstanceOf[Object], v.asInstanceOf[Object])
- )
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AvgFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AvgFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AvgFunctionTest.scala
deleted file mode 100644
index fd510ff..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/functions/aggfunctions/AvgFunctionTest.scala
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.functions.aggfunctions
-
-import java.math.BigDecimal
-import org.apache.flink.table.functions.AggregateFunction
-
-/**
- * Test case for built-in average aggregate function
- *
- * @tparam T the type for the aggregation result
- */
-abstract class AvgAggFunctionTestBase[T: Numeric, ACC] extends AggFunctionTestBase[T, ACC] {
-
- private val numeric: Numeric[T] = implicitly[Numeric[T]]
-
- def minVal: T
-
- def maxVal: T
-
- override def inputValueSets: Seq[Seq[T]] = Seq(
- Seq(
- minVal,
- minVal,
- null.asInstanceOf[T],
- minVal,
- minVal,
- null.asInstanceOf[T],
- minVal,
- minVal,
- minVal
- ),
- Seq(
- maxVal,
- maxVal,
- null.asInstanceOf[T],
- maxVal,
- maxVal,
- null.asInstanceOf[T],
- maxVal,
- maxVal,
- maxVal
- ),
- Seq(
- minVal,
- maxVal,
- null.asInstanceOf[T],
- numeric.fromInt(0),
- numeric.negate(maxVal),
- numeric.negate(minVal),
- null.asInstanceOf[T]
- ),
- Seq(
- numeric.fromInt(1),
- numeric.fromInt(2),
- null.asInstanceOf[T],
- numeric.fromInt(3),
- numeric.fromInt(4),
- numeric.fromInt(5),
- null.asInstanceOf[T]
- ),
- Seq(
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T],
- null.asInstanceOf[T]
- )
- )
-
- override def expectedResults: Seq[T] = Seq(
- minVal,
- maxVal,
- numeric.fromInt(0),
- numeric.fromInt(3),
- null.asInstanceOf[T]
- )
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
-
-class ByteAvgAggFunctionTest extends AvgAggFunctionTestBase[Byte, IntegralAvgAccumulator] {
-
- override def minVal = (Byte.MinValue + 1).toByte
-
- override def maxVal = (Byte.MaxValue - 1).toByte
-
- override def aggregator = new ByteAvgAggFunction()
-}
-
-class ShortAvgAggFunctionTest extends AvgAggFunctionTestBase[Short, IntegralAvgAccumulator] {
-
- override def minVal = (Short.MinValue + 1).toShort
-
- override def maxVal = (Short.MaxValue - 1).toShort
-
- override def aggregator = new ShortAvgAggFunction()
-}
-
-class IntAvgAggFunctionTest extends AvgAggFunctionTestBase[Int, IntegralAvgAccumulator] {
-
- override def minVal = Int.MinValue + 1
-
- override def maxVal = Int.MaxValue - 1
-
- override def aggregator = new IntAvgAggFunction()
-}
-
-class LongAvgAggFunctionTest extends AvgAggFunctionTestBase[Long, BigIntegralAvgAccumulator] {
-
- override def minVal = Long.MinValue + 1
-
- override def maxVal = Long.MaxValue - 1
-
- override def aggregator = new LongAvgAggFunction()
-}
-
-class FloatAvgAggFunctionTest extends AvgAggFunctionTestBase[Float, FloatingAvgAccumulator] {
-
- override def minVal = Float.MinValue
-
- override def maxVal = Float.MaxValue
-
- override def aggregator = new FloatAvgAggFunction()
-}
-
-class DoubleAvgAggFunctionTest extends AvgAggFunctionTestBase[Double, FloatingAvgAccumulator] {
-
- override def minVal = Float.MinValue
-
- override def maxVal = Float.MaxValue
-
- override def aggregator = new DoubleAvgAggFunction()
-}
-
-class DecimalAvgAggFunctionTest extends AggFunctionTestBase[BigDecimal, DecimalAvgAccumulator] {
-
- override def inputValueSets: Seq[Seq[_]] = Seq(
- Seq(
- new BigDecimal("987654321000000"),
- new BigDecimal("-0.000000000012345"),
- null,
- new BigDecimal("0.000000000012345"),
- new BigDecimal("-987654321000000"),
- null,
- new BigDecimal("0")
- ),
- Seq(
- new BigDecimal("987654321000000"),
- new BigDecimal("-0.000000000012345"),
- null,
- new BigDecimal("0.000000000012345"),
- new BigDecimal("-987654321000000"),
- null,
- new BigDecimal("5")
- ),
- Seq(
- null,
- null,
- null,
- null
- )
- )
-
- override def expectedResults: Seq[BigDecimal] = Seq(
- BigDecimal.ZERO,
- BigDecimal.ONE,
- null
- )
-
- override def aggregator: AggregateFunction[BigDecimal, DecimalAvgAccumulator] =
- new DecimalAvgAggFunction()
-
- override def retractFunc = aggregator.getClass.getMethod("retract", accType, classOf[Any])
-}
[10/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala
index a16688e..791f778 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsTest.scala
@@ -19,57 +19,22 @@
package org.apache.flink.table.api.scala.stream.table
import org.apache.flink.api.common.typeinfo.BasicTypeInfo
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-import org.apache.flink.table.api.scala._
import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
class GroupAggregationsTest extends TableTestBase {
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
- val overAgg = new OverAgg0
- table.select(overAgg('a, 'b))
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupingOnNonExistentField(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val ds = table
- // must fail. '_foo is not a valid field
- .groupBy('_foo)
- .select('a.avg)
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupingInvalidSelection(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
-
- val ds = table
- .groupBy('a, 'b)
- // must fail. 'c is not a grouping key or aggregation
- .select('c)
- }
-
@Test
- def testGroupbyWithoutWindow() = {
+ def testGroupAggregate() = {
val util = streamTestUtil()
val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
val resultTable = table
- .groupBy('b)
- .select('a.count)
+ .groupBy('b)
+ .select('a.count)
val expected =
unaryNode(
@@ -96,9 +61,9 @@ class GroupAggregationsTest extends TableTestBase {
val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
val resultTable = table
- .select('a, 4 as 'four, 'b)
- .groupBy('four, 'a)
- .select('four, 'b.sum)
+ .select('a, 4 as 'four, 'b)
+ .groupBy('four, 'a)
+ .select('four, 'b.sum)
val expected =
unaryNode(
@@ -124,9 +89,9 @@ class GroupAggregationsTest extends TableTestBase {
val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
val resultTable = table
- .select('b, 4 as 'four, 'a)
- .groupBy('b, 'four)
- .select('four, 'a.sum)
+ .select('b, 4 as 'four, 'a)
+ .groupBy('b, 'four)
+ .select('four, 'a.sum)
val expected =
unaryNode(
@@ -152,9 +117,9 @@ class GroupAggregationsTest extends TableTestBase {
val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
val resultTable = table
- .select('a as 'a, 'b % 3 as 'd, 'c as 'c)
- .groupBy('d)
- .select('c.min, 'a.avg)
+ .select('a as 'a, 'b % 3 as 'd, 'c as 'c)
+ .groupBy('d)
+ .select('c.min, 'a.avg)
val expected =
unaryNode(
@@ -180,9 +145,9 @@ class GroupAggregationsTest extends TableTestBase {
val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
val resultTable = table
- .groupBy('b)
- .select('b, 'a.sum)
- .where('b === 2)
+ .groupBy('b)
+ .select('b, 'a.sum)
+ .where('b === 2)
val expected =
unaryNode(
@@ -205,8 +170,8 @@ class GroupAggregationsTest extends TableTestBase {
val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
val resultTable = table
- .groupBy('b)
- .select('b, 'a.cast(BasicTypeInfo.DOUBLE_TYPE_INFO).avg)
+ .groupBy('b)
+ .select('b, 'a.cast(BasicTypeInfo.DOUBLE_TYPE_INFO).avg)
val expected =
unaryNode(
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala
index d78aea6..92c8522 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsITCase.scala
@@ -29,7 +29,7 @@ import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.scala.stream.table.GroupWindowAggregationsITCase.TimestampAndWatermarkWithOffset
-import org.apache.flink.table.api.scala.stream.utils.StreamITCase
+import org.apache.flink.table.runtime.datastream.StreamITCase
import org.apache.flink.table.functions.aggfunctions.CountAggFunction
import org.apache.flink.types.Row
import org.junit.Assert._
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala
new file mode 100644
index 0000000..6be0e13
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowAggregationsTest.scala
@@ -0,0 +1,785 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{WeightedAvg, WeightedAvgWithMerge}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.WindowReference
+import org.apache.flink.table.plan.logical._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil.{streamTableNode, term, unaryNode}
+import org.junit.{Ignore, Test}
+
+class GroupWindowAggregationsTest extends TableTestBase {
+
+ @Test
+ def testMultiWindow(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 50.milli on 'proctime as 'w1)
+ .groupBy('w1, 'string)
+ .select('w1.proctime as 'proctime, 'string, 'int.count)
+ .window(Slide over 20.milli every 10.milli on 'proctime as 'w2)
+ .groupBy('w2)
+ .select('string.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w1"),
+ 'proctime,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_1", "proctime('w1) AS TMP_0")
+ ),
+ term("select", "string", "TMP_0 AS proctime")
+ ),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w2"),
+ 'proctime,
+ 20.milli,
+ 10.milli)),
+ term("select", "COUNT(string) AS TMP_2")
+ )
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 50.milli on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(WindowReference("w"), 'proctime, 2.rows)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 5.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowWithUdAgg(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val weightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'rowtime,
+ 5.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 2.rows,
+ 1.rows)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "rowtime")
+ ),
+ term("groupBy", "string"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ @Ignore // see comments in DataStreamGroupWindowAggregate
+ def testEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 8.milli,
+ 10.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowWithUdAgg(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val weightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindowWithUdAgg(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val weightedAvg = new WeightedAvgWithMerge
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('long, 'int))
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'rowtime, 7.milli)),
+ term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 50.milli on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "proctime")
+ ),
+ term("groupBy", "string"),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli)),
+ term("select", "string", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "proctime")
+ ),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 2.rows)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "rowtime")
+ ),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ @Ignore // see comments in DataStreamGroupWindowAggregate
+ def testAllEventTimeTumblingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "long")
+ ),
+ term(
+ "window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 5.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "proctime")
+ ),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 50.milli,
+ 50.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllProcessingTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "proctime")
+ ),
+ term(
+ "window",
+ SlidingGroupWindow(
+ WindowReference("w"),
+ 'proctime,
+ 2.rows,
+ 1.rows)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "rowtime")
+ ),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+// @Ignore // see comments in DataStreamGroupWindowAggregate
+ def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Slide over 8.milli every 10.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "long")
+ ),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testAllEventTimeSessionGroupWindowOverTime(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "int", "long")
+ ),
+ term(
+ "window",
+ SessionGroupWindow(
+ WindowReference("w"),
+ 'long,
+ 7.milli)),
+ term("select", "COUNT(int) AS TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testTumbleWindowStartEnd(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "rowtime")
+ ),
+ term("groupBy", "string"),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
+ term("select",
+ "string",
+ "COUNT(int) AS TMP_0",
+ "start('w) AS TMP_1",
+ "end('w) AS TMP_2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testSlidingWindowWithUDAF(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String, Int, Int)](
+ 'long,
+ 'int,
+ 'string,
+ 'int2,
+ 'int3,
+ 'proctime.proctime)
+
+ val weightAvgFun = new WeightedAvg
+
+ val windowedTable = table
+ .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
+ .groupBy('w, 'int2, 'int3, 'string)
+ .select(weightAvgFun('long, 'int))
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string, int2, int3"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'proctime, 2.rows, 1.rows)),
+ term(
+ "select",
+ "string",
+ "int2",
+ "int3",
+ "WeightedAvg(long, int) AS TMP_0")
+ ),
+ term("select","TMP_0")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testSlideWindowStartEnd(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ val windowedTable = table
+ .window(Slide over 10.milli every 5.milli on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected = unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "string", "int", "rowtime")
+ ),
+ term("groupBy", "string"),
+ term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 10.milli, 5.milli)),
+ term("select",
+ "string",
+ "COUNT(int) AS TMP_0",
+ "start('w) AS TMP_1",
+ "end('w) AS TMP_2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testSessionWindowStartWithTwoEnd(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Session withGap 3.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('w.end as 'we1, 'string, 'int.count as 'cnt, 'w.start as 'ws, 'w.end as 'we2)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", SessionGroupWindow(WindowReference("w"), 'long, 3.milli)),
+ term("select",
+ "string",
+ "COUNT(int) AS TMP_1",
+ "end('w) AS TMP_0",
+ "start('w) AS TMP_2")
+ ),
+ term("select", "TMP_0 AS we1", "string", "TMP_1 AS cnt", "TMP_2 AS ws", "TMP_0 AS we2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+
+ @Test
+ def testTumbleWindowWithDuplicateAggsAndProps(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.millis on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.sum + 1 as 's1, 'int.sum + 3 as 's2, 'w.start as 'x, 'w.start as 'x2,
+ 'w.end as 'x3, 'w.end)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ streamTableNode(0),
+ term("groupBy", "string"),
+ term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.millis)),
+ term("select",
+ "string",
+ "SUM(int) AS TMP_0",
+ "start('w) AS TMP_1",
+ "end('w) AS TMP_2")
+ ),
+ term("select",
+ "string",
+ "+(CAST(TMP_0), 1) AS s1",
+ "+(CAST(TMP_0), 3) AS s2",
+ "TMP_1 AS x",
+ "TMP_1 AS x2",
+ "TMP_2 AS x3",
+ "TMP_2")
+ )
+
+ util.verifyTable(windowedTable, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowTest.scala
deleted file mode 100644
index 593b036..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupWindowTest.scala
+++ /dev/null
@@ -1,963 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvg, WeightedAvgWithMerge}
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.WindowReference
-import org.apache.flink.table.plan.logical._
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil.{streamTableNode, term, unaryNode}
-import org.junit.{Ignore, Test}
-
-class GroupWindowTest extends TableTestBase {
-
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val overAgg = new OverAgg0
- table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select(overAgg('long, 'int))
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowProperty(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .groupBy('string)
- .select('string, 'string.start) // property in non windowed table
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupByWithoutWindowAlias(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidRowTimeRef(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
- .groupBy('w2)
- .select('string)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidTumblingSize(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Tumble over "WRONG" on 'long as 'w) // string is not a valid interval
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testTumbleUdAggWithInvalidArgs(): Unit = {
- val util = streamTestUtil()
- val weightedAvg = new WeightedAvgWithMerge
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Tumble over 2.hours on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidSlidingSize(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Slide over "WRONG" every "WRONG" on 'long as 'w) // string is not a valid interval
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidSlidingSlide(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- // row and time intervals may not be mixed
- .window(Slide over 12.rows every 1.minute on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testSlideUdAggWithInvalidArgs(): Unit = {
- val util = streamTestUtil()
- val weightedAvg = new WeightedAvgWithMerge
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Slide over 2.hours every 30.minutes on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidSessionGap(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- // row interval is not valid for session windows
- .window(Session withGap 10.rows on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowAlias1(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- .window(Session withGap 100.milli on 'long as 1 + 1) // expression instead of a symbol
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowAlias2(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- table
- // field name "string" is already present
- .window(Session withGap 100.milli on 'long as 'string)
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testSessionUdAggWithInvalidArgs(): Unit = {
- val util = streamTestUtil()
- val weightedAvg = new WeightedAvgWithMerge
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- table
- .window(Session withGap 2.hours on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowPropertyOnRowCountsTumblingWindow(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowPropertyOnRowCountsSlidingWindow(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- table
- .window(Slide over 10.rows every 5.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
- }
-
- @Test
- def testMultiWindow(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 50.milli on 'proctime as 'w1)
- .groupBy('w1, 'string)
- .select('w1.proctime as 'proctime, 'string, 'int.count)
- .window(Slide over 20.milli every 10.milli on 'proctime as 'w2)
- .groupBy('w2)
- .select('string.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w1"),
- 'proctime,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_1", "proctime('w1) AS TMP_0")
- ),
- term("select", "string", "TMP_0 AS proctime")
- ),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w2"),
- 'proctime,
- 20.milli,
- 10.milli)),
- term("select", "COUNT(string) AS TMP_2")
- )
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 50.milli on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeTumblingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(WindowReference("w"), 'proctime, 2.rows)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'long,
- 5.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeTumblingGroupWindowWithUdAgg(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val weightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'rowtime,
- 5.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testProcessingTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 2.rows,
- 1.rows)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "rowtime")
- ),
- term("groupBy", "string"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- @Ignore // see comments in DataStreamGroupWindowAggregate
- def testEventTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'long,
- 8.milli,
- 10.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSlidingGroupWindowWithUdAgg(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val weightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSessionGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'long, 7.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testEventTimeSessionGroupWindowWithUdAgg(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val weightedAvg = new WeightedAvgWithMerge
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, weightedAvg('long, 'int))
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'rowtime, 7.milli)),
- term("select", "string", "WeightedAvgWithMerge(long, int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 50.milli on 'proctime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "proctime")
- ),
- term("groupBy", "string"),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli)),
- term("select", "string", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeTumblingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Tumble over 2.rows on 'proctime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "proctime")
- ),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 2.rows)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeTumblingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "rowtime")
- ),
- term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- @Ignore // see comments in DataStreamGroupWindowAggregate
- def testAllEventTimeTumblingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "long")
- ),
- term(
- "window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'long,
- 5.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 50.milli every 50.milli on 'proctime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "proctime")
- ),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 50.milli,
- 50.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllProcessingTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "proctime")
- ),
- term(
- "window",
- SlidingGroupWindow(
- WindowReference("w"),
- 'proctime,
- 2.rows,
- 1.rows)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'rowtime as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "rowtime")
- ),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 8.milli, 10.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
-// @Ignore // see comments in DataStreamGroupWindowAggregate
- def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Slide over 8.milli every 10.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "long")
- ),
- term("window", SlidingGroupWindow(WindowReference("w"), 'long, 8.milli, 10.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testAllEventTimeSessionGroupWindowOverTime(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Session withGap 7.milli on 'long as 'w)
- .groupBy('w)
- .select('int.count)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "int", "long")
- ),
- term(
- "window",
- SessionGroupWindow(
- WindowReference("w"),
- 'long,
- 7.milli)),
- term("select", "COUNT(int) AS TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testTumbleWindowStartEnd(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Tumble over 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "rowtime")
- ),
- term("groupBy", "string"),
- term("window", TumblingGroupWindow(WindowReference("w"), 'rowtime, 5.milli)),
- term("select",
- "string",
- "COUNT(int) AS TMP_0",
- "start('w) AS TMP_1",
- "end('w) AS TMP_2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testSlidingWindowWithUDAF(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String, Int, Int)](
- 'long,
- 'int,
- 'string,
- 'int2,
- 'int3,
- 'proctime.proctime)
-
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(Slide over 2.rows every 1.rows on 'proctime as 'w)
- .groupBy('w, 'int2, 'int3, 'string)
- .select(weightAvgFun('long, 'int))
-
- val expected =
- unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string, int2, int3"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'proctime, 2.rows, 1.rows)),
- term(
- "select",
- "string",
- "int2",
- "int3",
- "WeightedAvg(long, int) AS TMP_0")
- ),
- term("select","TMP_0")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testSlideWindowStartEnd(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Slide over 10.milli every 5.milli on 'rowtime as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count, 'w.start, 'w.end)
-
- val expected = unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "string", "int", "rowtime")
- ),
- term("groupBy", "string"),
- term("window", SlidingGroupWindow(WindowReference("w"), 'rowtime, 10.milli, 5.milli)),
- term("select",
- "string",
- "COUNT(int) AS TMP_0",
- "start('w) AS TMP_1",
- "end('w) AS TMP_2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testSessionWindowStartWithTwoEnd(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Session withGap 3.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('w.end as 'we1, 'string, 'int.count as 'cnt, 'w.start as 'ws, 'w.end as 'we2)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", SessionGroupWindow(WindowReference("w"), 'long, 3.milli)),
- term("select",
- "string",
- "COUNT(int) AS TMP_1",
- "end('w) AS TMP_0",
- "start('w) AS TMP_2")
- ),
- term("select", "TMP_0 AS we1", "string", "TMP_1 AS cnt", "TMP_2 AS ws", "TMP_0 AS we2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-
- @Test
- def testTumbleWindowWithDuplicateAggsAndProps(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
-
- val windowedTable = table
- .window(Tumble over 5.millis on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.sum + 1 as 's1, 'int.sum + 3 as 's2, 'w.start as 'x, 'w.start as 'x2,
- 'w.end as 'x3, 'w.end)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- streamTableNode(0),
- term("groupBy", "string"),
- term("window", TumblingGroupWindow(WindowReference("w"), 'long, 5.millis)),
- term("select",
- "string",
- "SUM(int) AS TMP_0",
- "start('w) AS TMP_1",
- "end('w) AS TMP_2")
- ),
- term("select",
- "string",
- "+(CAST(TMP_0), 1) AS s1",
- "+(CAST(TMP_0), 3) AS s2",
- "TMP_1 AS x",
- "TMP_1 AS x2",
- "TMP_2 AS x3",
- "TMP_2")
- )
-
- util.verifyTable(windowedTable, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowITCase.scala
deleted file mode 100644
index 6f9aad2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowITCase.scala
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.source.SourceFunction
-import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
-import org.apache.flink.table.api.java.utils.UserDefinedScalarFunctions.JavaFunc0
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.table.OverWindowITCase.RowTimeSourceFunction
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.table.functions.aggfunctions.CountAggFunction
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class OverWindowITCase extends StreamingWithStateTestBase {
-
- @Test
- def testProcTimeUnBoundedPartitionedRowOver(): Unit = {
-
- val data = List(
- (1L, 1, "Hello"),
- (2L, 2, "Hello"),
- (3L, 3, "Hello"),
- (4L, 4, "Hello"),
- (5L, 5, "Hello"),
- (6L, 6, "Hello"),
- (7L, 7, "Hello World"),
- (8L, 8, "Hello World"),
- (20L, 20, "Hello World"))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- StreamITCase.clear
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
-
- val windowedTable = table
- .window(
- Over partitionBy 'c orderBy 'proctime preceding UNBOUNDED_ROW as 'w)
- .select('c, countFun('b) over 'w as 'mycount, weightAvgFun('a, 'b) over 'w as 'wAvg)
- .select('c, 'mycount, 'wAvg)
-
- val results = windowedTable.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = Seq(
- "Hello World,1,7", "Hello World,2,7", "Hello World,3,14",
- "Hello,1,1", "Hello,2,1", "Hello,3,2", "Hello,4,3", "Hello,5,3", "Hello,6,4")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.testResults = mutable.MutableList()
- StreamITCase.clear
- env.setParallelism(1)
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (1, 1L, "Hello")),
- Left(14000002L, (1, 2L, "Hello")),
- Left(14000002L, (1, 3L, "Hello world")),
- Left(14000003L, (2, 2L, "Hello world")),
- Left(14000003L, (2, 3L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 4L, "Hello world")),
- Left(14000022L, (1, 5L, "Hello world")),
- Left(14000022L, (1, 6L, "Hello world")),
- Left(14000022L, (1, 7L, "Hello world")),
- Left(14000023L, (2, 4L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000030L)
- )
- val table = env
- .addSource(new RowTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
- val countFun = new CountAggFunction
- val weightAvgFun = new WeightedAvg
- val plusOne = new JavaFunc0
-
- val windowedTable = table
- .window(Over partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_RANGE following
- CURRENT_RANGE as 'w)
- .select(
- 'a, 'b, 'c,
- 'b.sum over 'w,
- "SUM:".toExpr + ('b.sum over 'w),
- countFun('b) over 'w,
- (countFun('b) over 'w) + 1,
- plusOne(countFun('b) over 'w),
- array('b.avg over 'w, 'b.max over 'w),
- 'b.avg over 'w,
- 'b.max over 'w,
- 'b.min over 'w,
- ('b.min over 'w).abs(),
- weightAvgFun('b, 'a) over 'w)
-
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,2,Hello,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,1,Hi,7,SUM:7,4,5,5,[1, 3],1,3,1,1,1",
- "2,1,Hello,1,SUM:1,1,2,2,[1, 1],1,1,1,1,1",
- "2,2,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "2,3,Hello world,6,SUM:6,3,4,4,[2, 3],2,3,1,1,2",
- "1,4,Hello world,11,SUM:11,5,6,6,[2, 4],2,4,1,1,2",
- "1,5,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
- "1,6,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
- "1,7,Hello world,29,SUM:29,8,9,9,[3, 7],3,7,1,1,3",
- "2,4,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3",
- "2,5,Hello world,15,SUM:15,5,6,6,[3, 5],3,5,1,1,3"
- )
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeBoundedPartitionedRowsOver(): Unit = {
-
- val data = List(
- (1, 1L, 0, "Hallo", 1L),
- (2, 2L, 1, "Hallo Welt", 2L),
- (2, 3L, 2, "Hallo Welt wie", 1L),
- (3, 4L, 3, "Hallo Welt wie gehts?", 2L),
- (3, 5L, 4, "ABC", 2L),
- (3, 6L, 5, "BCD", 3L),
- (4, 7L, 6, "CDE", 2L),
- (4, 8L, 7, "DEF", 1L),
- (4, 9L, 8, "EFG", 1L),
- (4, 10L, 9, "FGH", 2L),
- (5, 11L, 10, "GHI", 1L),
- (5, 12L, 11, "HIJ", 3L),
- (5, 13L, 12, "IJK", 3L),
- (5, 14L, 13, "JKL", 2L),
- (5, 15L, 14, "KLM", 2L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setParallelism(1)
- StreamITCase.testResults = mutable.MutableList()
-
- val stream = env.fromCollection(data)
- val table = stream.toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
-
- val windowedTable = table
- .window(Over partitionBy 'a orderBy 'proctime preceding 4.rows following CURRENT_ROW as 'w)
- .select('a, 'c.sum over 'w, 'c.min over 'w)
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,0,0",
- "2,1,1",
- "2,3,1",
- "3,3,3",
- "3,7,3",
- "3,12,3",
- "4,6,6",
- "4,13,6",
- "4,21,6",
- "4,30,6",
- "5,10,10",
- "5,21,10",
- "5,33,10",
- "5,46,10",
- "5,60,10")
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRowOver(): Unit = {
- val data = Seq(
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((3L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Right(2L),
- Left((3L, (3L, 3, "Hello"))),
- Left((4L, (4L, 4, "Hello"))),
- Left((5L, (5L, 5, "Hello"))),
- Left((6L, (6L, 6, "Hello"))),
- Left((20L, (20L, 20, "Hello World"))),
- Right(6L),
- Left((8L, (8L, 8, "Hello World"))),
- Left((7L, (7L, 7, "Hello World"))),
- Right(20L))
-
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setParallelism(1)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val table = env.addSource[(Long, Int, String)](
- new RowTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_ROW as 'w)
- .select('c, 'a, 'a.count over 'w, 'a.sum over 'w)
-
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
- "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
- "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
- "Hello,6,3,15",
- "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
- "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRangeOver(): Unit = {
- val data = Seq(
- Left((1500L, (1L, 15, "Hello"))),
- Left((1600L, (1L, 16, "Hello"))),
- Left((1000L, (1L, 1, "Hello"))),
- Left((2000L, (2L, 2, "Hello"))),
- Right(1000L),
- Left((2000L, (2L, 2, "Hello"))),
- Left((2000L, (2L, 3, "Hello"))),
- Left((3000L, (3L, 3, "Hello"))),
- Right(2000L),
- Left((4000L, (4L, 4, "Hello"))),
- Right(3000L),
- Left((5000L, (5L, 5, "Hello"))),
- Right(5000L),
- Left((6000L, (6L, 6, "Hello"))),
- Left((6500L, (6L, 65, "Hello"))),
- Right(7000L),
- Left((9000L, (6L, 9, "Hello"))),
- Left((9500L, (6L, 18, "Hello"))),
- Left((9000L, (6L, 9, "Hello"))),
- Right(10000L),
- Left((10000L, (7L, 7, "Hello World"))),
- Left((11000L, (7L, 17, "Hello World"))),
- Left((11000L, (7L, 77, "Hello World"))),
- Right(12000L),
- Left((14000L, (7L, 18, "Hello World"))),
- Right(14000L),
- Left((15000L, (8L, 8, "Hello World"))),
- Right(17000L),
- Left((20000L, (20L, 20, "Hello World"))),
- Right(19000L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val table = env.addSource[(Long, Int, String)](
- new RowTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- val windowedTable = table
- .window(
- Over partitionBy 'c orderBy 'rowtime preceding 1.seconds following CURRENT_RANGE as 'w)
- .select('c, 'b, 'a.count over 'w, 'a.sum over 'w)
-
- val result = windowedTable.toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
- "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
- "Hello,3,4,9",
- "Hello,4,2,7",
- "Hello,5,2,9",
- "Hello,6,2,11", "Hello,65,2,12",
- "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
- "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
- "Hello World,8,2,15",
- "Hello World,20,1,20")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
-
-object OverWindowITCase {
-
- class RowTimeSourceFunction[T](
- dataWithTimestampList: Seq[Either[(Long, T), Long]]) extends SourceFunction[T] {
- override def run(ctx: SourceContext[T]): Unit = {
- dataWithTimestampList.foreach {
- case Left(t) => ctx.collectWithTimestamp(t._2, t._1)
- case Right(w) => ctx.emitWatermark(new Watermark(w))
- }
- }
-
- override def cancel(): Unit = ???
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala
index e571bae..e11b804 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/OverWindowTest.scala
@@ -19,9 +19,9 @@ package org.apache.flink.table.api.scala.stream.table
import org.apache.flink.api.scala._
import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithRetract
-import org.apache.flink.table.api.{Table, ValidationException}
import org.apache.flink.table.api.scala._
import org.apache.flink.table.expressions.utils.Func1
+import org.apache.flink.table.api.Table
import org.apache.flink.table.utils.TableTestUtil._
import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
import org.junit.Test
@@ -31,92 +31,6 @@ class OverWindowTest extends TableTestBase {
val table: Table = streamUtil.addTable[(Int, String, Long)]("MyTable",
'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
- @Test(expected = classOf[ValidationException])
- def testInvalidWindowAlias(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
- .select('c, 'b.count over 'x)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testOrderBy(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'abc preceding 2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPrecedingAndFollowingUsingIsLiteral(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2 following "xx" as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPrecedingAndFollowingUsingSameType(): Unit = {
- val result = table
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_RANGE as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPartitionByWithUnresolved(): Unit = {
- val result = table
- .window(Over partitionBy 'a + 'b orderBy 'rowtime preceding 2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPartitionByWithNotKeyType(): Unit = {
- val table2 = streamUtil.addTable[(Int, String, Either[Long, String])]("MyTable2", 'a, 'b, 'c)
-
- val result = table2
- .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testPrecedingValue(): Unit = {
- val result = table
- .window(Over orderBy 'rowtime preceding -1.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testFollowingValue(): Unit = {
- val result = table
- .window(Over orderBy 'rowtime preceding 1.rows following -2.rows as 'w)
- .select('c, 'b.count over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUdAggWithInvalidArgs(): Unit = {
- val weightedAvg = new WeightedAvgWithRetract
-
- val result = table
- .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
- .select('c, weightedAvg('b, 'a) over 'w)
- streamUtil.tEnv.optimize(result.getRelNode, updatesAsRetraction = true)
- }
-
- @Test
- def testAccessesWindowProperties(): Unit = {
- thrown.expect(classOf[ValidationException])
- thrown.expectMessage("Window start and end properties are not available for Over windows.")
-
- table
- .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
- .select('c, 'a.count over 'w, 'w.start, 'w.end)
- }
-
@Test
def testScalarFunctionsOnOverWindow() = {
val weightedAvg = new WeightedAvgWithRetract
@@ -676,9 +590,6 @@ class OverWindowTest extends TableTestBase {
streamUtil.verifyTable(result, expected)
}
-
}
-object OverWindowTest{
- case class Pojo(id: Long, name: String)
-}
+
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala
new file mode 100644
index 0000000..a446c84
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/TableSourceTest.scala
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream.table
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.streaming.api.datastream.DataStream
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.sources.{DefinedProctimeAttribute, DefinedRowtimeAttribute, StreamTableSource}
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil.{term, unaryNode}
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class TableSourceTest extends TableTestBase {
+
+ @Test
+ def testRowTimeTableSourceSimple(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
+
+ val t = util.tableEnv.scan("rowTimeT").select("addTime, id, name, val")
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
+ term("select", "TIME_MATERIALIZATION(addTime) AS addTime", "id", "name", "val")
+ )
+ util.verifyTable(t, expected)
+ }
+
+ @Test
+ def testRowTimeTableSourceGroupWindow(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource("addTime"))
+
+ val t = util.tableEnv.scan("rowTimeT")
+ .filter("val > 100")
+ .window(Tumble over 10.minutes on 'addTime as 'w)
+ .groupBy('name, 'w)
+ .select('name, 'w.end, 'val.avg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ "StreamTableSourceScan(table=[[rowTimeT]], fields=[id, val, name, addTime])",
+ term("select", "name", "val", "addTime"),
+ term("where", ">(val, 100)")
+ ),
+ term("groupBy", "name"),
+ term("window", "TumblingGroupWindow('w, 'addTime, 600000.millis)"),
+ term("select", "name", "AVG(val) AS TMP_1", "end('w) AS TMP_0")
+ ),
+ term("select", "name", "TMP_0", "TMP_1")
+ )
+ util.verifyTable(t, expected)
+ }
+
+ @Test
+ def testProcTimeTableSourceSimple(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
+
+ val t = util.tableEnv.scan("procTimeT").select("pTime, id, name, val")
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
+ term("select", "TIME_MATERIALIZATION(pTime) AS pTime", "id", "name", "val")
+ )
+ util.verifyTable(t, expected)
+ }
+
+ @Test
+ def testProcTimeTableSourceOverWindow(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource("pTime"))
+
+ val t = util.tableEnv.scan("procTimeT")
+ .window(Over partitionBy 'id orderBy 'pTime preceding 2.hours as 'w)
+ .select('id, 'name, 'val.sum over 'w as 'valSum)
+ .filter('valSum > 100)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ "StreamTableSourceScan(table=[[procTimeT]], fields=[id, val, name, pTime])",
+ term("partitionBy", "id"),
+ term("orderBy", "pTime"),
+ term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
+ term("select", "id", "val", "name", "pTime", "SUM(val) AS w0$o0")
+ ),
+ term("select", "id", "name", "w0$o0 AS valSum"),
+ term("where", ">(w0$o0, 100)")
+ )
+ util.verifyTable(t, expected)
+ }
+
+
+}
+
+class TestRowtimeSource(timeField: String)
+ extends StreamTableSource[Row] with DefinedRowtimeAttribute {
+
+ override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
+
+ override def getRowtimeAttribute: String = timeField
+
+ override def getReturnType: TypeInformation[Row] = {
+ new RowTypeInfo(
+ Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
+ Array("id", "val", "name"))
+ }
+}
+
+class TestProctimeSource(timeField: String)
+ extends StreamTableSource[Row] with DefinedProctimeAttribute {
+
+ override def getDataStream(execEnv: StreamExecutionEnvironment): DataStream[Row] = ???
+
+ override def getProctimeAttribute: String = timeField
+
+ override def getReturnType: TypeInformation[Row] = {
+ new RowTypeInfo(
+ Array(Types.INT, Types.LONG, Types.STRING).asInstanceOf[Array[TypeInformation[_]]],
+ Array("id", "val", "name"))
+ }
+}
+
+
[09/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnionITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnionITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnionITCase.scala
deleted file mode 100644
index 3d1704e..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnionITCase.scala
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamTestData}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class UnionITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'd, 'e, 'f)
-
- val unionDs = ds1.unionAll(ds2).select('c)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "Hi", "Hello", "Hello world", "Hi", "Hello", "Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnionWithFilter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
-
- val unionDs = ds1.unionAll(ds2.select('a, 'b, 'c)).filter('b < 2).select('c)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("Hi", "Hallo")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnionFieldsNameNotOverlap1(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
-
- val unionDs = ds1.unionAll(ds2)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- assertEquals(true, StreamITCase.testResults.isEmpty)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnionFieldsNameNotOverlap2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .select('a, 'b, 'c)
-
- val unionDs = ds1.unionAll(ds2)
-
- val results = unionDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- assertEquals(true, StreamITCase.testResults.isEmpty)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnionTablesFromDifferentEnvs(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv1 = TableEnvironment.getTableEnvironment(env)
- val tEnv2 = TableEnvironment.getTableEnvironment(env)
-
- val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv1, 'a, 'b, 'c)
- val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv2, 'a, 'b, 'c)
-
- // Must fail. Tables are bound to different TableEnvironments.
- ds1.unionAll(ds2)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnsupportedOpsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnsupportedOpsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnsupportedOpsTest.scala
deleted file mode 100644
index 0e33d8b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UnsupportedOpsTest.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.junit.Test
-
-class UnsupportedOpsTest extends StreamingMultipleProgramsTestBase {
-
- @Test(expected = classOf[ValidationException])
- def testSort(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).orderBy('_1.desc)
- }
-
- @Test(expected = classOf[ValidationException])
- def testJoin(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.join(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.union(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testIntersect(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.intersect(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testIntersectAll(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.intersectAll(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMinus(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.minus(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testMinusAll(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.minusAll(t2)
- }
-
- @Test(expected = classOf[ValidationException])
- def testLimit(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv)
- t1.limit(0,5)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala
index 3edfd8c..bb9877b 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/UserDefinedTableFunctionTest.scala
@@ -18,257 +18,14 @@
package org.apache.flink.table.api.scala.stream.table
import org.apache.flink.api.scala._
-import org.apache.flink.types.Row
-import org.apache.flink.api.java.typeutils.RowTypeInfo
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api._
-import org.apache.flink.table.expressions.utils._
import org.apache.flink.table.utils.TableTestUtil._
import org.apache.flink.table.utils._
-import org.apache.flink.streaming.api.datastream.{DataStream => JDataStream}
-import org.apache.flink.streaming.api.environment.{StreamExecutionEnvironment => JavaExecutionEnv}
-import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment => ScalaExecutionEnv}
-import org.junit.Assert.{assertTrue, fail}
import org.junit.Test
-import org.mockito.Mockito._
class UserDefinedTableFunctionTest extends TableTestBase {
@Test
- def testJavaScalaTableAPIEquality(): Unit = {
- // mock
- val ds = mock(classOf[DataStream[Row]])
- val jDs = mock(classOf[JDataStream[Row]])
- val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
- when(ds.javaStream).thenReturn(jDs)
- when(jDs.getType).thenReturn(typeInfo)
-
- // Scala environment
- val env = mock(classOf[ScalaExecutionEnv])
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val in1 = ds.toTable(tableEnv).as('a, 'b, 'c)
-
- // Java environment
- val javaEnv = mock(classOf[JavaExecutionEnv])
- val javaTableEnv = TableEnvironment.getTableEnvironment(javaEnv)
- val in2 = javaTableEnv.fromDataStream(jDs).as("a, b, c")
-
- // test cross join
- val func1 = new TableFunc1
- javaTableEnv.registerFunction("func1", func1)
- var scalaTable = in1.join(func1('c) as 's).select('c, 's)
- var javaTable = in2.join(new Table(javaTableEnv, "func1(c).as(s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test left outer join
- scalaTable = in1.leftOuterJoin(func1('c) as 's).select('c, 's)
- javaTable = in2.leftOuterJoin(new Table(javaTableEnv, "func1(c)").as("s")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test overloading
- scalaTable = in1.join(func1('c, "$") as 's).select('c, 's)
- javaTable = in2.join(new Table(javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // test custom result type
- val func2 = new TableFunc2
- javaTableEnv.registerFunction("func2", func2)
- scalaTable = in1.join(func2('c) as ('name, 'len)).select('c, 'name, 'len)
- javaTable = in2.join(new Table(javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
- verifyTableEquals(scalaTable, javaTable)
-
- // test hierarchy generic type
- val hierarchy = new HierarchyTableFunction
- javaTableEnv.registerFunction("hierarchy", hierarchy)
- scalaTable = in1.join(hierarchy('c) as ('name, 'adult, 'len))
- .select('c, 'name, 'len, 'adult)
- javaTable = in2.join(new Table(javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
- .select("c, name, len, adult")
- verifyTableEquals(scalaTable, javaTable)
-
- // test pojo type
- val pojo = new PojoTableFunc
- javaTableEnv.registerFunction("pojo", pojo)
- scalaTable = in1.join(pojo('c))
- .select('c, 'name, 'age)
- javaTable = in2.join(new Table(javaTableEnv, "pojo(c)"))
- .select("c, name, age")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with filter
- scalaTable = in1.join(func2('c) as ('name, 'len))
- .select('c, 'name, 'len).filter('len > 2)
- javaTable = in2.join(new Table(javaTableEnv, "func2(c) as (name, len)"))
- .select("c, name, len").filter("len > 2")
- verifyTableEquals(scalaTable, javaTable)
-
- // test with scalar function
- scalaTable = in1.join(func1('c.substring(2)) as 's)
- .select('a, 'c, 's)
- javaTable = in2.join(new Table(javaTableEnv, "func1(substring(c, 2)) as (s)"))
- .select("a, c, s")
- verifyTableEquals(scalaTable, javaTable)
-
- // check scala object is forbidden
- expectExceptionThrown(
- tableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
- expectExceptionThrown(
- javaTableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
- expectExceptionThrown(in1.join(ObjectTableFunction('a, 1)), "Scala object")
-
- }
-
- @Test
- def testInvalidTableFunctions(): Unit = {
- // mock
- val ds = mock(classOf[DataStream[Row]])
- val jDs = mock(classOf[JDataStream[Row]])
- val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
- when(ds.javaStream).thenReturn(jDs)
- when(jDs.getType).thenReturn(typeInfo)
-
- // Scala environment
- val env = mock(classOf[ScalaExecutionEnv])
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val in1 = ds.toTable(tableEnv).as('a, 'b, 'c)
-
- // Java environment
- val javaEnv = mock(classOf[JavaExecutionEnv])
- val javaTableEnv = TableEnvironment.getTableEnvironment(javaEnv)
- val in2 = javaTableEnv.fromDataStream(jDs).as("a, b, c")
-
- val func1 = new TableFunc1
- javaTableEnv.registerFunction("func1", func1)
-
- // table function call select
- expectExceptionThrown(
- func1('c).select("f0"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call select
- expectExceptionThrown(
- func1('c).select('f0),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call writeToSink
- expectExceptionThrown(
- func1('c).writeToSink(null),
- "Cannot translate a query with an unbounded table function call."
- )
-
- // table function call distinct
- expectExceptionThrown(
- func1('c).distinct(),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call filter
- expectExceptionThrown(
- func1('c).filter('f0 === "?"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call filter
- expectExceptionThrown(
- func1('c).filter("f0 = '?'"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call limit
- expectExceptionThrown(
- func1('c).orderBy('f0).limit(3),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call limit
- expectExceptionThrown(
- func1('c).orderBy('f0).limit(0, 3),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call orderBy
- expectExceptionThrown(
- func1('c).orderBy("f0"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call orderBy
- expectExceptionThrown(
- func1('c).orderBy('f0),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call where
- expectExceptionThrown(
- func1('c).where("f0 = '?'"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call where
- expectExceptionThrown(
- func1('c).where('f0 === "?"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- }
-
- @Test
- def testInvalidTableFunction(): Unit = {
- // mock
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
- val tEnv = TableEnvironment.getTableEnvironment(mock(classOf[JavaExecutionEnv]))
-
- //=================== check scala object is forbidden =====================
- // Scala table environment register
- expectExceptionThrown(util.addFunction("udtf", ObjectTableFunction), "Scala object")
- // Java table environment register
- expectExceptionThrown(tEnv.registerFunction("udtf", ObjectTableFunction), "Scala object")
- // Scala Table API directly call
- expectExceptionThrown(t.join(ObjectTableFunction('a, 1)), "Scala object")
-
-
- //============ throw exception when table function is not registered =========
- // Java Table API call
- expectExceptionThrown(
- t.join(new Table(util.tEnv, "nonexist(a)")
- ), "Undefined function: NONEXIST")
- // SQL API call
- expectExceptionThrown(
- util.tEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(nonexist(a))"),
- "No match found for function signature nonexist(<NUMERIC>)")
-
-
- //========= throw exception when the called function is a scalar function ====
- util.tEnv.registerFunction("func0", Func0)
-
- // Java Table API call
- expectExceptionThrown(
- t.join(new Table(util.tEnv, "func0(a)")),
- "only accept String that define table function",
- classOf[TableException])
- // SQL API call
- // NOTE: it doesn't throw an exception but an AssertionError, maybe a Calcite bug
- expectExceptionThrown(
- util.tEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func0(a))"),
- null,
- classOf[AssertionError])
-
- //========== throw exception when the parameters is not correct ===============
- // Java Table API call
- util.addFunction("func2", new TableFunc2)
- expectExceptionThrown(
- t.join(new Table(util.tEnv, "func2(c, c)")),
- "Given parameters of function 'FUNC2' do not match any signature")
- // SQL API call
- expectExceptionThrown(
- util.tEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func2(c, c))"),
- "No match found for function signature func2(<CHARACTER>, <CHARACTER>)")
- }
-
- @Test
def testCrossJoin(): Unit = {
val util = streamTestUtil()
val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
@@ -459,25 +216,4 @@ class UserDefinedTableFunctionTest extends TableTestBase {
util.verifyTable(result, expected)
}
- // ----------------------------------------------------------------------------------------------
-
- private def expectExceptionThrown(
- function: => Unit,
- keywords: String,
- clazz: Class[_ <: Throwable] = classOf[ValidationException])
- : Unit = {
- try {
- function
- fail(s"Expected a $clazz, but no exception is thrown.")
- } catch {
- case e if e.getClass == clazz =>
- if (keywords != null) {
- assertTrue(
- s"The exception message '${e.getMessage}' doesn't contain keyword '$keywords'",
- e.getMessage.contains(keywords))
- }
- case e: Throwable => fail(s"Expected throw ${clazz.getSimpleName}, but is $e.")
- }
- }
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala
new file mode 100644
index 0000000..b558193
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/CalcStringExpressionTest.scala
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testSimpleSelect(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]()
+
+ val resScala = t.select('_1, '_2)
+ val resJava = t.select("_1, _2")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSelectStar(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.select('*)
+ val resJava = t.select("*")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSelectWithWhere(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val resScala = t.where('string === "true").select('int)
+ val resJava = t.where("string === 'true'").select("int")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSimpleSelectWithNaming(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.select('int, 'string)
+ val resJava = t.select("int, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSimpleSelectWithAlias(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val resScala = t.select('int as 'myInt, 'string as 'myString)
+ val resJava = t.select("int as myInt, string as myString")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testSimpleFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter('int === 3).select('int as 'myInt, 'string)
+ val resJava = t.filter("int === 3").select("int as myInt, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter(Literal(false)).select('int as 'myInt, 'string)
+ val resJava = t.filter("false").select("int as myInt, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter(Literal(true)).select('int as 'myInt, 'string)
+ val resJava = t.filter("true").select("int as myInt, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testNotEqualsFilter(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter('int !== 2).filter('string.like("%world%")).select('int, 'string)
+ val resJava = t.filter("int !== 2").filter("string.like('%world%')").select("int, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testFilterWithExpression(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t.filter('int % 2 === 0).select('int, 'string)
+ val resJava = t.filter("int % 2 === 0").select("int, string")
+ verifyTableEquals(resJava, resScala)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala
new file mode 100644
index 0000000..fb23f09
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupAggregationsStringExpressionTest.scala
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
+import org.junit.Test
+
+class GroupAggregationsStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testGroupedAggregate(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .groupBy('string)
+ .select('int.count as 'cnt, weightAvgFun('long, 'int))
+
+ // String / Java API
+ val resJava = t
+ .groupBy("string")
+ .select("int.count as cnt, weightAvgFun(long, int)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testNonGroupedAggregate(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ // Expression / Scala API
+ val resScala = t.select('int.count as 'cnt, 'long.sum)
+
+ // String / Java API
+ val resJava = t.select("int.count as cnt, long.sum")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
index 1cc156e..bb0b121 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/GroupWindowStringExpressionTest.scala
@@ -18,9 +18,9 @@
package org.apache.flink.table.api.scala.stream.table.stringexpr
import org.apache.flink.api.scala._
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
-import org.apache.flink.table.api.java.{Slide => JSlide}
import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
+import org.apache.flink.table.api.java.{Slide => JSlide, Session => JSession, Tumble => JTumble}
import org.apache.flink.table.functions.aggfunctions.CountAggFunction
import org.apache.flink.table.utils.TableTestBase
import org.junit.Test
@@ -29,14 +29,14 @@ import org.junit.Test
class GroupWindowStringExpressionTest extends TableTestBase {
@Test
- def testJavaScalaTableAPIEquality(): Unit = {
+ def testRowTimeSlide(): Unit = {
val util = streamTestUtil()
val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'rowtime.rowtime)
val myCountFun = new CountAggFunction
- util.tEnv.registerFunction("myCountFun", myCountFun)
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
val weightAvgFun = new WeightedAvg
- util.tEnv.registerFunction("weightAvgFun", weightAvgFun)
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
// Expression / Scala API
val resScala = t
@@ -66,4 +66,193 @@ class GroupWindowStringExpressionTest extends TableTestBase {
verifyTableEquals(resJava, resScala)
}
+
+ @Test
+ def testRowTimeTumble(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, Long, String)]('int, 'long, 'rowtime.rowtime, 'string)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Tumble over 4.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select(
+ 'string,
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JTumble.over("4.hours").on("rowtime").as("w"))
+ .groupBy("w, string")
+ .select(
+ "string, " +
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)," +
+ "end(w)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testRowTimeSession(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'rowtime.rowtime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Session withGap 4.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select(
+ 'string,
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start)
+
+ // String / Java API
+ val resJava = t
+ .window(JSession.withGap("4.hours").on("rowtime").as("w"))
+ .groupBy("w, string")
+ .select(
+ "string, " +
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)"
+ )
+
+ verifyTableEquals(resJava, resScala)
+ }
+ @Test
+ def testProcTimeSlide(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'proctime.proctime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Slide over 4.hours every 2.hours on 'proctime as 'w)
+ .groupBy('w)
+ .select(
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JSlide.over("4.hours").every("2.hours").on("proctime").as("w"))
+ .groupBy("w")
+ .select(
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)," +
+ "end(w)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testProcTimeTumble(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long,'string, 'proctime.proctime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Tumble over 4.hours on 'proctime as 'w)
+ .groupBy('w)
+ .select(
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JTumble.over("4.hours").on("proctime").as("w"))
+ .groupBy("w")
+ .select(
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w)," +
+ "end(w)")
+
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testProcTimeSession(): Unit = {
+ val util = streamTestUtil()
+ val t = util.addTable[(Int, Long, String)]('int, 'long, 'string, 'proctime.proctime)
+
+ val myCountFun = new CountAggFunction
+ util.tableEnv.registerFunction("myCountFun", myCountFun)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
+ // Expression / Scala API
+ val resScala = t
+ .window(Session withGap 4.hours on 'proctime as 'w)
+ .groupBy('w)
+ .select(
+ myCountFun('string),
+ 'int.sum,
+ weightAvgFun('long, 'int),
+ weightAvgFun('int, 'int) * 2,
+ 'w.start,
+ 'w.end)
+
+ // String / Java API
+ val resJava = t
+ .window(JSession.withGap("4.hours").on("proctime").as("w"))
+ .groupBy("w")
+ .select(
+ "myCountFun(string), " +
+ "int.sum, " +
+ "weightAvgFun(long, int), " +
+ "weightAvgFun(int, int) * 2, " +
+ "start(w), " +
+ "end(w)"
+ )
+
+ verifyTableEquals(resJava, resScala)
+ }
+
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala
index 4c95916..9430514 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/OverWindowStringExpressionTest.scala
@@ -20,6 +20,7 @@ package org.apache.flink.table.api.scala.stream.table.stringexpr
import org.apache.flink.api.scala._
import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithRetract
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvg
import org.apache.flink.table.api.java.{Over => JOver}
import org.apache.flink.table.api.scala.{Over => SOver, _}
import org.apache.flink.table.expressions.utils.Func1
@@ -33,12 +34,15 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_ROW as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w as 'cnt, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_row").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w as cnt, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -48,12 +52,15 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver orderBy 'rowtime preceding UNBOUNDED_ROW following CURRENT_ROW as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(JOver.orderBy("rowtime").preceding("unbounded_row").following("current_row").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -63,12 +70,15 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver partitionBy('a, 'd) orderBy 'rowtime preceding 10.rows as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(JOver.partitionBy("a, d").orderBy("rowtime").preceding("10.rows").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -78,12 +88,15 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver orderBy 'rowtime preceding 10.rows following CURRENT_ROW as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(JOver.orderBy("rowtime").preceding("10.rows").following("current_row").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -93,12 +106,15 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver partitionBy 'a orderBy 'rowtime preceding UNBOUNDED_RANGE as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(JOver.partitionBy("a").orderBy("rowtime").preceding("unbounded_range").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -108,13 +124,16 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver orderBy 'rowtime preceding UNBOUNDED_RANGE following CURRENT_RANGE as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(
JOver.orderBy("rowtime").preceding("unbounded_range").following("current_range").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -124,12 +143,15 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver partitionBy('a, 'c) orderBy 'rowtime preceding 10.minutes as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(JOver.partitionBy("a, c").orderBy("rowtime").preceding("10.minutes").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -139,12 +161,15 @@ class OverWindowStringExpressionTest extends TableTestBase {
val util = streamTestUtil()
val t = util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rowtime.rowtime)
+ val weightAvgFun = new WeightedAvg
+ util.tableEnv.registerFunction("weightAvgFun", weightAvgFun)
+
val resScala = t
.window(SOver orderBy 'rowtime preceding 4.hours following CURRENT_RANGE as 'w)
- .select('a, 'b.sum over 'w)
+ .select('a, 'b.sum over 'w, weightAvgFun('a, 'b) over 'w as 'myCnt)
val resJava = t
.window(JOver.orderBy("rowtime").preceding("4.hours").following("current_range").as("w"))
- .select("a, SUM(b) OVER w")
+ .select("a, SUM(b) OVER w, weightAvgFun(a, b) over w as myCnt")
verifyTableEquals(resScala, resJava)
}
@@ -181,6 +206,4 @@ class OverWindowStringExpressionTest extends TableTestBase {
verifyTableEquals(resScala, resJava)
}
-
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala
new file mode 100644
index 0000000..dc2e92f
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UnionStringExpressionTest.scala
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.stringexpr
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class UnionStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testUnionAll(): Unit = {
+ val util = streamTestUtil()
+ val t1 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val t2 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+
+ val resScala = t1.unionAll(t2).select('int)
+ val resJava = t1.unionAll(t2).select("int")
+ verifyTableEquals(resJava, resScala)
+ }
+
+ @Test
+ def testUnionAllWithFilter(): Unit = {
+ val util = streamTestUtil()
+ val t1 = util.addTable[(Int, Long, String)]('int, 'long, 'string)
+ val t2 = util.addTable[(Int, Long, Double, String)]('int, 'long, 'double, 'string)
+
+ val resScala = t1.unionAll(t2.select('int, 'long, 'string)).filter('int < 2).select('int)
+ val resJava = t1.unionAll(t2.select("int, long, string")).filter("int < 2").select("int")
+ verifyTableEquals(resJava, resScala)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
new file mode 100644
index 0000000..2f0c57c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/stringexpr/UserDefinedTableFunctionStringExpressionTest.scala
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.stringexpr
+
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api._
+import org.apache.flink.table.utils._
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class UserDefinedTableFunctionStringExpressionTest extends TableTestBase {
+
+ @Test
+ def testJoin(): Unit = {
+
+ val util = streamTestUtil()
+ val sTab = util.addTable[(Int, Long, String)]('a, 'b, 'c)
+ val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
+ val jTab = util.addJavaTable[Row](typeInfo,"MyTab","a, b, c")
+
+ // test cross join
+ val func1 = new TableFunc1
+ util.javaTableEnv.registerFunction("func1", func1)
+ var scalaTable = sTab.join(func1('c) as 's).select('c, 's)
+ var javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c).as(s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test left outer join
+ scalaTable = sTab.leftOuterJoin(func1('c) as 's).select('c, 's)
+ javaTable = jTab.leftOuterJoin(new Table(util.javaTableEnv, "func1(c)").as("s")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test overloading
+ scalaTable = sTab.join(func1('c, "$") as 's).select('c, 's)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func1(c, '$') as (s)")).select("c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test custom result type
+ val func2 = new TableFunc2
+ util.javaTableEnv.registerFunction("func2", func2)
+ scalaTable = sTab.join(func2('c) as ('name, 'len)).select('c, 'name, 'len)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func2(c).as(name, len)")).select("c, name, len")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test hierarchy generic type
+ val hierarchy = new HierarchyTableFunction
+ util.javaTableEnv.registerFunction("hierarchy", hierarchy)
+ scalaTable = sTab.join(hierarchy('c) as ('name, 'adult, 'len)).select('c, 'name, 'len, 'adult)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "AS(hierarchy(c), name, adult, len)"))
+ .select("c, name, len, adult")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test pojo type
+ val pojo = new PojoTableFunc
+ util.javaTableEnv.registerFunction("pojo", pojo)
+ scalaTable = sTab.join(pojo('c)).select('c, 'name, 'age)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "pojo(c)")).select("c, name, age")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with filter
+ scalaTable = sTab.join(func2('c) as ('name, 'len)).select('c, 'name, 'len).filter('len > 2)
+ javaTable = jTab.join(new Table(util.javaTableEnv, "func2(c) as (name, len)"))
+ .select("c, name, len").filter("len > 2")
+ verifyTableEquals(scalaTable, javaTable)
+
+ // test with scalar function
+ scalaTable = sTab.join(func1('c.substring(2)) as 's).select('a, 'c, 's)
+ javaTable = jTab.join(
+ new Table(util.javaTableEnv, "func1(substring(c, 2)) as (s)")).select("a, c, s")
+ verifyTableEquals(scalaTable, javaTable)
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala
new file mode 100644
index 0000000..879fca3
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/CalcValidationTest.scala
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.api.TableException
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+import scala.collection.mutable
+
+class CalcValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testAsWithToManyFields(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("no")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testAsWithAmbiguousFields(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'b)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("no")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testOnlyFieldRefInAs(): Unit = {
+
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ StreamITCase.testResults = mutable.MutableList()
+ val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b as 'c, 'd)
+
+ val results = ds.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ val expected = mutable.MutableList("no")
+ assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala
new file mode 100644
index 0000000..5cec6fc
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupAggregationsValidationTest.scala
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupAggregationsValidationTest extends TableTestBase {
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testOverAggregation(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+ val overAgg = new OverAgg0
+ table.select(overAgg('a, 'b))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupingOnNonExistentField(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val ds = table
+ // must fail. '_foo is not a valid field
+ .groupBy('_foo)
+ .select('a.avg)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupingInvalidSelection(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val ds = table
+ .groupBy('a, 'b)
+ // must fail. 'c is not a grouping key or aggregation
+ .select('c)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala
new file mode 100644
index 0000000..e046986
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/GroupWindowAggregationsValidationTest.scala
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowAggregationsValidationTest extends TableTestBase {
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testOverAggregation(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ val overAgg = new OverAgg0
+ table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select(overAgg('long, 'int))
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowProperty(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .groupBy('string)
+ .select('string, 'string.start) // property in non windowed table
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testGroupByWithoutWindowAlias(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidRowTimeRef(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
+ .groupBy('w2)
+ .select('string)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidTumblingSize(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Tumble over "WRONG" on 'long as 'w) // string is not a valid interval
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testTumbleUdAggWithInvalidArgs(): Unit = {
+ val util = streamTestUtil()
+ val weightedAvg = new WeightedAvgWithMerge
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Tumble over 2.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSlidingSize(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Slide over "WRONG" every "WRONG" on 'long as 'w) // string is not a valid interval
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSlidingSlide(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ // row and time intervals may not be mixed
+ .window(Slide over 12.rows every 1.minute on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSlideUdAggWithInvalidArgs(): Unit = {
+ val util = streamTestUtil()
+ val weightedAvg = new WeightedAvgWithMerge
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
+
+ table
+ .window(Slide over 2.hours every 30.minutes on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidSessionGap(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ // row interval is not valid for session windows
+ .window(Session withGap 10.rows on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowAlias1(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ .window(Session withGap 100.milli on 'long as 1 + 1) // expression instead of a symbol
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowAlias2(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long.rowtime, 'int, 'string)
+
+ table
+ // field name "string" is already present
+ .window(Session withGap 100.milli on 'long as 'string)
+ .groupBy('string)
+ .select('string, 'int.count)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testSessionUdAggWithInvalidArgs(): Unit = {
+ val util = streamTestUtil()
+ val weightedAvg = new WeightedAvgWithMerge
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
+
+ table
+ .window(Session withGap 2.hours on 'rowtime as 'w)
+ .groupBy('w, 'string)
+ .select('string, weightedAvg('string, 'int)) // invalid UDAGG args
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowPropertyOnRowCountsTumblingWindow(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ table
+ .window(Tumble over 2.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowPropertyOnRowCountsSlidingWindow(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
+
+ table
+ .window(Slide over 10.rows every 5.rows on 'proctime as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'w.start, 'w.end) // invalid start/end on rows-count window
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala
new file mode 100644
index 0000000..cb84ae4
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/OverWindowValidationTest.scala
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithRetract
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{Table, ValidationException}
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class OverWindowValidationTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ val table: Table = streamUtil.addTable[(Int, String, Long)]("MyTable",
+ 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidWindowAlias(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
+ .select('c, 'b.count over 'x)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testOrderBy(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'abc preceding 2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPrecedingAndFollowingUsingIsLiteral(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2 following "xx" as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPrecedingAndFollowingUsingSameType(): Unit = {
+ val result = table
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows following CURRENT_RANGE as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPartitionByWithUnresolved(): Unit = {
+ val result = table
+ .window(Over partitionBy 'a + 'b orderBy 'rowtime preceding 2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPartitionByWithNotKeyType(): Unit = {
+ val table2 = streamUtil.addTable[(Int, String, Either[Long, String])]("MyTable2", 'a, 'b, 'c)
+
+ val result = table2
+ .window(Over partitionBy 'c orderBy 'rowtime preceding 2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testPrecedingValue(): Unit = {
+ val result = table
+ .window(Over orderBy 'rowtime preceding -1.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testFollowingValue(): Unit = {
+ val result = table
+ .window(Over orderBy 'rowtime preceding 1.rows following -2.rows as 'w)
+ .select('c, 'b.count over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUdAggWithInvalidArgs(): Unit = {
+ val weightedAvg = new WeightedAvgWithRetract
+
+ val result = table
+ .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
+ .select('c, weightedAvg('b, 'a) over 'w)
+ streamUtil.tableEnv.optimize(result.getRelNode, updatesAsRetraction = true)
+ }
+
+ @Test
+ def testAccessesWindowProperties(): Unit = {
+ thrown.expect(classOf[ValidationException])
+ thrown.expectMessage("Window start and end properties are not available for Over windows.")
+
+ table
+ .window(Over orderBy 'rowtime preceding 1.minutes as 'w)
+ .select('c, 'a.count over 'w, 'w.start, 'w.end)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala
new file mode 100644
index 0000000..72fb0b6
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSinksValidationTest.scala
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.{TableEnvironment, TableException}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.runtime.datastream.table.{TestAppendSink, TestUpsertSink}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableSinksValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testAppendSinkOnUpdatingTable(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'id, 'num, 'text)
+
+ t.groupBy('text)
+ .select('text, 'id.count, 'num.sum)
+ .writeToSink(new TestAppendSink)
+
+ // must fail because table is not append-only
+ env.execute()
+ }
+
+ @Test(expected = classOf[TableException])
+ def testUpsertSinkOnUpdatingTableWithoutFullKey(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val t = StreamTestData.get3TupleDataStream(env)
+ .assignAscendingTimestamps(_._1.toLong)
+ .toTable(tEnv, 'id, 'num, 'text)
+
+ t.select('id, 'num, 'text.charLength() as 'len, ('id > 0) as 'cTrue)
+ .groupBy('len, 'cTrue)
+ .select('len, 'id.count, 'num.sum)
+ .writeToSink(new TestUpsertSink(Array("len", "cTrue"), false))
+
+ // must fail because table is updating table without full key
+ env.execute()
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala
new file mode 100644
index 0000000..bcfa146
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TableSourceValidationTest.scala
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.table.{TestProctimeSource, TestRowtimeSource}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TableSourceValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeTableSourceWithEmptyName(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("rowTimeT", new TestRowtimeSource(" "))
+
+ val t = util.tableEnv.scan("rowTimeT")
+ .select('id)
+
+ util.tableEnv.optimize(t.getRelNode, false)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testProctimeTableSourceWithEmptyName(): Unit = {
+ val util = streamTestUtil()
+ util.tableEnv.registerTableSource("procTimeT", new TestProctimeSource(" "))
+
+ val t = util.tableEnv.scan("procTimeT")
+ .select('id)
+
+ util.tableEnv.optimize(t.getRelNode, false)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala
new file mode 100644
index 0000000..7a684d1
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/TimeAttributesValidationTest.scala
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.scala.{Tumble, _}
+import org.apache.flink.table.api.{TableEnvironment, TableException, ValidationException}
+import org.apache.flink.table.runtime.datastream.table.TimeAttributesITCase._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class TimeAttributesValidationTest extends TableTestBase {
+
+ val data = List(
+ (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
+ (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
+ (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
+ (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
+ (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
+ (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"),
+ (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"))
+
+ @Test(expected = classOf[TableException])
+ def testInvalidTimeCharacteristic(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidUseOfRowtime(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ .select('rowtime.rowtime)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidUseOfRowtime2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ stream
+ .toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ .window(Tumble over 2.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select('w.end.rowtime, 'int.count as 'int) // no rowtime on non-window reference
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala
new file mode 100644
index 0000000..1767d9f
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UnionValidationTest.scala
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.stream.utils.StreamTestData
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.runtime.datastream.StreamITCase
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+import scala.collection.mutable
+
+class UnionValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionFieldsNameNotOverlap1(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'd, 'c, 'e)
+
+ val unionDs = ds1.unionAll(ds2)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ assertEquals(true, StreamITCase.testResults.isEmpty)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionFieldsNameNotOverlap2(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ StreamITCase.testResults = mutable.MutableList()
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .select('a, 'b, 'c)
+
+ val unionDs = ds1.unionAll(ds2)
+
+ val results = unionDs.toAppendStream[Row]
+ results.addSink(new StreamITCase.StringSink[Row])
+ env.execute()
+
+ assertEquals(true, StreamITCase.testResults.isEmpty)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testUnionTablesFromDifferentEnv(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv1 = TableEnvironment.getTableEnvironment(env)
+ val tEnv2 = TableEnvironment.getTableEnvironment(env)
+
+ val ds1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv1, 'a, 'b, 'c)
+ val ds2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv2, 'a, 'b, 'c)
+
+ // Must fail. Tables are bound to different TableEnvironments.
+ ds1.unionAll(ds2)
+ }
+}
[23/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala
deleted file mode 100644
index 6b68665..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SetOperatorsITCase.scala
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-import scala.util.Random
-
-@RunWith(classOf[Parameterized])
-class SetOperatorsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testUnionAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
-
- val unionDs = ds1.unionAll(ds2).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnion(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
-
- val unionDs = ds1.union(ds2).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTernaryUnionAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val unionDs = ds1.unionAll(ds2).unionAll(ds3).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" +
- "Hi\n" + "Hello\n" + "Hello world\n" +
- "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTernaryUnion(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val unionDs = ds1.union(ds2).union(ds3).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMinusAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
-
- val minusDs = ds1.unionAll(ds1).unionAll(ds1)
- .minusAll(ds2.unionAll(ds2)).select('c)
-
- val results = minusDs.toDataSet[Row].collect()
- val expected = "Hi\n" +
- "Hello\n" + "Hello world\n" +
- "Hello\n" + "Hello world\n" +
- "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMinus(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
-
- val minusDs = ds1.unionAll(ds1).unionAll(ds1)
- .minus(ds2.unionAll(ds2)).select('c)
-
- val results = minusDs.toDataSet[Row].collect()
- val expected = "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMinusDifferentFieldNames(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'd, 'e, 'f)
-
- val minusDs = ds1.unionAll(ds1).unionAll(ds1)
- .minus(ds2.unionAll(ds2)).select('c)
-
- val results = minusDs.toDataSet[Row].collect()
- val expected = "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersect(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Hi"))
- data.+=((2, 2L, "Hello"))
- data.+=((2, 2L, "Hello"))
- data.+=((3, 2L, "Hello world!"))
- val ds2 = env.fromCollection(Random.shuffle(data)).toTable(tEnv, 'a, 'b, 'c)
-
- val intersectDS = ds1.intersect(ds2).select('c).toDataSet[Row]
-
- val results = intersectDS.collect()
-
- val expected = "Hi\n" + "Hello\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data1 = new mutable.MutableList[Int]
- data1 += (1, 1, 1, 2, 2)
- val data2 = new mutable.MutableList[Int]
- data2 += (1, 2, 2, 2, 3)
- val ds1 = env.fromCollection(data1).toTable(tEnv, 'c)
- val ds2 = env.fromCollection(data2).toTable(tEnv, 'c)
-
- val intersectDS = ds1.intersectAll(ds2).select('c).toDataSet[Row]
-
- val expected = "1\n2\n2"
- val results = intersectDS.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectWithDifferentFieldNames(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'e, 'f, 'g)
-
- val intersectDs = ds1.intersect(ds2).select('c)
-
- val results = intersectDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectWithScalarExpression(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a + 1, 'b, 'c)
- val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a + 1, 'b, 'c)
-
- val intersectDs = ds1.intersect(ds2)
-
- val results = intersectDs.toDataSet[Row].collect()
- val expected = "2,1,Hi\n" + "3,2,Hello\n" + "4,2,Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala
deleted file mode 100644
index 1784d81..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/SortITCase.scala
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.api.scala.{ExecutionEnvironment, _}
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.SortTestUtils._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsClusterTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-@RunWith(classOf[Parameterized])
-class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
- extends TableProgramsClusterTestBase(mode, configMode) {
-
- private def getExecutionEnvironment = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- // set the parallelism explicitly to make sure the query is executed in
- // a distributed manner
- env.setParallelism(3)
- env
- }
-
- @Test
- def testOrderByDesc(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.desc)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- - x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByAsc(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.asc)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByMultipleFieldsDifferentDirections(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_2.asc, '_1.desc)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- (x.productElement(1).asInstanceOf[Long], - x.productElement(0).asInstanceOf[Int]) )
-
- val expected = sortExpectedly(tupleDataSetStrings)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- def rowOrdering = Ordering.by((r : Row) => {
- // ordering for this tuple will fall into the previous defined tupleOrdering,
- // so we just need to return the field by their defining sequence
- (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
- })
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(rowOrdering)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByOffset(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.asc).limit(3)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings, 3, 21)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByOffsetAndFetch(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.desc).limit(3, 5)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- - x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings, 3, 8)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
- @Test
- def testOrderByFetch(): Unit = {
- val env = getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- val t = ds.toTable(tEnv).orderBy('_1.asc).limit(0, 5)
- implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
- x.productElement(0).asInstanceOf[Int] )
-
- val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
- // squash all rows inside a partition into one element
- val results = t.toDataSet[Row].mapPartition(rows => {
- // the rows need to be copied in object reuse mode
- val copied = new mutable.ArrayBuffer[Row]
- rows.foreach(r => copied += Row.copy(r))
- Seq(copied)
- }).collect()
-
- implicit def rowOrdering = Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int])
-
- val result = results
- .filterNot(_.isEmpty)
- // sort all partitions by their head element to verify the order across partitions
- .sortBy(_.head)
- .reduceLeft(_ ++ _)
-
- TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala
deleted file mode 100644
index c7153dd..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableEnvironmentITCase.scala
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import java.util
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class TableEnvironmentITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSimpleRegister(): Unit = {
-
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet(tableName, ds)
- val t = tEnv.scan(tableName).select('_1, '_2, '_3)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRegisterWithFields(): Unit = {
-
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env)
- tEnv.registerDataSet(tableName, ds, 'a, 'b, 'c)
- val t = tEnv.scan(tableName).select('a, 'b)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" +
- "7,4\n" + "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
- "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableRegister(): Unit = {
-
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- tEnv.registerTable(tableName, t)
-
- val regT = tEnv.scan(tableName).select('a, 'b).filter('a > 8)
-
- val expected = "9,4\n" + "10,4\n" +
- "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" +
- "15,5\n" + "16,6\n" + "17,6\n" + "18,6\n" +
- "19,6\n" + "20,6\n" + "21,6\n"
-
- val results = regT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testToTable(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env)
- .toTable(tEnv, 'a, 'b, 'c)
- .select('a, 'b, 'c)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testToTableFromCaseClass(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- SomeCaseClass("Peter", 28, 4000.00, "Sales"),
- SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
- SomeCaseClass("Lucy", 42, 6000.00, "HR"))
-
- val t = env.fromCollection(data)
- .toTable(tEnv, 'a, 'b, 'c, 'd)
- .select('a, 'b, 'c, 'd)
-
- val expected: String =
- "Peter,28,4000.0,Sales\n" +
- "Anna,56,10000.0,Engineering\n" +
- "Lucy,42,6000.0,HR\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testToTableFromAndToCaseClass(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List(
- SomeCaseClass("Peter", 28, 4000.00, "Sales"),
- SomeCaseClass("Anna", 56, 10000.00, "Engineering"),
- SomeCaseClass("Lucy", 42, 6000.00, "HR"))
-
- val t = env.fromCollection(data)
- .toTable(tEnv, 'a, 'b, 'c, 'd)
- .select('a, 'b, 'c, 'd)
-
- val expected: String =
- "SomeCaseClass(Peter,28,4000.0,Sales)\n" +
- "SomeCaseClass(Anna,56,10000.0,Engineering)\n" +
- "SomeCaseClass(Lucy,42,6000.0,HR)\n"
- val results = t.toDataSet[SomeCaseClass].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-}
-
-object TableEnvironmentITCase {
-
- @Parameterized.Parameters(name = "Table config = {0}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](
- Array(TableProgramsTestBase.DEFAULT)
- ).asJava
- }
-}
-
-case class SomeCaseClass(name: String, age: Int, salary: Double, department: String) {
- def this() { this("", 0, 0.0, "") }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala
deleted file mode 100644
index c8f26ec..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSinkITCase.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import java.io.File
-
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.api.scala.{ExecutionEnvironment, _}
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.sinks.CsvTableSink
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-
-@RunWith(classOf[Parameterized])
-class TableSinkITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testBatchTableSink(): Unit = {
-
- val tmpFile = File.createTempFile("flink-table-sink-test", ".tmp")
- tmpFile.deleteOnExit()
- val path = tmpFile.toURI.toString
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- env.setParallelism(4)
-
- val input = CollectionDataSets.get3TupleDataSet(env)
- .map(x => x).setParallelism(4) // increase DOP to 4
-
- val results = input.toTable(tEnv, 'a, 'b, 'c)
- .where('a < 5 || 'a > 17)
- .select('c, 'b)
- .writeToSink(new CsvTableSink(path, fieldDelim = "|"))
-
- env.execute()
-
- val expected = Seq(
- "Hi|1", "Hello|2", "Hello world|2", "Hello world, how are you?|3",
- "Comment#12|6", "Comment#13|6", "Comment#14|6", "Comment#15|6").mkString("\n")
-
- TestBaseUtils.compareResultsByLinesInMemory(expected, path)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala
deleted file mode 100644
index fb93f26..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/dataset/table/TableSourceITCase.scala
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.dataset.table
-
-import org.apache.flink.api.scala.ExecutionEnvironment
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.utils.{CommonTestData, TestFilterableTableSource}
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class TableSourceITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testCsvTableSourceWithProjection(): Unit = {
- val csvTable = CommonTestData.getCsvTableSource
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- tEnv.registerTableSource("csvTable", csvTable)
-
- val results = tEnv
- .scan("csvTable")
- .where('score < 20)
- .select('last, 'id.floor(), 'score * 2)
- .collect()
-
- val expected = Seq(
- "Smith,1,24.6",
- "Miller,3,15.78",
- "Smith,4,0.24",
- "Miller,6,13.56",
- "Williams,8,4.68").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTableSourceWithFilterable(): Unit = {
- val tableName = "MyTable"
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- tableEnv.registerTableSource(tableName, new TestFilterableTableSource)
- val results = tableEnv
- .scan(tableName)
- .where("amount > 4 && price < 9")
- .select("id, name")
- .collect()
-
- val expected = Seq(
- "5,Record_5", "6,Record_6", "7,Record_7", "8,Record_8").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala
deleted file mode 100644
index e04bd75..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamITCase.scala
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream
-
-import java.util.Collections
-
-import org.apache.flink.streaming.api.functions.sink.RichSinkFunction
-import org.apache.flink.types.Row
-import org.junit.Assert._
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-import scala.collection.mutable.ArrayBuffer
-
-object StreamITCase {
-
- var testResults: mutable.MutableList[String] = mutable.MutableList.empty[String]
- var retractedResults: ArrayBuffer[String] = mutable.ArrayBuffer.empty[String]
-
- def clear = {
- StreamITCase.testResults.clear()
- StreamITCase.retractedResults.clear()
- }
-
- def compareWithList(expected: java.util.List[String]): Unit = {
- Collections.sort(expected)
- assertEquals(expected.asScala, StreamITCase.testResults.sorted)
- }
-
- final class StringSink[T] extends RichSinkFunction[T]() {
- def invoke(value: T) {
- testResults.synchronized {
- testResults += value.toString
- }
- }
- }
-
- final class RetractMessagesSink extends RichSinkFunction[(Boolean, Row)]() {
- def invoke(v: (Boolean, Row)) {
- testResults.synchronized {
- testResults += (if (v._1) "+" else "-") + v._2
- }
- }
- }
-
- final class RetractingSink() extends RichSinkFunction[(Boolean, Row)] {
- def invoke(v: (Boolean, Row)) {
- retractedResults.synchronized {
- val value = v._2.toString
- if (v._1) {
- retractedResults += value
- } else {
- val idx = retractedResults.indexOf(value)
- if (idx >= 0) {
- retractedResults.remove(idx)
- } else {
- throw new RuntimeException("Tried to retract a value that wasn't added first. " +
- "This is probably an incorrectly implemented test. " +
- "Try to set the parallelism of the sink to 1.")
- }
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala
deleted file mode 100644
index c32dd00..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/StreamingWithStateTestBase.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.runtime.datastream
-
-import org.apache.flink.contrib.streaming.state.RocksDBStateBackend
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.junit.Rule
-import org.junit.rules.TemporaryFolder
-
-class StreamingWithStateTestBase extends StreamingMultipleProgramsTestBase {
-
- val _tempFolder = new TemporaryFolder
-
- @Rule
- def tempFolder: TemporaryFolder = _tempFolder
-
- def getStateBackend: RocksDBStateBackend = {
- val dbPath = tempFolder.newFolder().getAbsolutePath
- val checkpointPath = tempFolder.newFolder().toURI.toString
- val backend = new RocksDBStateBackend(checkpointPath)
- backend.setDbStoragePath(dbPath)
- backend
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala
deleted file mode 100644
index 15828eb..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/OverWindowITCase.scala
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.sql
-
-import org.apache.flink.api.common.time.Time
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.sql.TimeTestUtil.EventTimeSourceFunction
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit._
-
-import scala.collection.mutable
-
-class OverWindowITCase extends StreamingWithStateTestBase {
-
- val data = List(
- (1L, 1, "Hello"),
- (2L, 2, "Hello"),
- (3L, 3, "Hello"),
- (4L, 4, "Hello"),
- (5L, 5, "Hello"),
- (6L, 6, "Hello"),
- (7L, 7, "Hello World"),
- (8L, 8, "Hello World"),
- (20L, 20, "Hello World"))
-
- @Test
- def testProcTimeBoundedPartitionedRowsOver(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setParallelism(1)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
- tEnv.registerTable("MyTable", t)
-
- val sqlQuery = "SELECT a, " +
- " SUM(c) OVER (" +
- " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW), " +
- " MIN(c) OVER (" +
- " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) " +
- "FROM MyTable"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,0,0",
- "2,1,1",
- "2,3,1",
- "3,3,3",
- "3,7,3",
- "3,12,3",
- "4,6,6",
- "4,13,6",
- "4,21,6",
- "4,30,6",
- "5,10,10",
- "5,21,10",
- "5,33,10",
- "5,46,10",
- "5,60,10")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeBoundedNonPartitionedRowsOver(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
- tEnv.registerTable("MyTable", t)
-
- val sqlQuery = "SELECT a, " +
- " SUM(c) OVER (" +
- " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW), " +
- " MIN(c) OVER (" +
- " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) " +
- "FROM MyTable"
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,0,0",
- "2,1,0",
- "2,3,0",
- "3,6,0",
- "3,10,0",
- "3,15,0",
- "4,21,0",
- "4,28,0",
- "4,36,0",
- "4,45,0",
- "5,55,0",
- "5,66,1",
- "5,77,2",
- "5,88,3",
- "5,99,4")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeUnboundedPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- // for sum aggregation ensure that every time the order of each element is consistent
- env.setParallelism(1)
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
- "sum(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) " +
- "from T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello World,1,7", "Hello World,2,15", "Hello World,3,35",
- "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeUnboundedPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT c, cnt1 from " +
- "(SELECT " +
- "c, " +
- "count(a) " +
- " OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
- "as cnt1 from T1)"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello World,1", "Hello World,2", "Hello World,3",
- "Hello,1", "Hello,2", "Hello,3", "Hello,4", "Hello,5", "Hello,6")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
-
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRangeOver(): Unit = {
- val queryConfig =
- new StreamQueryConfig().withIdleStateRetentionTime(Time.hours(2), Time.hours(3))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- // for sum aggregation ensure that every time the order of each element is consistent
- env.setParallelism(1)
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding), " +
- "sum(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) " +
- "from T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row](queryConfig)
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello World,7,28", "Hello World,8,36", "Hello World,9,56",
- "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "count(a) OVER (ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
- "from T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("1", "2", "3", "4", "5", "6", "7", "8", "9")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRangeOver(): Unit = {
- val data = Seq(
- Left((1500L, (1L, 15, "Hello"))),
- Left((1600L, (1L, 16, "Hello"))),
- Left((1000L, (1L, 1, "Hello"))),
- Left((2000L, (2L, 2, "Hello"))),
- Right(1000L),
- Left((2000L, (2L, 2, "Hello"))),
- Left((2000L, (2L, 3, "Hello"))),
- Left((3000L, (3L, 3, "Hello"))),
- Right(2000L),
- Left((4000L, (4L, 4, "Hello"))),
- Right(3000L),
- Left((5000L, (5L, 5, "Hello"))),
- Right(5000L),
- Left((6000L, (6L, 6, "Hello"))),
- Left((6500L, (6L, 65, "Hello"))),
- Right(7000L),
- Left((9000L, (6L, 9, "Hello"))),
- Left((9500L, (6L, 18, "Hello"))),
- Left((9000L, (6L, 9, "Hello"))),
- Right(10000L),
- Left((10000L, (7L, 7, "Hello World"))),
- Left((11000L, (7L, 17, "Hello World"))),
- Left((11000L, (7L, 77, "Hello World"))),
- Right(12000L),
- Left((14000L, (7L, 18, "Hello World"))),
- Right(14000L),
- Left((15000L, (8L, 8, "Hello World"))),
- Right(17000L),
- Left((20000L, (20L, 20, "Hello World"))),
- Right(19000L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- " c, b, " +
- " COUNT(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
- " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
- " SUM(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
- " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW)" +
- " FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
- "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
- "Hello,3,4,9",
- "Hello,4,2,7",
- "Hello,5,2,9",
- "Hello,6,2,11", "Hello,65,2,12",
- "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
- "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
- "Hello World,8,2,15",
- "Hello World,20,1,20")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRowsOver(): Unit = {
- val data = Seq(
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((3L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Right(2L),
- Left((3L, (3L, 3, "Hello"))),
- Left((4L, (4L, 4, "Hello"))),
- Left((5L, (5L, 5, "Hello"))),
- Left((6L, (6L, 6, "Hello"))),
- Left((20L, (20L, 20, "Hello World"))),
- Right(6L),
- Left((8L, (8L, 8, "Hello World"))),
- Left((7L, (7L, 7, "Hello World"))),
- Right(20L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- " c, a, " +
- " COUNT(a) " +
- " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), " +
- " SUM(a) " +
- " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
- "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
- "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
- "Hello,6,3,15",
- "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
- "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRangeOver(): Unit = {
- val data = Seq(
- Left((1500L, (1L, 15, "Hello"))),
- Left((1600L, (1L, 16, "Hello"))),
- Left((1000L, (1L, 1, "Hello"))),
- Left((2000L, (2L, 2, "Hello"))),
- Right(1000L),
- Left((2000L, (2L, 2, "Hello"))),
- Left((2000L, (2L, 3, "Hello"))),
- Left((3000L, (3L, 3, "Hello"))),
- Right(2000L),
- Left((4000L, (4L, 4, "Hello"))),
- Right(3000L),
- Left((5000L, (5L, 5, "Hello"))),
- Right(5000L),
- Left((6000L, (6L, 6, "Hello"))),
- Left((6500L, (6L, 65, "Hello"))),
- Right(7000L),
- Left((9000L, (6L, 9, "Hello"))),
- Left((9500L, (6L, 18, "Hello"))),
- Left((9000L, (6L, 9, "Hello"))),
- Right(10000L),
- Left((10000L, (7L, 7, "Hello World"))),
- Left((11000L, (7L, 17, "Hello World"))),
- Left((11000L, (7L, 77, "Hello World"))),
- Right(12000L),
- Left((14000L, (7L, 18, "Hello World"))),
- Right(14000L),
- Left((15000L, (8L, 8, "Hello World"))),
- Right(17000L),
- Left((20000L, (20L, 20, "Hello World"))),
- Right(19000L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- " c, b, " +
- " COUNT(a) " +
- " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
- " SUM(a) " +
- " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW) " +
- " FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
- "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
- "Hello,3,4,9",
- "Hello,4,2,7",
- "Hello,5,2,9",
- "Hello,6,2,11", "Hello,65,2,12",
- "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
- "Hello World,7,4,25", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
- "Hello World,8,2,15",
- "Hello World,20,1,20")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRowsOver(): Unit = {
-
- val data = Seq(
- Left((2L, (2L, 2, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((20L, (20L, 20, "Hello World"))), // early row
- Right(3L),
- Left((2L, (2L, 2, "Hello"))), // late row
- Left((3L, (3L, 3, "Hello"))),
- Left((4L, (4L, 4, "Hello"))),
- Left((5L, (5L, 5, "Hello"))),
- Left((6L, (6L, 6, "Hello"))),
- Left((7L, (7L, 7, "Hello World"))),
- Right(7L),
- Left((9L, (9L, 9, "Hello World"))),
- Left((8L, (8L, 8, "Hello World"))),
- Left((8L, (8L, 8, "Hello World"))),
- Right(20L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "c, a, " +
- " COUNT(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW), " +
- " SUM(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW) " +
- "FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
- "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
- "Hello,3,3,7",
- "Hello,4,3,9", "Hello,5,3,12",
- "Hello,6,3,15", "Hello World,7,3,18",
- "Hello World,8,3,21", "Hello World,8,3,23",
- "Hello World,9,3,25",
- "Hello World,20,3,37")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- StreamITCase.clear
-
- val sqlQuery = "SELECT a, b, c, " +
- " SUM(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " COUNT(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " AVG(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MAX(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MIN(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (1, 1L, "Hello")),
- Left(14000002L, (1, 2L, "Hello")),
- Left(14000002L, (1, 3L, "Hello world")),
- Left(14000003L, (2, 2L, "Hello world")),
- Left(14000003L, (2, 3L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 4L, "Hello world")),
- Left(14000022L, (1, 5L, "Hello world")),
- Left(14000022L, (1, 6L, "Hello world")),
- Left(14000022L, (1, 7L, "Hello world")),
- Left(14000023L, (2, 4L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000030L))
-
- val t1 = env
- .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,1,Hello,6,3,2,3,1",
- "1,2,Hello,6,3,2,3,1",
- "1,3,Hello world,6,3,2,3,1",
- "1,1,Hi,7,4,1,3,1",
- "2,1,Hello,1,1,1,1,1",
- "2,2,Hello world,6,3,2,3,1",
- "2,3,Hello world,6,3,2,3,1",
- "1,4,Hello world,11,5,2,4,1",
- "1,5,Hello world,29,8,3,7,1",
- "1,6,Hello world,29,8,3,7,1",
- "1,7,Hello world,29,8,3,7,1",
- "2,4,Hello world,15,5,3,5,1",
- "2,5,Hello world,15,5,3,5,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.testResults = mutable.MutableList()
-
- val sqlQuery = "SELECT a, b, c, " +
- "SUM(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "count(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "avg(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "max(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "min(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row) " +
- "from T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (3, 1L, "Hello")),
- Left(14000003L, (1, 2L, "Hello")),
- Left(14000004L, (1, 3L, "Hello world")),
- Left(14000007L, (3, 2L, "Hello world")),
- Left(14000008L, (2, 2L, "Hello world")),
- Right(14000010L),
- Left(14000012L, (1, 5L, "Hello world")),
- Left(14000021L, (1, 6L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000020L),
- Left(14000024L, (3, 5L, "Hello world")),
- Left(14000026L, (1, 7L, "Hello world")),
- Left(14000025L, (1, 8L, "Hello world")),
- Left(14000022L, (1, 9L, "Hello world")),
- Right(14000030L))
-
- val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,2,Hello,2,1,2,2,2",
- "1,3,Hello world,5,2,2,3,2",
- "1,1,Hi,6,3,2,3,1",
- "2,1,Hello,1,1,1,1,1",
- "2,2,Hello world,3,2,1,2,1",
- "3,1,Hello,1,1,1,1,1",
- "3,2,Hello world,3,2,1,2,1",
- "1,5,Hello world,11,4,2,5,1",
- "1,6,Hello world,17,5,3,6,1",
- "1,9,Hello world,26,6,4,9,1",
- "1,8,Hello world,34,7,4,9,1",
- "1,7,Hello world,41,8,5,9,1",
- "2,5,Hello world,8,3,2,5,1",
- "3,5,Hello world,8,3,2,5,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedNonPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- StreamITCase.clear
-
- val sqlQuery = "SELECT a, b, c, " +
- " SUM(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " COUNT(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " AVG(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MAX(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MIN(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (1, 1L, "Hello")),
- Left(14000002L, (1, 2L, "Hello")),
- Left(14000002L, (1, 3L, "Hello world")),
- Left(14000003L, (2, 2L, "Hello world")),
- Left(14000003L, (2, 3L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 4L, "Hello world")),
- Left(14000022L, (1, 5L, "Hello world")),
- Left(14000022L, (1, 6L, "Hello world")),
- Left(14000022L, (1, 7L, "Hello world")),
- Left(14000023L, (2, 4L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000030L))
-
- val t1 = env
- .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "2,1,Hello,1,1,1,1,1",
- "1,1,Hello,7,4,1,3,1",
- "1,2,Hello,7,4,1,3,1",
- "1,3,Hello world,7,4,1,3,1",
- "2,2,Hello world,12,6,2,3,1",
- "2,3,Hello world,12,6,2,3,1",
- "1,1,Hi,13,7,1,3,1",
- "1,4,Hello world,17,8,2,4,1",
- "1,5,Hello world,35,11,3,7,1",
- "1,6,Hello world,35,11,3,7,1",
- "1,7,Hello world,35,11,3,7,1",
- "2,4,Hello world,44,13,3,7,1",
- "2,5,Hello world,44,13,3,7,1")
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedNonPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.clear
- env.setParallelism(1)
-
- val sqlQuery = "SELECT a, b, c, " +
- " SUM(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " COUNT(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " AVG(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MAX(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MIN(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 2L, "Hello")),
- Left(14000002L, (3, 5L, "Hello")),
- Left(14000003L, (1, 3L, "Hello")),
- Left(14000004L, (3, 7L, "Hello world")),
- Left(14000007L, (4, 9L, "Hello world")),
- Left(14000008L, (5, 8L, "Hello world")),
- Right(14000010L),
- // this element will be discard because it is late
- Left(14000008L, (6, 8L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (6, 8L, "Hello world")),
- Right(14000030L)
- )
-
- val t1 = env
- .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "2,2,Hello,2,1,2,2,2",
- "3,5,Hello,7,2,3,5,2",
- "1,3,Hello,10,3,3,5,2",
- "3,7,Hello world,17,4,4,7,2",
- "1,1,Hi,18,5,3,7,1",
- "4,9,Hello world,27,6,4,9,1",
- "5,8,Hello world,35,7,5,9,1",
- "6,8,Hello world,43,8,5,9,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test sliding event-time unbounded window with partition by **/
- @Test
- def testRowTimeUnBoundedPartitionedRowsOver2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.clear
- env.setParallelism(1)
-
- val sqlQuery = "SELECT a, b, c, " +
- "SUM(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "count(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "avg(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "max(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "min(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row) " +
- "from T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (3, 1L, "Hello")),
- Left(14000003L, (1, 2L, "Hello")),
- Left(14000004L, (1, 3L, "Hello world")),
- Left(14000007L, (3, 2L, "Hello world")),
- Left(14000008L, (2, 2L, "Hello world")),
- Right(14000010L),
- // the next 3 elements are late
- Left(14000008L, (1, 4L, "Hello world")),
- Left(14000008L, (2, 3L, "Hello world")),
- Left(14000008L, (3, 3L, "Hello world")),
- Left(14000012L, (1, 5L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 6L, "Hello world")),
- // the next 3 elements are late
- Left(14000019L, (1, 6L, "Hello world")),
- Left(14000018L, (2, 4L, "Hello world")),
- Left(14000018L, (3, 4L, "Hello world")),
- Left(14000022L, (2, 5L, "Hello world")),
- Left(14000022L, (3, 5L, "Hello world")),
- Left(14000024L, (1, 7L, "Hello world")),
- Left(14000023L, (1, 8L, "Hello world")),
- Left(14000021L, (1, 9L, "Hello world")),
- Right(14000030L)
- )
-
- val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,2,Hello,2,1,2,2,2",
- "1,3,Hello world,5,2,2,3,2",
- "1,1,Hi,6,3,2,3,1",
- "2,1,Hello,1,1,1,1,1",
- "2,2,Hello world,3,2,1,2,1",
- "3,1,Hello,1,1,1,1,1",
- "3,2,Hello world,3,2,1,2,1",
- "1,5,Hello world,11,4,2,5,1",
- "1,6,Hello world,17,5,3,6,1",
- "1,9,Hello world,26,6,4,9,1",
- "1,8,Hello world,34,7,4,9,1",
- "1,7,Hello world,41,8,5,9,1",
- "2,5,Hello world,8,3,2,5,1",
- "3,5,Hello world,8,3,2,5,1"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala
deleted file mode 100644
index ec719d2..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/SqlITCase.scala
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.sql
-
-import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.runtime.datastream.{StreamITCase, StreamingWithStateTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit._
-
-class SqlITCase extends StreamingWithStateTestBase {
-
- /** test row stream registered table **/
- @Test
- def testRowRegister(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM MyTableRow WHERE c < 3"
-
- val data = List(
- Row.of("Hello", "Worlds", Int.box(1)),
- Row.of("Hello", "Hiden", Int.box(5)),
- Row.of("Hello again", "Worlds", Int.box(2)))
-
- implicit val tpe: TypeInformation[Row] = new RowTypeInfo(
- BasicTypeInfo.STRING_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO,
- BasicTypeInfo.INT_TYPE_INFO) // tpe is automatically
-
- val ds = env.fromCollection(data)
-
- val t = ds.toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTableRow", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("Hello,Worlds,1","Hello again,Worlds,2")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test unbounded groupBy (without window) **/
- @Test
- def testUnboundedGroupBy(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT b, COUNT(a) FROM MyTable GROUP BY b"
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toRetractStream[Row]
- result.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = List("1,1", "2,2", "3,3", "4,4", "5,5", "6,6")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- /** test selection **/
- @Test
- def testSelectExpressionFromTable(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT a * 2, b - 1 FROM MyTable"
-
- val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("2,0", "4,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test filtering with registered table **/
- @Test
- def testSimpleFilter(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM MyTable WHERE a = 3"
-
- val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test filtering with registered datastream **/
- @Test
- def testDatastreamFilter(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM MyTable WHERE _1 = 3"
-
- val t = StreamTestData.getSmall3TupleDataStream(env)
- tEnv.registerDataStream("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test union with registered tables **/
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM T1 " +
- "UNION ALL " +
- "SELECT * FROM T2"
-
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T1", t1)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T2", t2)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,1,Hi", "1,1,Hi",
- "2,2,Hello", "2,2,Hello",
- "3,2,Hello world", "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test union with filter **/
- @Test
- def testUnionWithFilter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM T1 WHERE a = 3 " +
- "UNION ALL " +
- "SELECT * FROM T2 WHERE a = 2"
-
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T1", t1)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T2", t2)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test union of a table and a datastream **/
- @Test
- def testUnionTableWithDataSet(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT c FROM T1 WHERE a = 3 " +
- "UNION ALL " +
- "SELECT c FROM T2 WHERE a = 2"
-
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T1", t1)
- val t2 = StreamTestData.get3TupleDataStream(env)
- tEnv.registerDataStream("T2", t2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("Hello", "Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnnestPrimitiveArrayFromTable(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val data = List(
- (1, Array(12, 45), Array(Array(12, 45))),
- (2, Array(41, 5), Array(Array(18), Array(87))),
- (3, Array(18, 42), Array(Array(1), Array(45)))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, b, s FROM T, UNNEST(T.b) AS A (s)"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,[12, 45],12",
- "1,[12, 45],45",
- "2,[41, 5],41",
- "2,[41, 5],5",
- "3,[18, 42],18",
- "3,[18, 42],42"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnnestArrayOfArrayFromTable(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val data = List(
- (1, Array(12, 45), Array(Array(12, 45))),
- (2, Array(41, 5), Array(Array(18), Array(87))),
- (3, Array(18, 42), Array(Array(1), Array(45)))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) AS A (s)"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,[12, 45]",
- "2,[18]",
- "2,[87]",
- "3,[1]",
- "3,[45]")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnnestObjectArrayFromTableWithFilter(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val data = List(
- (1, Array((12, "45.6"), (12, "45.612"))),
- (2, Array((13, "41.6"), (14, "45.2136"))),
- (3, Array((18, "42.6")))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataStream("T", stream, 'a, 'b)
-
- val sqlQuery = "SELECT a, b, s, t FROM T, UNNEST(T.b) AS A (s, t) WHERE s > 13"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "2,[(13,41.6), (14,45.2136)],14,45.2136",
- "3,[(18,42.6)],18,42.6")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala
deleted file mode 100644
index 31e7c5a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/datastream/sql/TableSourceITCase.scala
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.datastream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.runtime.datastream.StreamITCase
-import org.apache.flink.table.utils.CommonTestData
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class TableSourceITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testCsvTableSource(): Unit = {
-
- val csvTable = CommonTestData.getCsvTableSource
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- tEnv.registerTableSource("persons", csvTable)
-
- tEnv.sql(
- "SELECT id, `first`, `last`, score FROM persons WHERE id < 4 ")
- .toAppendStream[Row]
- .addSink(new StreamITCase.StringSink[Row])
-
- env.execute()
-
- val expected = mutable.MutableList(
- "1,Mike,Smith,12.3",
- "2,Bob,Taylor,45.6",
- "3,Sam,Miller,7.89")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-}
[42/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableEnvironmentTest.scala
new file mode 100644
index 0000000..ad84a03
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableEnvironmentTest.scala
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo._
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.{GenericTypeInfo, RowTypeInfo, TupleTypeInfo, TypeExtractor}
+import org.apache.flink.api.scala._
+import org.apache.flink.table.expressions.{Alias, UnresolvedFieldReference}
+import org.apache.flink.table.runtime.types.CRowTypeInfo
+import org.apache.flink.table.utils.{MockTableEnvironment, TableTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class TableEnvironmentTest extends TableTestBase {
+
+ val tEnv = new MockTableEnvironment
+
+ val tupleType = new TupleTypeInfo(
+ INT_TYPE_INFO,
+ STRING_TYPE_INFO,
+ DOUBLE_TYPE_INFO)
+
+ val rowType = new RowTypeInfo(INT_TYPE_INFO, STRING_TYPE_INFO,DOUBLE_TYPE_INFO)
+
+ val cRowType = new CRowTypeInfo(rowType)
+
+ val caseClassType: TypeInformation[CClass] = implicitly[TypeInformation[CClass]]
+
+ val pojoType: TypeInformation[PojoClass] = TypeExtractor.createTypeInfo(classOf[PojoClass])
+
+ val atomicType = INT_TYPE_INFO
+
+ val genericRowType = new GenericTypeInfo[Row](classOf[Row])
+
+ @Test
+ def testGetFieldInfoRow(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(rowType)
+
+ fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoRowNames(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ rowType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTuple(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(tupleType)
+
+ fieldInfo._1.zip(Array("f0", "f1", "f2")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClass(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(caseClassType)
+
+ fieldInfo._1.zip(Array("cf1", "cf2", "cf3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojo(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(pojoType)
+
+ fieldInfo._1.zip(Array("pf1", "pf2", "pf3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoAtomic(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(atomicType)
+
+ fieldInfo._1.zip(Array("f0")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTupleNames(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClassNames(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ UnresolvedFieldReference("name1"),
+ UnresolvedFieldReference("name2"),
+ UnresolvedFieldReference("name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojoNames2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ UnresolvedFieldReference("pf3"),
+ UnresolvedFieldReference("pf1"),
+ UnresolvedFieldReference("pf2")
+ ))
+
+ fieldInfo._1.zip(Array("pf3", "pf1", "pf2")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoAtomicName1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ atomicType,
+ Array(UnresolvedFieldReference("name")))
+
+ fieldInfo._1.zip(Array("name")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTupleAlias1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ Alias(UnresolvedFieldReference("f0"), "name1"),
+ Alias(UnresolvedFieldReference("f1"), "name2"),
+ Alias(UnresolvedFieldReference("f2"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoTupleAlias2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ tupleType,
+ Array(
+ Alias(UnresolvedFieldReference("f2"), "name1"),
+ Alias(UnresolvedFieldReference("f0"), "name2"),
+ Alias(UnresolvedFieldReference("f1"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClassAlias1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ Alias(UnresolvedFieldReference("cf1"), "name1"),
+ Alias(UnresolvedFieldReference("cf2"), "name2"),
+ Alias(UnresolvedFieldReference("cf3"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoCClassAlias2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ caseClassType,
+ Array(
+ Alias(UnresolvedFieldReference("cf3"), "name1"),
+ Alias(UnresolvedFieldReference("cf1"), "name2"),
+ Alias(UnresolvedFieldReference("cf2"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojoAlias1(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ Alias(UnresolvedFieldReference("pf1"), "name1"),
+ Alias(UnresolvedFieldReference("pf2"), "name2"),
+ Alias(UnresolvedFieldReference("pf3"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(0, 1, 2)).foreach(x => assertEquals(x._2, x._1))
+ }
+
+ @Test
+ def testGetFieldInfoPojoAlias2(): Unit = {
+ val fieldInfo = tEnv.getFieldInfo(
+ pojoType,
+ Array(
+ Alias(UnresolvedFieldReference("pf3"), "name1"),
+ Alias(UnresolvedFieldReference("pf1"), "name2"),
+ Alias(UnresolvedFieldReference("pf2"), "name3")
+ ))
+
+ fieldInfo._1.zip(Array("name1", "name2", "name3")).foreach(x => assertEquals(x._2, x._1))
+ fieldInfo._2.zip(Array(2, 0, 1)).foreach(x => assertEquals(x._2, x._1))
+ }
+}
+
+case class CClass(cf1: Int, cf2: String, cf3: Double)
+
+class PojoClass(var pf1: Int, var pf2: String, var pf3: Double) {
+ def this() = this(0, "", 0.0)
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSchemaTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSchemaTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSchemaTest.scala
new file mode 100644
index 0000000..c8aca9d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSchemaTest.scala
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Assert.{assertEquals, assertTrue}
+import org.junit.Test
+
+class TableSchemaTest extends TableTestBase {
+
+ @Test
+ def testBatchTableSchema(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
+ val schema = table.getSchema
+
+ assertEquals("a", schema.getColumnNames.apply(0))
+ assertEquals("b", schema.getColumnNames.apply(1))
+
+ assertEquals(Types.INT, schema.getTypes.apply(0))
+ assertEquals(Types.STRING, schema.getTypes.apply(1))
+
+ val expectedString = "root\n" +
+ " |-- a: Integer\n" +
+ " |-- b: String\n"
+ assertEquals(expectedString, schema.toString)
+
+ assertTrue(schema.getColumnName(3).isEmpty)
+ assertTrue(schema.getType(-1).isEmpty)
+ assertTrue(schema.getType("c").isEmpty)
+ }
+
+ @Test
+ def testStreamTableSchema(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, String)]("MyTable", 'a, 'b)
+ val schema = table.getSchema
+
+ assertEquals("a", schema.getColumnNames.apply(0))
+ assertEquals("b", schema.getColumnNames.apply(1))
+
+ assertEquals(Types.INT, schema.getTypes.apply(0))
+ assertEquals(Types.STRING, schema.getTypes.apply(1))
+
+ val expectedString = "root\n" +
+ " |-- a: Integer\n" +
+ " |-- b: String\n"
+ assertEquals(expectedString, schema.toString)
+
+ assertTrue(schema.getColumnName(3).isEmpty)
+ assertTrue(schema.getType(-1).isEmpty)
+ assertTrue(schema.getType("c").isEmpty)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala
new file mode 100644
index 0000000..59d2a47
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api
+
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils._
+import org.apache.flink.table.runtime.utils.CommonTestData
+import org.apache.flink.table.sources.{CsvTableSource, TableSource}
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{TableTestBase, TestFilterableTableSource}
+import org.junit.{Assert, Test}
+
+class TableSourceTest extends TableTestBase {
+
+ private val projectedFields: Array[String] = Array("last", "id", "score")
+ private val noCalcFields: Array[String] = Array("id", "score", "first")
+
+ @Test
+ def testTableSourceScanToString(): Unit = {
+ val (tableSource1, _) = filterableTableSource
+ val (tableSource2, _) = filterableTableSource
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource("table1", tableSource1)
+ tableEnv.registerTableSource("table2", tableSource2)
+
+ val table1 = tableEnv.scan("table1").where("amount > 2")
+ val table2 = tableEnv.scan("table2").where("amount > 2")
+ val result = table1.unionAll(table2)
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ batchFilterableSourceTableNode(
+ "table1",
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ batchFilterableSourceTableNode(
+ "table2",
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("union", "name, id, amount, price")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ // batch plan
+
+ @Test
+ def testBatchProjectableSourceScanPlanTableApi(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('last.upperCase(), 'id.floor(), 'score * 2)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchSourceTableNode(tableName, projectedFields),
+ term("select", "UPPER(last) AS _c0", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchProjectableSourceScanPlanSQL(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = batchTestUtil()
+
+ util.tableEnv.registerTableSource(tableName, tableSource)
+
+ val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testBatchProjectableSourceScanNoIdentityCalc(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('id, 'score, 'first)
+
+ val expected = batchSourceTableNode(tableName, noCalcFields)
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableWithoutPushDown(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("price * 2 < 32")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price")),
+ term("select", "price", "id", "amount"),
+ term("where", "<(*(price, 2), 32)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterablePartialPushDown(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .where("amount > 2 && price * 2 < 32")
+ .select('price, 'name.lowerCase(), 'amount)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "LOWER(name) AS _c1", "amount"),
+ term("where", "<(*(price, 2), 32)")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableFullyPushedDown(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && amount < 32")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2 && 'amount < 32"),
+ term("select", "price", "id", "amount")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableWithUnconvertedExpression(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && (amount < 32 || amount.cast(LONG) > 10)") // cast can not be converted
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "id", "amount"),
+ term("where", "OR(<(amount, 32), >(CAST(amount), 10))")
+ )
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchFilterableWithUDF(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+ val func = Func0
+ tableEnv.registerFunction("func0", func)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && func0(amount) < 32")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "id", "amount"),
+ term("where", s"<(${func.functionIdentifier}(amount), 32)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ // stream plan
+
+ @Test
+ def testStreamProjectableSourceScanPlanTableApi(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('last, 'id.floor(), 'score * 2)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testStreamProjectableSourceScanPlanSQL(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+
+ util.tableEnv.registerTableSource(tableName, tableSource)
+
+ val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamSourceTableNode(tableName, projectedFields),
+ term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testStreamProjectableSourceScanNoIdentityCalc(): Unit = {
+ val (tableSource, tableName) = csvTable
+ val util = streamTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('id, 'score, 'first)
+
+ val expected = streamSourceTableNode(tableName, noCalcFields)
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testStreamFilterableSourceScanPlanTableApi(): Unit = {
+ val (tableSource, tableName) = filterableTableSource
+ val util = streamTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerTableSource(tableName, tableSource)
+
+ val result = tableEnv
+ .scan(tableName)
+ .select('price, 'id, 'amount)
+ .where("amount > 2 && price * 2 < 32")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamFilterableSourceTableNode(
+ tableName,
+ Array("name", "id", "amount", "price"),
+ "'amount > 2"),
+ term("select", "price", "id", "amount"),
+ term("where", "<(*(price, 2), 32)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ // csv builder
+
+ @Test
+ def testCsvTableSourceBuilder(): Unit = {
+ val source1 = CsvTableSource.builder()
+ .path("/path/to/csv")
+ .field("myfield", Types.STRING)
+ .field("myfield2", Types.INT)
+ .quoteCharacter(';')
+ .fieldDelimiter("#")
+ .lineDelimiter("\r\n")
+ .commentPrefix("%%")
+ .ignoreFirstLine()
+ .ignoreParseErrors()
+ .build()
+
+ val source2 = new CsvTableSource(
+ "/path/to/csv",
+ Array("myfield", "myfield2"),
+ Array(Types.STRING, Types.INT),
+ "#",
+ "\r\n",
+ ';',
+ true,
+ "%%",
+ true)
+
+ Assert.assertEquals(source1, source2)
+ }
+
+ // utils
+
+ def filterableTableSource:(TableSource[_], String) = {
+ val tableSource = new TestFilterableTableSource
+ (tableSource, "filterableTable")
+ }
+
+ def csvTable: (CsvTableSource, String) = {
+ val csvTable = CommonTestData.getCsvTableSource
+ val tableName = "csvTable"
+ (csvTable, tableName)
+ }
+
+ def batchSourceTableNode(sourceName: String, fields: Array[String]): String = {
+ s"BatchTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
+ }
+
+ def streamSourceTableNode(sourceName: String, fields: Array[String] ): String = {
+ s"StreamTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
+ }
+
+ def batchFilterableSourceTableNode(
+ sourceName: String,
+ fields: Array[String],
+ exp: String): String = {
+ "BatchTableSourceScan(" +
+ s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+ }
+
+ def streamFilterableSourceTableNode(
+ sourceName: String,
+ fields: Array[String],
+ exp: String): String = {
+ "StreamTableSourceScan(" +
+ s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala
new file mode 100644
index 0000000..c9a7049
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class BatchTableEnvironmentTest extends TableTestBase {
+
+ @Test
+ def testSqlWithoutRegistering(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
+
+ val sqlTable = util.tableEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a, b, c"),
+ term("where", ">(b, 12)"))
+
+ util.verifyTable(sqlTable, expected)
+
+ val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
+
+ val sqlTable2 = util.tableEnv.sql(s"SELECT d, e, f FROM $table, $table2 WHERE c = d")
+
+ val join = unaryNode(
+ "DataSetJoin",
+ binaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ batchTableNode(1),
+ term("select", "c")),
+ term("where", "=(c, d)"),
+ term("join", "c, d, e, f"),
+ term("joinType", "InnerJoin"))
+
+ val expected2 = unaryNode(
+ "DataSetCalc",
+ join,
+ term("select", "d, e, f"))
+
+ util.verifyTable(sqlTable2, expected2)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala
new file mode 100644
index 0000000..e953ed3
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.test.util.MultipleProgramsTestBase
+import org.junit.Assert.assertEquals
+import org.junit._
+
+class ExplainTest
+ extends MultipleProgramsTestBase(MultipleProgramsTestBase.TestExecutionMode.CLUSTER) {
+
+ private val testFilePath = ExplainTest.this.getClass.getResource("/").getFile
+
+ @Test
+ def testFilterWithoutExtended(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements((1, "hello"))
+ .toTable(tEnv, 'a, 'b)
+ .filter("a % 2 = 0")
+
+ val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testFilter0.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testFilterWithExtended(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements((1, "hello"))
+ .toTable(tEnv, 'a, 'b)
+ .filter("a % 2 = 0")
+
+ val result = tEnv.explain(table, extended = true).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testFilter1.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testJoinWithoutExtended(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
+ val table = table1.join(table2).where("b = d").select("a, c")
+
+ val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testJoin0.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testJoinWithExtended(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
+ val table = table1.join(table2).where("b = d").select("a, c")
+
+ val result = tEnv.explain(table, extended = true).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testJoin1.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testUnionWithoutExtended(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table = table1.unionAll(table2)
+
+ val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testUnion0.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testUnionWithExtended(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table = table1.unionAll(table2)
+
+ val result = tEnv.explain(table, extended = true).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testUnion1.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala
new file mode 100644
index 0000000..7ae7db6
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala
@@ -0,0 +1,341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+/**
+ * Test for testing aggregate plans.
+ */
+class AggregateTest extends TableTestBase {
+
+ @Test
+ def testAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable"
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ batchTableNode(0),
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testAggregateWithFilter(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1"
+
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", "=(a, 1)")
+ )
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ calcNode,
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testGroupAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable GROUP BY a"
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "a"),
+ term("select",
+ "a",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ val expected = unaryNode(
+ "DataSetCalc",
+ aggregate,
+ term("select",
+ "EXPR$0",
+ "EXPR$1",
+ "EXPR$2")
+ )
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testGroupAggregateWithFilter(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1 GROUP BY a"
+
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select","a", "b", "c") ,
+ term("where","=(a, 1)")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetAggregate",
+ calcNode,
+ term("groupBy", "a"),
+ term("select",
+ "a",
+ "AVG(a) AS EXPR$0",
+ "SUM(b) AS EXPR$1",
+ "COUNT(c) AS EXPR$2")
+ )
+ val expected = unaryNode(
+ "DataSetCalc",
+ aggregate,
+ term("select",
+ "EXPR$0",
+ "EXPR$1",
+ "EXPR$2")
+ )
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testGroupingSets(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g FROM MyTable " +
+ "GROUP BY GROUPING SETS (b, c)"
+
+ val aggregate = unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b"),
+ term("select", "b", "AVG(a) AS c")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "c"),
+ term("select", "c AS b", "AVG(a) AS c")
+ ),
+ term("union", "b", "c", "i$b", "i$c", "a")
+ ),
+ term("select",
+ "CASE(i$b, null, b) AS b",
+ "CASE(i$c, null, c) AS c",
+ "a",
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g") // GROUP_ID()
+ )
+
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testCube(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
+ "GROUPING(b) as gb, GROUPING(c) as gc, " +
+ "GROUPING_ID(b) as gib, GROUPING_ID(c) as gic, " +
+ "GROUPING_ID(b, c) as gid " +
+ "FROM MyTable " +
+ "GROUP BY CUBE (b, c)"
+
+ val group1 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b, c"),
+ term("select", "b", "c",
+ "AVG(a) AS i$b")
+ )
+
+ val group2 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b"),
+ term("select", "b",
+ "AVG(a) AS c")
+ )
+
+ val group3 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "c"),
+ term("select", "c AS b",
+ "AVG(a) AS c")
+ )
+
+ val group4 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("select",
+ "AVG(a) AS b")
+ )
+
+ val union1 = binaryNode(
+ "DataSetUnion",
+ group1, group2,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val union2 = binaryNode(
+ "DataSetUnion",
+ union1, group3,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val union3 = binaryNode(
+ "DataSetUnion",
+ union2, group4,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetCalc",
+ union3,
+ term("select",
+ "CASE(i$b, null, b) AS b",
+ "CASE(i$c, null, c) AS c",
+ "a",
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g", // GROUP_ID()
+ "CASE(i$b, 1, 0) AS gb", // GROUPING(b)
+ "CASE(i$c, 1, 0) AS gc", // GROUPING(c)
+ "CASE(i$b, 1, 0) AS gib", // GROUPING_ID(b)
+ "CASE(i$c, 1, 0) AS gic", // GROUPING_ID(c)
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS gid") // GROUPING_ID(b, c)
+ )
+
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testRollup(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
+ "GROUPING(b) as gb, GROUPING(c) as gc, " +
+ "GROUPING_ID(b) as gib, GROUPING_ID(c) as gic, " +
+ "GROUPING_ID(b, c) as gid " + " FROM MyTable " +
+ "GROUP BY ROLLUP (b, c)"
+
+ val group1 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b, c"),
+ term("select", "b", "c",
+ "AVG(a) AS i$b")
+ )
+
+ val group2 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b"),
+ term("select", "b",
+ "AVG(a) AS c")
+ )
+
+ val group3 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("select",
+ "AVG(a) AS b")
+ )
+
+ val union1 = binaryNode(
+ "DataSetUnion",
+ group1, group2,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val union2 = binaryNode(
+ "DataSetUnion",
+ union1, group3,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetCalc",
+ union2,
+ term("select",
+ "CASE(i$b, null, b) AS b",
+ "CASE(i$c, null, c) AS c",
+ "a",
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g", // GROUP_ID()
+ "CASE(i$b, 1, 0) AS gb", // GROUPING(b)
+ "CASE(i$c, 1, 0) AS gc", // GROUPING(c)
+ "CASE(i$b, 1, 0) AS gib", // GROUPING_ID(b)
+ "CASE(i$c, 1, 0) AS gic", // GROUPING_ID(c)
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS gid") // GROUPING_ID(b, c)
+ )
+
+ util.verifySql(sqlQuery, aggregate)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala
new file mode 100644
index 0000000..6271fac
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class CalcTest extends TableTestBase {
+
+ @Test
+ def testMultipleFlattening(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "a._1 AS _1",
+ "a._2 AS _2",
+ "c",
+ "b._1 AS _10",
+ "b._2 AS _20"
+ )
+ )
+
+ util.verifySql(
+ "SELECT MyTable.a.*, c, MyTable.b.* FROM MyTable",
+ expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala
new file mode 100644
index 0000000..5b9aa8c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{HierarchyTableFunction, PojoTableFunc, TableFunc2, _}
+import org.junit.Test
+
+class CorrelateTest extends TableTestBase {
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val util = batchTestUtil()
+ val func1 = new TableFunc1
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func1", func1)
+
+ val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c)) AS T(s)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "func1($cor0.c)"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery, expected)
+
+ // test overloading
+
+ val sqlQuery2 = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c, '$')) AS T(s)"
+
+ val expected2 = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "func1($cor0.c, '$')"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery2, expected2)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val util = batchTestUtil()
+ val func1 = new TableFunc1
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func1", func1)
+
+ val sqlQuery = "SELECT c, s FROM MyTable LEFT JOIN LATERAL TABLE(func1(c)) AS T(s) ON TRUE"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "func1($cor0.c)"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "LEFT")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testCustomType(): Unit = {
+ val util = batchTestUtil()
+ val func2 = new TableFunc2
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func2", func2)
+
+ val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "func2($cor0.c)"),
+ term("function", func2.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
+ "VARCHAR(2147483647) f0, INTEGER f1)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS name", "f1 AS len")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testHierarchyType(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = new HierarchyTableFunction
+ util.addFunction("hierarchy", function)
+
+ val sqlQuery = "SELECT c, T.* FROM MyTable, LATERAL TABLE(hierarchy(c)) AS T(name, adult, len)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "hierarchy($cor0.c)"),
+ term("function", function.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
+ " VARCHAR(2147483647) f0, BOOLEAN f1, INTEGER f2)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS name", "f1 AS adult", "f2 AS len")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testPojoType(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = new PojoTableFunc
+ util.addFunction("pojo", function)
+
+ val sqlQuery = "SELECT c, name, age FROM MyTable, LATERAL TABLE(pojo(c))"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "pojo($cor0.c)"),
+ term("function", function.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
+ " INTEGER age, VARCHAR(2147483647) name)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "name", "age")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testFilter(): Unit = {
+ val util = batchTestUtil()
+ val func2 = new TableFunc2
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func2", func2)
+
+ val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len) " +
+ "WHERE len > 2"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "func2($cor0.c)"),
+ term("function", func2.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
+ "VARCHAR(2147483647) f0, INTEGER f1)"),
+ term("joinType", "INNER"),
+ term("condition", ">($1, 2)")
+ ),
+ term("select", "c", "f0 AS name", "f1 AS len")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+
+ @Test
+ def testScalarFunction(): Unit = {
+ val util = batchTestUtil()
+ val func1 = new TableFunc1
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func1", func1)
+
+ val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(SUBSTRING(c, 2))) AS T(s)"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetCorrelate",
+ batchTableNode(0),
+ term("invocation", "func1(SUBSTRING($cor0.c, 2))"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala
new file mode 100644
index 0000000..7ea2d8b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala
@@ -0,0 +1,466 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class DistinctAggregateTest extends TableTestBase {
+
+ @Test
+ def testSingleDistinctAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT COUNT(DISTINCT a) FROM MyTable"
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a")
+ ),
+ term("distinct", "a")
+ ),
+ tuples(List(null)),
+ term("values", "a")
+ ),
+ term("union", "a")
+ ),
+ term("select", "COUNT(a) AS EXPR$0")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testMultiDistinctAggregateOnSameColumn(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT a), MAX(DISTINCT a) FROM MyTable"
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a")
+ ),
+ term("distinct", "a")
+ ),
+ tuples(List(null)),
+ term("values", "a")
+ ),
+ term("union", "a")
+ ),
+ term("select", "COUNT(a) AS EXPR$0", "SUM(a) AS EXPR$1", "MAX(a) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testSingleDistinctAggregateAndOneOrMultiNonDistinctAggregate(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ // case 0x00: DISTINCT on COUNT and Non-DISTINCT on others
+ val sqlQuery0 = "SELECT COUNT(DISTINCT a), SUM(b) FROM MyTable"
+
+ val expected0 = unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("groupBy", "a"),
+ term("select", "a", "SUM(b) AS EXPR$1")
+ ),
+ tuples(List(null, null)),
+ term("values", "a", "EXPR$1")
+ ),
+ term("union", "a", "EXPR$1")
+ ),
+ term("select", "COUNT(a) AS EXPR$0", "SUM(EXPR$1) AS EXPR$1")
+ )
+
+ util.verifySql(sqlQuery0, expected0)
+
+ // case 0x01: Non-DISTINCT on COUNT and DISTINCT on others
+ val sqlQuery1 = "SELECT COUNT(a), SUM(DISTINCT b) FROM MyTable"
+
+ val expected1 = unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("groupBy", "b"),
+ term("select", "b", "COUNT(a) AS EXPR$0")
+ ),
+ tuples(List(null, null)),
+ term("values", "b", "EXPR$0")
+ ),
+ term("union", "b", "EXPR$0")
+ ),
+ term("select", "$SUM0(EXPR$0) AS EXPR$0", "SUM(b) AS EXPR$1")
+ )
+
+ util.verifySql(sqlQuery1, expected1)
+ }
+
+ @Test
+ def testMultiDistinctAggregateOnDifferentColumn(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT b) FROM MyTable"
+
+ val expected = binaryNode(
+ "DataSetSingleRowJoin",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a")
+ ),
+ term("distinct", "a")
+ ),
+ tuples(List(null)),
+ term("values", "a")
+ ),
+ term("union", "a")
+ ),
+ term("select", "COUNT(a) AS EXPR$0")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "b")
+ ),
+ term("distinct", "b")
+ ),
+ tuples(List(null)),
+ term("values", "b")
+ ),
+ term("union", "b")
+ ),
+ term("select", "SUM(b) AS EXPR$1")
+ ),
+ term("where", "true"),
+ term("join", "EXPR$0", "EXPR$1"),
+ term("joinType", "NestedLoopInnerJoin")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testMultiDistinctAndNonDistinctAggregateOnDifferentColumn(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT b), COUNT(c) FROM MyTable"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetSingleRowJoin",
+ binaryNode(
+ "DataSetSingleRowJoin",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ batchTableNode(0),
+ tuples(List(null, null, null)),
+ term("values", "a, b, c")
+ ),
+ term("union", "a, b, c")
+ ),
+ term("select", "COUNT(c) AS EXPR$2")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a")
+ ),
+ term("distinct", "a")
+ ),
+ tuples(List(null)),
+ term("values", "a")
+ ),
+ term("union", "a")
+ ),
+ term("select", "COUNT(a) AS EXPR$0")
+ ),
+ term("where", "true"),
+ term("join", "EXPR$2, EXPR$0"),
+ term("joinType", "NestedLoopInnerJoin")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetValues",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "b")
+ ),
+ term("distinct", "b")
+ ),
+ tuples(List(null)),
+ term("values", "b")
+ ),
+ term("union", "b")
+ ),
+ term("select", "SUM(b) AS EXPR$1")
+ ),
+ term("where", "true"),
+ term("join", "EXPR$2", "EXPR$0, EXPR$1"),
+ term("joinType", "NestedLoopInnerJoin")
+ ),
+ term("select", "EXPR$0, EXPR$1, EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testSingleDistinctAggregateWithGrouping(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, COUNT(a), SUM(DISTINCT b) FROM MyTable GROUP BY a"
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("groupBy", "a", "b"),
+ term("select", "a", "b", "COUNT(a) AS EXPR$1")
+ ),
+ term("groupBy", "a"),
+ term("select", "a", "SUM(EXPR$1) AS EXPR$1", "SUM(b) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testSingleDistinctAggregateWithGroupingAndCountStar(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b) FROM MyTable GROUP BY a"
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("groupBy", "a", "b"),
+ term("select", "a", "b", "COUNT(*) AS EXPR$1")
+ ),
+ term("groupBy", "a"),
+ term("select", "a", "SUM(EXPR$1) AS EXPR$1", "SUM(b) AS EXPR$2")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testTwoDistinctAggregateWithGroupingAndCountStar(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b), COUNT(DISTINCT b) FROM MyTable GROUP BY a"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("groupBy", "a"),
+ term("select", "a", "COUNT(*) AS EXPR$1")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("distinct", "a, b")
+ ),
+ term("groupBy", "a"),
+ term("select", "a, SUM(b) AS EXPR$2, COUNT(b) AS EXPR$3")
+ ),
+ term("where", "IS NOT DISTINCT FROM(a, a0)"),
+ term("join", "a, EXPR$1, a0, EXPR$2, EXPR$3"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "a, EXPR$1, EXPR$2, EXPR$3")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testTwoDifferentDistinctAggregateWithGroupingAndCountStar(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b), COUNT(DISTINCT c) FROM MyTable GROUP BY a"
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "a"),
+ term("select", "a, COUNT(*) AS EXPR$1")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("distinct", "a, b")
+ ),
+ term("groupBy", "a"),
+ term("select", "a, SUM(b) AS EXPR$2")
+ ),
+ term("where", "IS NOT DISTINCT FROM(a, a0)"),
+ term("join", "a, EXPR$1, a0, EXPR$2"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "a, EXPR$1, EXPR$2")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetDistinct",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "c")
+ ),
+ term("distinct", "a, c")
+ ),
+ term("groupBy", "a"),
+ term("select", "a, COUNT(c) AS EXPR$3")
+ ),
+ term("where", "IS NOT DISTINCT FROM(a, a0)"),
+ term("join", "a, EXPR$1, EXPR$2, a0, EXPR$3"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "a, EXPR$1, EXPR$2, EXPR$3")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala
new file mode 100644
index 0000000..e77087c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import java.sql.Timestamp
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMerge
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.plan.logical._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupWindowTest extends TableTestBase {
+
+ @Test
+ def testNonPartitionedTumbleWindow(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB FROM T GROUP BY TUMBLE(ts, INTERVAL '2' HOUR)"
+
+ val expected =
+ unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "ts, a, b")
+ ),
+ term("window", TumblingGroupWindow('w$, 'ts, 7200000.millis)),
+ term("select", "SUM(a) AS sumA, COUNT(b) AS cntB")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testPartitionedTumbleWindow(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT " +
+ " TUMBLE_START(ts, INTERVAL '4' MINUTE), " +
+ " TUMBLE_END(ts, INTERVAL '4' MINUTE), " +
+ " c, " +
+ " SUM(a) AS sumA, " +
+ " MIN(b) AS minB " +
+ "FROM T " +
+ "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE), c"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "c"),
+ term("window", TumblingGroupWindow('w$, 'ts, 240000.millis)),
+ term("select", "c, SUM(a) AS sumA, MIN(b) AS minB, " +
+ "start('w$) AS w$start, end('w$) AS w$end")
+ ),
+ term("select", "CAST(w$start) AS w$start, CAST(w$end) AS w$end, c, sumA, minB")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testTumbleWindowWithUdAgg() = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val weightedAvg = new WeightedAvgWithMerge
+ util.tableEnv.registerFunction("weightedAvg", weightedAvg)
+
+ val sql = "SELECT weightedAvg(b, a) AS wAvg " +
+ "FROM T " +
+ "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE)"
+
+ val expected =
+ unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "ts, b, a")
+ ),
+ term("window", TumblingGroupWindow('w$, 'ts, 240000.millis)),
+ term("select", "weightedAvg(b, a) AS wAvg")
+ )
+
+ util.verifySql(sql, expected)
+ }
+
+ @Test
+ def testNonPartitionedHopWindow(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM T " +
+ "GROUP BY HOP(ts, INTERVAL '15' MINUTE, INTERVAL '90' MINUTE)"
+
+ val expected =
+ unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "ts, a, b")
+ ),
+ term("window",
+ SlidingGroupWindow('w$, 'ts, 5400000.millis, 900000.millis)),
+ term("select", "SUM(a) AS sumA, COUNT(b) AS cntB")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testPartitionedHopWindow(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Long, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
+
+ val sqlQuery =
+ "SELECT " +
+ " c, " +
+ " HOP_END(ts, INTERVAL '1' HOUR, INTERVAL '3' HOUR), " +
+ " HOP_START(ts, INTERVAL '1' HOUR, INTERVAL '3' HOUR), " +
+ " SUM(a) AS sumA, " +
+ " AVG(b) AS avgB " +
+ "FROM T " +
+ "GROUP BY HOP(ts, INTERVAL '1' HOUR, INTERVAL '3' HOUR), d, c"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "c, d"),
+ term("window",
+ SlidingGroupWindow('w$, 'ts, 10800000.millis, 3600000.millis)),
+ term("select", "c, d, SUM(a) AS sumA, AVG(b) AS avgB, " +
+ "start('w$) AS w$start, end('w$) AS w$end")
+ ),
+ term("select", "c, CAST(w$end) AS w$end, CAST(w$start) AS w$start, sumA, avgB")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testNonPartitionedSessionWindow(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT COUNT(*) AS cnt FROM T GROUP BY SESSION(ts, INTERVAL '30' MINUTE)"
+
+ val expected =
+ unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "ts")
+ ),
+ term("window", SessionGroupWindow('w$, 'ts, 1800000.millis)),
+ term("select", "COUNT(*) AS cnt")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testPartitionedSessionWindow(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Int, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
+
+ val sqlQuery =
+ "SELECT " +
+ " c, d, " +
+ " SESSION_START(ts, INTERVAL '12' HOUR), " +
+ " SESSION_END(ts, INTERVAL '12' HOUR), " +
+ " SUM(a) AS sumA, " +
+ " MIN(b) AS minB " +
+ "FROM T " +
+ "GROUP BY SESSION(ts, INTERVAL '12' HOUR), c, d"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetWindowAggregate",
+ batchTableNode(0),
+ term("groupBy", "c, d"),
+ term("window", SessionGroupWindow('w$, 'ts, 43200000.millis)),
+ term("select", "c, d, SUM(a) AS sumA, MIN(b) AS minB, " +
+ "start('w$) AS w$start, end('w$) AS w$end")
+ ),
+ term("select", "c, d, CAST(w$start) AS w$start, CAST(w$end) AS w$end, sumA, minB")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testWindowEndOnly(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+
+ val sqlQuery =
+ "SELECT " +
+ " TUMBLE_END(ts, INTERVAL '4' MINUTE)" +
+ "FROM T " +
+ "GROUP BY TUMBLE(ts, INTERVAL '4' MINUTE), c"
+
+ val expected =
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetWindowAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "ts, c")
+ ),
+ term("groupBy", "c"),
+ term("window", TumblingGroupWindow('w$, 'ts, 240000.millis)),
+ term("select", "c, start('w$) AS w$start, end('w$) AS w$end")
+ ),
+ term("select", "CAST(w$end) AS w$end")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala
new file mode 100644
index 0000000..af46c5b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class GroupingSetsTest extends TableTestBase {
+
+ @Test
+ def testGroupingSets(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g FROM MyTable " +
+ "GROUP BY GROUPING SETS (b, c)"
+
+ val aggregate = unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b"),
+ term("select", "b", "AVG(a) AS c")
+ ),
+ unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "c"),
+ term("select", "c AS b", "AVG(a) AS c")
+ ),
+ term("union", "b", "c", "i$b", "i$c", "a")
+ ),
+ term("select",
+ "CASE(i$b, null, b) AS b",
+ "CASE(i$c, null, c) AS c",
+ "a",
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g") // GROUP_ID()
+ )
+
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testCube(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
+ "GROUPING(b) as gb, GROUPING(c) as gc, " +
+ "GROUPING_ID(b) as gib, GROUPING_ID(c) as gic, " +
+ "GROUPING_ID(b, c) as gid " +
+ "FROM MyTable " +
+ "GROUP BY CUBE (b, c)"
+
+ val group1 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b, c"),
+ term("select", "b", "c",
+ "AVG(a) AS i$b")
+ )
+
+ val group2 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b"),
+ term("select", "b",
+ "AVG(a) AS c")
+ )
+
+ val group3 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "c"),
+ term("select", "c AS b",
+ "AVG(a) AS c")
+ )
+
+ val group4 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("select",
+ "AVG(a) AS b")
+ )
+
+ val union1 = binaryNode(
+ "DataSetUnion",
+ group1, group2,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val union2 = binaryNode(
+ "DataSetUnion",
+ union1, group3,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val union3 = binaryNode(
+ "DataSetUnion",
+ union2, group4,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetCalc",
+ union3,
+ term("select",
+ "CASE(i$b, null, b) AS b",
+ "CASE(i$c, null, c) AS c",
+ "a",
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g", // GROUP_ID()
+ "CASE(i$b, 1, 0) AS gb", // GROUPING(b)
+ "CASE(i$c, 1, 0) AS gc", // GROUPING(c)
+ "CASE(i$b, 1, 0) AS gib", // GROUPING_ID(b)
+ "CASE(i$c, 1, 0) AS gic", // GROUPING_ID(c)
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS gid") // GROUPING_ID(b, c)
+ )
+
+ util.verifySql(sqlQuery, aggregate)
+ }
+
+ @Test
+ def testRollup(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
+ "GROUPING(b) as gb, GROUPING(c) as gc, " +
+ "GROUPING_ID(b) as gib, GROUPING_ID(c) as gic, " +
+ "GROUPING_ID(b, c) as gid " + " FROM MyTable " +
+ "GROUP BY ROLLUP (b, c)"
+
+ val group1 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b, c"),
+ term("select", "b", "c",
+ "AVG(a) AS i$b")
+ )
+
+ val group2 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("groupBy", "b"),
+ term("select", "b",
+ "AVG(a) AS c")
+ )
+
+ val group3 = unaryNode(
+ "DataSetAggregate",
+ batchTableNode(0),
+ term("select",
+ "AVG(a) AS b")
+ )
+
+ val union1 = binaryNode(
+ "DataSetUnion",
+ group1, group2,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val union2 = binaryNode(
+ "DataSetUnion",
+ union1, group3,
+ term("union", "b", "c", "i$b", "i$c", "a")
+ )
+
+ val aggregate = unaryNode(
+ "DataSetCalc",
+ union2,
+ term("select",
+ "CASE(i$b, null, b) AS b",
+ "CASE(i$c, null, c) AS c",
+ "a",
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS g", // GROUP_ID()
+ "CASE(i$b, 1, 0) AS gb", // GROUPING(b)
+ "CASE(i$c, 1, 0) AS gc", // GROUPING(c)
+ "CASE(i$b, 1, 0) AS gib", // GROUPING_ID(b)
+ "CASE(i$c, 1, 0) AS gic", // GROUPING_ID(c)
+ "+(*(CASE(i$b, 1, 0), 2), CASE(i$c, 1, 0)) AS gid") // GROUPING_ID(b, c)
+ )
+
+ util.verifySql(sqlQuery, aggregate)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala
new file mode 100644
index 0000000..c47e940
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class SetOperatorsTest extends TableTestBase {
+
+ @Test
+ def testMinusWithNestedTypes(): Unit = {
+ val util = batchTestUtil()
+ val t = util.addTable[(Long, (Int, String), Array[Boolean])]("MyTable", 'a, 'b, 'c)
+
+ val expected = binaryNode(
+ "DataSetMinus",
+ batchTableNode(0),
+ batchTableNode(0),
+ term("minus", "a", "b", "c")
+ )
+
+ val result = t.minus(t)
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testExists(): Unit = {
+ val util = batchTestUtil()
+ util.addTable[(Long, Int, String)]("A", 'a_long, 'a_int, 'a_string)
+ util.addTable[(Long, Int, String)]("B", 'b_long, 'b_int, 'b_string)
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ binaryNode(
+ "DataSetJoin",
+ batchTableNode(0),
+ unaryNode(
+ "DataSetCalc",
+ unaryNode(
+ "DataSetAggregate",
+ unaryNode(
+ "DataSetCalc",
+ batchTableNode(1),
+ term("select", "b_long AS b_long3", "true AS $f0"),
+ term("where", "IS NOT NULL(b_long)")
+ ),
+ term("groupBy", "b_long3"),
+ term("select", "b_long3", "MIN($f0) AS $f1")
+ ),
+ term("select", "b_long3")
+ ),
+ term("where", "=(a_long, b_long3)"),
+ term("join", "a_long", "a_int", "a_string", "b_long3"),
+ term("joinType", "InnerJoin")
+ ),
+ term("select", "a_int", "a_string")
+ )
+
+ util.verifySql(
+ "SELECT a_int, a_string FROM A WHERE EXISTS(SELECT * FROM B WHERE a_long = b_long)",
+ expected
+ )
+ }
+}
[43/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/JavaTableSourceITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/JavaTableSourceITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/JavaTableSourceITCase.java
new file mode 100644
index 0000000..eb97afe
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/JavaTableSourceITCase.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch;
+
+import org.apache.flink.api.java.DataSet;
+import org.apache.flink.api.java.ExecutionEnvironment;
+import org.apache.flink.table.api.Table;
+import org.apache.flink.table.api.TableEnvironment;
+import org.apache.flink.table.api.java.BatchTableEnvironment;
+import org.apache.flink.table.runtime.utils.CommonTestData;
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase;
+import org.apache.flink.table.sources.BatchTableSource;
+import org.apache.flink.types.Row;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.List;
+
+/**
+ * Integration tests for {@link BatchTableSource}.
+ */
+@RunWith(Parameterized.class)
+public class JavaTableSourceITCase extends TableProgramsCollectionTestBase {
+
+ public JavaTableSourceITCase(TableConfigMode configMode) {
+ super(configMode);
+ }
+
+ @Test
+ public void testBatchTableSourceTableAPI() throws Exception {
+
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+ BatchTableSource csvTable = CommonTestData.getCsvTableSource();
+
+ tableEnv.registerTableSource("persons", csvTable);
+
+ Table result = tableEnv.scan("persons")
+ .select("id, first, last, score");
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+
+ String expected = "1,Mike,Smith,12.3\n" +
+ "2,Bob,Taylor,45.6\n" +
+ "3,Sam,Miller,7.89\n" +
+ "4,Peter,Smith,0.12\n" +
+ "5,Liz,Williams,34.5\n" +
+ "6,Sally,Miller,6.78\n" +
+ "7,Alice,Smith,90.1\n" +
+ "8,Kelly,Williams,2.34\n";
+
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testBatchTableSourceSQL() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+ BatchTableSource csvTable = CommonTestData.getCsvTableSource();
+
+ tableEnv.registerTableSource("persons", csvTable);
+
+ Table result = tableEnv
+ .sql("SELECT `last`, FLOOR(id), score * 2 FROM persons WHERE score < 20");
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+
+ String expected = "Smith,1,24.6\n" +
+ "Miller,3,15.78\n" +
+ "Smith,4,0.24\n" +
+ "Miller,6,13.56\n" +
+ "Williams,8,4.68\n";
+
+ compareResultAsText(results, expected);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/GroupingSetsITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/GroupingSetsITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/GroupingSetsITCase.java
new file mode 100644
index 0000000..3c8a1cc
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/GroupingSetsITCase.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql;
+
+import org.apache.flink.api.common.functions.MapFunction;
+import org.apache.flink.api.java.DataSet;
+import org.apache.flink.api.java.ExecutionEnvironment;
+import org.apache.flink.api.java.operators.MapOperator;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.table.api.Table;
+import org.apache.flink.table.api.TableConfig;
+import org.apache.flink.table.api.TableEnvironment;
+import org.apache.flink.table.api.java.BatchTableEnvironment;
+import org.apache.flink.table.runtime.utils.TableProgramsClusterTestBase;
+import org.apache.flink.test.operators.util.CollectionDataSets;
+import org.apache.flink.test.util.TestBaseUtils;
+import org.apache.flink.types.Row;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * This test should be replaced by a DataSetAggregateITCase.
+ * We should only perform logical unit tests here.
+ * Until then, we perform a cluster test here.
+ */
+@RunWith(Parameterized.class)
+public class GroupingSetsITCase extends TableProgramsClusterTestBase {
+
+ private static final String TABLE_NAME = "MyTable";
+ private static final String TABLE_WITH_NULLS_NAME = "MyTableWithNulls";
+ private BatchTableEnvironment tableEnv;
+
+ public GroupingSetsITCase(TestExecutionMode mode, TableConfigMode tableConfigMode) {
+ super(mode, tableConfigMode);
+ }
+
+ @Before
+ public void setupTables() {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ tableEnv = TableEnvironment.getTableEnvironment(env, new TableConfig());
+
+ DataSet<Tuple3<Integer, Long, String>> dataSet = CollectionDataSets.get3TupleDataSet(env);
+ tableEnv.registerDataSet(TABLE_NAME, dataSet);
+
+ MapOperator<Tuple3<Integer, Long, String>, Tuple3<Integer, Long, String>> dataSetWithNulls =
+ dataSet.map(new MapFunction<Tuple3<Integer, Long, String>, Tuple3<Integer, Long, String>>() {
+
+ @Override
+ public Tuple3<Integer, Long, String> map(Tuple3<Integer, Long, String> value) throws Exception {
+ if (value.f2.toLowerCase().contains("world")) {
+ value.f2 = null;
+ }
+ return value;
+ }
+ });
+ tableEnv.registerDataSet(TABLE_WITH_NULLS_NAME, dataSetWithNulls);
+ }
+
+ @Test
+ public void testGroupingSets() throws Exception {
+ String query =
+ "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
+ " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
+ " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
+ " GROUPING_ID(f1, f2) as gid " +
+ " FROM " + TABLE_NAME +
+ " GROUP BY GROUPING SETS (f1, f2)";
+
+ String expected =
+ "1,null,1,1,0,1,0,1,1\n" +
+ "6,null,18,1,0,1,0,1,1\n" +
+ "2,null,2,1,0,1,0,1,1\n" +
+ "4,null,8,1,0,1,0,1,1\n" +
+ "5,null,13,1,0,1,0,1,1\n" +
+ "3,null,5,1,0,1,0,1,1\n" +
+ "null,Comment#11,17,2,1,0,1,0,2\n" +
+ "null,Comment#8,14,2,1,0,1,0,2\n" +
+ "null,Comment#2,8,2,1,0,1,0,2\n" +
+ "null,Comment#1,7,2,1,0,1,0,2\n" +
+ "null,Comment#14,20,2,1,0,1,0,2\n" +
+ "null,Comment#7,13,2,1,0,1,0,2\n" +
+ "null,Comment#6,12,2,1,0,1,0,2\n" +
+ "null,Comment#3,9,2,1,0,1,0,2\n" +
+ "null,Comment#12,18,2,1,0,1,0,2\n" +
+ "null,Comment#5,11,2,1,0,1,0,2\n" +
+ "null,Comment#15,21,2,1,0,1,0,2\n" +
+ "null,Comment#4,10,2,1,0,1,0,2\n" +
+ "null,Hi,1,2,1,0,1,0,2\n" +
+ "null,Comment#10,16,2,1,0,1,0,2\n" +
+ "null,Hello world,3,2,1,0,1,0,2\n" +
+ "null,I am fine.,5,2,1,0,1,0,2\n" +
+ "null,Hello world, how are you?,4,2,1,0,1,0,2\n" +
+ "null,Comment#9,15,2,1,0,1,0,2\n" +
+ "null,Comment#13,19,2,1,0,1,0,2\n" +
+ "null,Luke Skywalker,6,2,1,0,1,0,2\n" +
+ "null,Hello,2,2,1,0,1,0,2";
+
+ checkSql(query, expected);
+ }
+
+ @Test
+ public void testGroupingSetsWithNulls() throws Exception {
+ String query =
+ "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g FROM " + TABLE_WITH_NULLS_NAME +
+ " GROUP BY GROUPING SETS (f1, f2)";
+
+ String expected =
+ "6,null,18,1\n5,null,13,1\n4,null,8,1\n3,null,5,1\n2,null,2,1\n1,null,1,1\n" +
+ "null,Luke Skywalker,6,2\nnull,I am fine.,5,2\nnull,Hi,1,2\n" +
+ "null,null,3,2\nnull,Hello,2,2\nnull,Comment#9,15,2\nnull,Comment#8,14,2\n" +
+ "null,Comment#7,13,2\nnull,Comment#6,12,2\nnull,Comment#5,11,2\n" +
+ "null,Comment#4,10,2\nnull,Comment#3,9,2\nnull,Comment#2,8,2\n" +
+ "null,Comment#15,21,2\nnull,Comment#14,20,2\nnull,Comment#13,19,2\n" +
+ "null,Comment#12,18,2\nnull,Comment#11,17,2\nnull,Comment#10,16,2\n" +
+ "null,Comment#1,7,2";
+
+ checkSql(query, expected);
+ }
+
+ @Test
+ public void testCubeAsGroupingSets() throws Exception {
+ String cubeQuery =
+ "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
+ " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
+ " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
+ " GROUPING_ID(f1, f2) as gid " +
+ " FROM " + TABLE_NAME + " GROUP BY CUBE (f1, f2)";
+
+ String groupingSetsQuery =
+ "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
+ " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
+ " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
+ " GROUPING_ID(f1, f2) as gid " +
+ " FROM " + TABLE_NAME +
+ " GROUP BY GROUPING SETS ((f1, f2), (f1), (f2), ())";
+
+ compareSql(cubeQuery, groupingSetsQuery);
+ }
+
+ @Test
+ public void testRollupAsGroupingSets() throws Exception {
+ String rollupQuery =
+ "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
+ " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
+ " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
+ " GROUPING_ID(f1, f2) as gid " +
+ " FROM " + TABLE_NAME + " GROUP BY ROLLUP (f1, f2)";
+
+ String groupingSetsQuery =
+ "SELECT f1, f2, avg(f0) as a, GROUP_ID() as g, " +
+ " GROUPING(f1) as gf1, GROUPING(f2) as gf2, " +
+ " GROUPING_ID(f1) as gif1, GROUPING_ID(f2) as gif2, " +
+ " GROUPING_ID(f1, f2) as gid " +
+ " FROM " + TABLE_NAME +
+ " GROUP BY GROUPING SETS ((f1, f2), (f1), ())";
+
+ compareSql(rollupQuery, groupingSetsQuery);
+ }
+
+ /**
+ * Execute SQL query and check results.
+ *
+ * @param query SQL query.
+ * @param expected Expected result.
+ */
+ private void checkSql(String query, String expected) throws Exception {
+ Table resultTable = tableEnv.sql(query);
+ DataSet<Row> resultDataSet = tableEnv.toDataSet(resultTable, Row.class);
+ List<Row> results = resultDataSet.collect();
+ TestBaseUtils.compareResultAsText(results, expected);
+ }
+
+ private void compareSql(String query1, String query2) throws Exception {
+
+ // Function to map row to string
+ MapFunction<Row, String> mapFunction = new MapFunction<Row, String>() {
+
+ @Override
+ public String map(Row value) throws Exception {
+ return value == null ? "null" : value.toString();
+ }
+ };
+
+ // Execute first query and store results
+ Table resultTable1 = tableEnv.sql(query1);
+ DataSet<Row> resultDataSet1 = tableEnv.toDataSet(resultTable1, Row.class);
+ List<String> results1 = resultDataSet1.map(mapFunction).collect();
+
+ // Execute second query and store results
+ Table resultTable2 = tableEnv.sql(query2);
+ DataSet<Row> resultDataSet2 = tableEnv.toDataSet(resultTable2, Row.class);
+ List<String> results2 = resultDataSet2.map(mapFunction).collect();
+
+ // Compare results
+ TestBaseUtils.compareResultCollections(results1, results2, new Comparator<String>() {
+
+ @Override
+ public int compare(String o1, String o2) {
+ return o2 == null ? o1 == null ? 0 : 1 : o1.compareTo(o2);
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/JavaSqlITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/JavaSqlITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/JavaSqlITCase.java
new file mode 100644
index 0000000..c5a394a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/sql/JavaSqlITCase.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql;
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.DataSet;
+import org.apache.flink.api.java.ExecutionEnvironment;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.api.java.tuple.Tuple5;
+import org.apache.flink.api.java.typeutils.MapTypeInfo;
+import org.apache.flink.api.java.typeutils.TupleTypeInfo;
+import org.apache.flink.table.api.Table;
+import org.apache.flink.table.api.TableEnvironment;
+import org.apache.flink.table.api.java.BatchTableEnvironment;
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase;
+import org.apache.flink.test.operators.util.CollectionDataSets;
+import org.apache.flink.types.Row;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Integration tests for batch SQL.
+ */
+@RunWith(Parameterized.class)
+public class JavaSqlITCase extends TableProgramsCollectionTestBase {
+
+ public JavaSqlITCase(TableConfigMode configMode) {
+ super(configMode);
+ }
+
+ @Test
+ public void testValues() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ String sqlQuery = "VALUES (1, 'Test', TRUE, DATE '1944-02-24', 12.4444444444444445)," +
+ "(2, 'Hello', TRUE, DATE '1944-02-24', 12.666666665)," +
+ "(3, 'World', FALSE, DATE '1944-12-24', 12.54444445)";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+
+ List<Row> results = resultSet.collect();
+ String expected = "3,World,false,1944-12-24,12.5444444500000000\n" +
+ "2,Hello,true,1944-02-24,12.6666666650000000\n" +
+ // Calcite converts to decimals and strings with equal length
+ "1,Test ,true,1944-02-24,12.4444444444444445\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testSelectFromTable() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ Table in = tableEnv.fromDataSet(ds, "a,b,c");
+ tableEnv.registerTable("T", in);
+
+ String sqlQuery = "SELECT a, c FROM T";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "1,Hi\n" + "2,Hello\n" + "3,Hello world\n" +
+ "4,Hello world, how are you?\n" + "5,I am fine.\n" + "6,Luke Skywalker\n" +
+ "7,Comment#1\n" + "8,Comment#2\n" + "9,Comment#3\n" + "10,Comment#4\n" +
+ "11,Comment#5\n" + "12,Comment#6\n" + "13,Comment#7\n" +
+ "14,Comment#8\n" + "15,Comment#9\n" + "16,Comment#10\n" +
+ "17,Comment#11\n" + "18,Comment#12\n" + "19,Comment#13\n" +
+ "20,Comment#14\n" + "21,Comment#15\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testFilterFromDataSet() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ tableEnv.registerDataSet("DataSetTable", ds, "x, y, z");
+
+ String sqlQuery = "SELECT x FROM DataSetTable WHERE z LIKE '%Hello%'";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "2\n" + "3\n" + "4";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testAggregation() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ tableEnv.registerDataSet("AggTable", ds, "x, y, z");
+
+ String sqlQuery = "SELECT sum(x), min(x), max(x), count(y), avg(x) FROM AggTable";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "231,1,21,21,11";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testJoin() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds1 = CollectionDataSets.getSmall3TupleDataSet(env);
+ DataSet<Tuple5<Integer, Long, Integer, String, Long>> ds2 = CollectionDataSets.get5TupleDataSet(env);
+
+ tableEnv.registerDataSet("t1", ds1, "a, b, c");
+ tableEnv.registerDataSet("t2", ds2, "d, e, f, g, h");
+
+ String sqlQuery = "SELECT c, g FROM t1, t2 WHERE b = e";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testMap() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ List<Tuple2<Integer, Map<String, String>>> rows = new ArrayList<>();
+ rows.add(new Tuple2<>(1, Collections.singletonMap("foo", "bar")));
+ rows.add(new Tuple2<>(2, Collections.singletonMap("foo", "spam")));
+
+ TypeInformation<Tuple2<Integer, Map<String, String>>> ty = new TupleTypeInfo<>(
+ BasicTypeInfo.INT_TYPE_INFO,
+ new MapTypeInfo<>(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO));
+
+ DataSet<Tuple2<Integer, Map<String, String>>> ds1 = env.fromCollection(rows, ty);
+ tableEnv.registerDataSet("t1", ds1, "a, b");
+
+ String sqlQuery = "SELECT b['foo'] FROM t1";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "bar\n" + "spam\n";
+ compareResultAsText(results, expected);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/table/JavaTableEnvironmentITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/table/JavaTableEnvironmentITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/table/JavaTableEnvironmentITCase.java
new file mode 100644
index 0000000..be7879a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/batch/table/JavaTableEnvironmentITCase.java
@@ -0,0 +1,686 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table;
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.DataSet;
+import org.apache.flink.api.java.ExecutionEnvironment;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.api.java.tuple.Tuple5;
+import org.apache.flink.api.java.typeutils.GenericTypeInfo;
+import org.apache.flink.api.java.typeutils.TupleTypeInfo;
+import org.apache.flink.table.api.Table;
+import org.apache.flink.table.api.TableEnvironment;
+import org.apache.flink.table.api.TableException;
+import org.apache.flink.table.api.java.BatchTableEnvironment;
+import org.apache.flink.table.calcite.CalciteConfig;
+import org.apache.flink.table.calcite.CalciteConfigBuilder;
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase;
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase;
+import org.apache.flink.test.operators.util.CollectionDataSets;
+import org.apache.flink.types.Row;
+
+import org.apache.calcite.tools.RuleSets;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Integration tests for {@link BatchTableEnvironment}.
+ */
+@RunWith(Parameterized.class)
+public class JavaTableEnvironmentITCase extends TableProgramsCollectionTestBase {
+
+ public JavaTableEnvironmentITCase(TableConfigMode configMode) {
+ super(configMode);
+ }
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ public static Collection<Object[]> parameters() {
+ return Arrays.asList(new Object[][] {
+ { TableProgramsTestBase.DEFAULT() }
+ });
+ }
+
+ @Test
+ public void testSimpleRegister() throws Exception {
+ final String tableName = "MyTable";
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ tableEnv.registerDataSet(tableName, ds);
+ Table t = tableEnv.scan(tableName);
+
+ Table result = t.select("f0, f1");
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
+ "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testRegisterWithFields() throws Exception {
+ final String tableName = "MyTable";
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ tableEnv.registerDataSet(tableName, ds, "a, b, c");
+ Table t = tableEnv.scan(tableName);
+
+ Table result = t.select("a, b, c");
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" +
+ "14,5,Comment#8\n" + "15,5,Comment#9\n" + "16,6,Comment#10\n" +
+ "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19,6,Comment#13\n" +
+ "20,6,Comment#14\n" + "21,6,Comment#15\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test(expected = TableException.class)
+ public void testRegisterExistingDatasetTable() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ tableEnv.registerDataSet("MyTable", ds);
+ DataSet<Tuple5<Integer, Long, Integer, String, Long>> ds2 =
+ CollectionDataSets.getSmall5TupleDataSet(env);
+ // Must fail. Name is already used for different table.
+ tableEnv.registerDataSet("MyTable", ds2);
+ }
+
+ @Test(expected = TableException.class)
+ public void testScanUnregisteredTable() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // Must fail. No table registered under that name.
+ tableEnv.scan("nonRegisteredTable");
+ }
+
+ @Test
+ public void testTableRegister() throws Exception {
+ final String tableName = "MyTable";
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ Table t = tableEnv.fromDataSet(ds);
+ tableEnv.registerTable(tableName, t);
+ Table result = tableEnv.scan(tableName).select("f0, f1").filter("f0 > 7");
+
+ DataSet<Row> resultSet = tableEnv.toDataSet(result, Row.class);
+ List<Row> results = resultSet.collect();
+ String expected = "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" +
+ "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test(expected = TableException.class)
+ public void testIllegalName() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ Table t = tableEnv.fromDataSet(ds);
+ // Must fail. Table name matches internal name pattern.
+ tableEnv.registerTable("_DataSetTable_42", t);
+ }
+
+ @Test(expected = TableException.class)
+ public void testRegisterTableFromOtherEnv() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv1 = TableEnvironment.getTableEnvironment(env, config());
+ BatchTableEnvironment tableEnv2 = TableEnvironment.getTableEnvironment(env, config());
+
+ Table t = tableEnv1.fromDataSet(CollectionDataSets.get3TupleDataSet(env));
+ // Must fail. Table is bound to different TableEnvironment.
+ tableEnv2.registerTable("MyTable", t);
+ }
+
+ @Test
+ public void testAsFromTuple() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ Table table = tableEnv
+ .fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, c")
+ .select("a, b, c");
+
+ DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
+ List<Row> results = ds.collect();
+ String expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" +
+ "14,5,Comment#8\n" + "15,5,Comment#9\n" + "16,6,Comment#10\n" +
+ "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19,6,Comment#13\n" +
+ "20,6,Comment#14\n" + "21,6,Comment#15\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testAsFromAndToTuple() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ Table table = tableEnv
+ .fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, c")
+ .select("a, b, c");
+
+ TypeInformation<?> ti = new TupleTypeInfo<Tuple3<Integer, Long, String>>(
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.LONG_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO);
+
+ DataSet<?> ds = tableEnv.toDataSet(table, ti);
+ List<?> results = ds.collect();
+ String expected = "(1,1,Hi)\n" + "(2,2,Hello)\n" + "(3,2,Hello world)\n" +
+ "(4,3,Hello world, how are you?)\n" + "(5,3,I am fine.)\n" + "(6,3,Luke Skywalker)\n" +
+ "(7,4,Comment#1)\n" + "(8,4,Comment#2)\n" + "(9,4,Comment#3)\n" + "(10,4,Comment#4)\n" +
+ "(11,5,Comment#5)\n" + "(12,5,Comment#6)\n" + "(13,5,Comment#7)\n" +
+ "(14,5,Comment#8)\n" + "(15,5,Comment#9)\n" + "(16,6,Comment#10)\n" +
+ "(17,6,Comment#11)\n" + "(18,6,Comment#12)\n" + "(19,6,Comment#13)\n" +
+ "(20,6,Comment#14)\n" + "(21,6,Comment#15)\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Ignore
+ @Test
+ public void testAsFromTupleToPojo() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ List<Tuple4<String, Integer, Double, String>> data = new ArrayList<>();
+ data.add(new Tuple4<>("Rofl", 1, 1.0, "Hi"));
+ data.add(new Tuple4<>("lol", 2, 1.0, "Hi"));
+ data.add(new Tuple4<>("Test me", 4, 3.33, "Hello world"));
+
+ Table table = tableEnv
+ .fromDataSet(env.fromCollection(data), "q, w, e, r")
+ .select("q as a, w as b, e as c, r as d");
+
+ DataSet<SmallPojo2> ds = tableEnv.toDataSet(table, SmallPojo2.class);
+ List<SmallPojo2> results = ds.collect();
+ String expected = "Rofl,1,1.0,Hi\n" + "lol,2,1.0,Hi\n" + "Test me,4,3.33,Hello world\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testAsFromPojo() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ List<SmallPojo> data = new ArrayList<>();
+ data.add(new SmallPojo("Peter", 28, 4000.00, "Sales", new Integer[] {42}));
+ data.add(new SmallPojo("Anna", 56, 10000.00, "Engineering", new Integer[] {}));
+ data.add(new SmallPojo("Lucy", 42, 6000.00, "HR", new Integer[] {1, 2, 3}));
+
+ Table table = tableEnv
+ .fromDataSet(env.fromCollection(data),
+ "department AS a, " +
+ "age AS b, " +
+ "salary AS c, " +
+ "name AS d," +
+ "roles as e")
+ .select("a, b, c, d, e");
+
+ DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
+ List<Row> results = ds.collect();
+ String expected =
+ "Sales,28,4000.0,Peter,[42]\n" +
+ "Engineering,56,10000.0,Anna,[]\n" +
+ "HR,42,6000.0,Lucy,[1, 2, 3]\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testAsFromPrivateFieldsPojo() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ List<PrivateSmallPojo> data = new ArrayList<>();
+ data.add(new PrivateSmallPojo("Peter", 28, 4000.00, "Sales"));
+ data.add(new PrivateSmallPojo("Anna", 56, 10000.00, "Engineering"));
+ data.add(new PrivateSmallPojo("Lucy", 42, 6000.00, "HR"));
+
+ Table table = tableEnv
+ .fromDataSet(env.fromCollection(data),
+ "department AS a, " +
+ "age AS b, " +
+ "salary AS c, " +
+ "name AS d")
+ .select("a, b, c, d");
+
+ DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
+ List<Row> results = ds.collect();
+ String expected =
+ "Sales,28,4000.0,Peter\n" +
+ "Engineering,56,10000.0,Anna\n" +
+ "HR,42,6000.0,Lucy\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testAsFromAndToPojo() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ List<SmallPojo> data = new ArrayList<>();
+ data.add(new SmallPojo("Peter", 28, 4000.00, "Sales", new Integer[] {42}));
+ data.add(new SmallPojo("Anna", 56, 10000.00, "Engineering", new Integer[] {}));
+ data.add(new SmallPojo("Lucy", 42, 6000.00, "HR", new Integer[] {1, 2, 3}));
+
+ Table table = tableEnv
+ .fromDataSet(env.fromCollection(data),
+ "department AS a, " +
+ "age AS b, " +
+ "salary AS c, " +
+ "name AS d," +
+ "roles AS e")
+ .select("a, b, c, d, e");
+
+ DataSet<SmallPojo2> ds = tableEnv.toDataSet(table, SmallPojo2.class);
+ List<SmallPojo2> results = ds.collect();
+ String expected =
+ "Sales,28,4000.0,Peter,[42]\n" +
+ "Engineering,56,10000.0,Anna,[]\n" +
+ "HR,42,6000.0,Lucy,[1, 2, 3]\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testAsFromAndToPrivateFieldPojo() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ List<PrivateSmallPojo> data = new ArrayList<>();
+ data.add(new PrivateSmallPojo("Peter", 28, 4000.00, "Sales"));
+ data.add(new PrivateSmallPojo("Anna", 56, 10000.00, "Engineering"));
+ data.add(new PrivateSmallPojo("Lucy", 42, 6000.00, "HR"));
+
+ Table table = tableEnv
+ .fromDataSet(env.fromCollection(data),
+ "department AS a, " +
+ "age AS b, " +
+ "salary AS c, " +
+ "name AS d")
+ .select("a, b, c, d");
+
+ DataSet<PrivateSmallPojo2> ds = tableEnv.toDataSet(table, PrivateSmallPojo2.class);
+ List<PrivateSmallPojo2> results = ds.collect();
+ String expected =
+ "Sales,28,4000.0,Peter\n" +
+ "Engineering,56,10000.0,Anna\n" +
+ "HR,42,6000.0,Lucy\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test
+ public void testAsWithPojoAndGenericTypes() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ List<PojoWithGeneric> data = new ArrayList<>();
+ data.add(new PojoWithGeneric("Peter", 28, new HashMap<String, String>(), new ArrayList<String>()));
+ HashMap<String, String> hm1 = new HashMap<>();
+ hm1.put("test1", "test1");
+ data.add(new PojoWithGeneric("Anna", 56, hm1, new ArrayList<String>()));
+ HashMap<String, String> hm2 = new HashMap<>();
+ hm2.put("abc", "cde");
+ data.add(new PojoWithGeneric("Lucy", 42, hm2, new ArrayList<String>()));
+
+ Table table = tableEnv
+ .fromDataSet(env.fromCollection(data),
+ "name AS a, " +
+ "age AS b, " +
+ "generic AS c, " +
+ "generic2 AS d")
+ .select("a, b, c, c as c2, d")
+ .select("a, b, c, c === c2, d");
+
+ DataSet<Row> ds = tableEnv.toDataSet(table, Row.class);
+ List<Row> results = ds.collect();
+ String expected =
+ "Peter,28,{},true,[]\n" +
+ "Anna,56,{test1=test1},true,[]\n" +
+ "Lucy,42,{abc=cde},true,[]\n";
+ compareResultAsText(results, expected);
+ }
+
+ @Test(expected = TableException.class)
+ public void testGenericRow() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // use null value the enforce GenericType
+ DataSet<Row> dataSet = env.fromElements(Row.of(1, 2L, "Hello", null));
+ assertTrue(dataSet.getType() instanceof GenericTypeInfo);
+ assertTrue(dataSet.getType().getTypeClass().equals(Row.class));
+
+ // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
+ tableEnv.fromDataSet(dataSet);
+ }
+
+ @Test(expected = TableException.class)
+ public void testGenericRowWithAlias() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // use null value the enforce GenericType
+ DataSet<Row> dataSet = env.fromElements(Row.of((Integer) null));
+ assertTrue(dataSet.getType() instanceof GenericTypeInfo);
+ assertTrue(dataSet.getType().getTypeClass().equals(Row.class));
+
+ // Must fail. Cannot import DataSet<Row> with GenericTypeInfo.
+ tableEnv.fromDataSet(dataSet, "nullField");
+ }
+
+ @Test(expected = TableException.class)
+ public void testAsWithToManyFields() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // Must fail. Too many field names specified.
+ tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, c, d");
+ }
+
+ @Test(expected = TableException.class)
+ public void testAsWithAmbiguousFields() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // Must fail. Specified field names are not unique.
+ tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a, b, b");
+ }
+
+ @Test(expected = TableException.class)
+ public void testAsWithNonFieldReference1() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // Must fail. as() does only allow field name expressions
+ tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a + 1, b, c");
+ }
+
+ @Test(expected = TableException.class)
+ public void testAsWithNonFieldReference2() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // Must fail. as() does only allow field name expressions
+ tableEnv.fromDataSet(CollectionDataSets.get3TupleDataSet(env), "a as foo, b, c");
+ }
+
+ @Test(expected = TableException.class)
+ public void testNonStaticClassInput() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // Must fail since class is not static
+ tableEnv.fromDataSet(env.fromElements(new MyNonStatic()), "name");
+ }
+
+ @Test(expected = TableException.class)
+ public void testNonStaticClassOutput() throws Exception {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ // Must fail since class is not static
+ Table t = tableEnv.fromDataSet(env.fromElements(1, 2, 3), "number");
+ tableEnv.toDataSet(t, MyNonStatic.class);
+ }
+
+ @Test(expected = TableException.class)
+ public void testCustomCalciteConfig() {
+ ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+ BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env, config());
+
+ CalciteConfig cc = new CalciteConfigBuilder()
+ .replaceLogicalOptRuleSet(RuleSets.ofList())
+ .replacePhysicalOptRuleSet(RuleSets.ofList())
+ .build();
+ tableEnv.getConfig().setCalciteConfig(cc);
+
+ DataSet<Tuple3<Integer, Long, String>> ds = CollectionDataSets.get3TupleDataSet(env);
+ Table t = tableEnv.fromDataSet(ds);
+ tableEnv.toDataSet(t, Row.class);
+ }
+
+ // --------------------------------------------------------------------------------------------
+
+ /**
+ * Non-static class.
+ */
+ public class MyNonStatic {
+ public int number;
+ }
+
+ /**
+ * Small POJO.
+ */
+ @SuppressWarnings("unused")
+ public static class SmallPojo {
+
+ public SmallPojo() { }
+
+ public SmallPojo(String name, int age, double salary, String department, Integer[] roles) {
+ this.name = name;
+ this.age = age;
+ this.salary = salary;
+ this.department = department;
+ this.roles = roles;
+ }
+
+ public String name;
+ public int age;
+ public double salary;
+ public String department;
+ public Integer[] roles;
+ }
+
+ /**
+ * POJO with generic fields.
+ */
+ @SuppressWarnings("unused")
+ public static class PojoWithGeneric {
+ public String name;
+ public int age;
+ public HashMap<String, String> generic;
+ public ArrayList<String> generic2;
+
+ public PojoWithGeneric() {
+ // default constructor
+ }
+
+ public PojoWithGeneric(String name, int age, HashMap<String, String> generic,
+ ArrayList<String> generic2) {
+ this.name = name;
+ this.age = age;
+ this.generic = generic;
+ this.generic2 = generic2;
+ }
+
+ @Override
+ public String toString() {
+ return name + "," + age + "," + generic + "," + generic2;
+ }
+ }
+
+ /**
+ * Small POJO with private fields.
+ */
+ @SuppressWarnings("unused")
+ public static class PrivateSmallPojo {
+
+ public PrivateSmallPojo() { }
+
+ public PrivateSmallPojo(String name, int age, double salary, String department) {
+ this.name = name;
+ this.age = age;
+ this.salary = salary;
+ this.department = department;
+ }
+
+ private String name;
+ private int age;
+ private double salary;
+ private String department;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public double getSalary() {
+ return salary;
+ }
+
+ public void setSalary(double salary) {
+ this.salary = salary;
+ }
+
+ public String getDepartment() {
+ return department;
+ }
+
+ public void setDepartment(String department) {
+ this.department = department;
+ }
+ }
+
+ /**
+ * Another small POJO.
+ */
+ @SuppressWarnings("unused")
+ public static class SmallPojo2 {
+
+ public SmallPojo2() { }
+
+ public SmallPojo2(String a, int b, double c, String d, Integer[] e) {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
+ this.e = e;
+ }
+
+ public String a;
+ public int b;
+ public double c;
+ public String d;
+ public Integer[] e;
+
+ @Override
+ public String toString() {
+ return a + "," + b + "," + c + "," + d + "," + Arrays.toString(e);
+ }
+ }
+
+ /**
+ * Another small POJO with private fields.
+ */
+ @SuppressWarnings("unused")
+ public static class PrivateSmallPojo2 {
+
+ public PrivateSmallPojo2() { }
+
+ public PrivateSmallPojo2(String a, int b, double c, String d) {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
+ }
+
+ private String a;
+ private int b;
+ private double c;
+ private String d;
+
+ public String getA() {
+ return a;
+ }
+
+ public void setA(String a) {
+ this.a = a;
+ }
+
+ public int getB() {
+ return b;
+ }
+
+ public void setB(int b) {
+ this.b = b;
+ }
+
+ public double getC() {
+ return c;
+ }
+
+ public void setC(double c) {
+ this.c = c;
+ }
+
+ public String getD() {
+ return d;
+ }
+
+ public void setD(String d) {
+ this.d = d;
+ }
+
+ @Override
+ public String toString() {
+ return a + "," + b + "," + c + "," + d;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/stream/sql/JavaSqlITCase.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/stream/sql/JavaSqlITCase.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/stream/sql/JavaSqlITCase.java
new file mode 100644
index 0000000..c6368d4
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/stream/sql/JavaSqlITCase.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.stream.sql;
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.api.java.tuple.Tuple5;
+import org.apache.flink.api.java.typeutils.RowTypeInfo;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase;
+import org.apache.flink.table.api.Table;
+import org.apache.flink.table.api.TableEnvironment;
+import org.apache.flink.table.api.java.StreamTableEnvironment;
+import org.apache.flink.table.runtime.utils.JavaStreamTestData;
+import org.apache.flink.table.runtime.utils.StreamITCase;
+import org.apache.flink.types.Row;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Integration tests for streaming SQL.
+ */
+public class JavaSqlITCase extends StreamingMultipleProgramsTestBase {
+
+ @Test
+ public void testRowRegisterRowWithNames() throws Exception {
+ StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+ StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
+ StreamITCase.clear();
+
+ List<Row> data = new ArrayList<>();
+ data.add(Row.of(1, 1L, "Hi"));
+ data.add(Row.of(2, 2L, "Hello"));
+ data.add(Row.of(3, 2L, "Hello world"));
+
+ TypeInformation<?>[] types = {
+ BasicTypeInfo.INT_TYPE_INFO,
+ BasicTypeInfo.LONG_TYPE_INFO,
+ BasicTypeInfo.STRING_TYPE_INFO};
+ String[] names = {"a", "b", "c"};
+
+ RowTypeInfo typeInfo = new RowTypeInfo(types, names);
+
+ DataStream<Row> ds = env.fromCollection(data).returns(typeInfo);
+
+ Table in = tableEnv.fromDataStream(ds, "a,b,c");
+ tableEnv.registerTable("MyTableRow", in);
+
+ String sqlQuery = "SELECT a,c FROM MyTableRow";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
+ resultSet.addSink(new StreamITCase.StringSink<Row>());
+ env.execute();
+
+ List<String> expected = new ArrayList<>();
+ expected.add("1,Hi");
+ expected.add("2,Hello");
+ expected.add("3,Hello world");
+
+ StreamITCase.compareWithList(expected);
+ }
+
+ @Test
+ public void testSelect() throws Exception {
+ StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+ StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
+ StreamITCase.clear();
+
+ DataStream<Tuple3<Integer, Long, String>> ds = JavaStreamTestData.getSmall3TupleDataSet(env);
+ Table in = tableEnv.fromDataStream(ds, "a,b,c");
+ tableEnv.registerTable("MyTable", in);
+
+ String sqlQuery = "SELECT * FROM MyTable";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
+ resultSet.addSink(new StreamITCase.StringSink<Row>());
+ env.execute();
+
+ List<String> expected = new ArrayList<>();
+ expected.add("1,1,Hi");
+ expected.add("2,2,Hello");
+ expected.add("3,2,Hello world");
+
+ StreamITCase.compareWithList(expected);
+ }
+
+ @Test
+ public void testFilter() throws Exception {
+ StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+ StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
+ StreamITCase.clear();
+
+ DataStream<Tuple5<Integer, Long, Integer, String, Long>> ds = JavaStreamTestData.get5TupleDataStream(env);
+ tableEnv.registerDataStream("MyTable", ds, "a, b, c, d, e");
+
+ String sqlQuery = "SELECT a, b, e FROM MyTable WHERE c < 4";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
+ resultSet.addSink(new StreamITCase.StringSink<Row>());
+ env.execute();
+
+ List<String> expected = new ArrayList<>();
+ expected.add("1,1,1");
+ expected.add("2,2,2");
+ expected.add("2,3,1");
+ expected.add("3,4,2");
+
+ StreamITCase.compareWithList(expected);
+ }
+
+ @Test
+ public void testUnion() throws Exception {
+ StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+ StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
+ StreamITCase.clear();
+
+ DataStream<Tuple3<Integer, Long, String>> ds1 = JavaStreamTestData.getSmall3TupleDataSet(env);
+ Table t1 = tableEnv.fromDataStream(ds1, "a,b,c");
+ tableEnv.registerTable("T1", t1);
+
+ DataStream<Tuple5<Integer, Long, Integer, String, Long>> ds2 = JavaStreamTestData.get5TupleDataStream(env);
+ tableEnv.registerDataStream("T2", ds2, "a, b, d, c, e");
+
+ String sqlQuery = "SELECT * FROM T1 " +
+ "UNION ALL " +
+ "(SELECT a, b, c FROM T2 WHERE a < 3)";
+ Table result = tableEnv.sql(sqlQuery);
+
+ DataStream<Row> resultSet = tableEnv.toAppendStream(result, Row.class);
+ resultSet.addSink(new StreamITCase.StringSink<Row>());
+ env.execute();
+
+ List<String> expected = new ArrayList<>();
+ expected.add("1,1,Hi");
+ expected.add("2,2,Hello");
+ expected.add("3,2,Hello world");
+ expected.add("1,1,Hallo");
+ expected.add("2,2,Hallo Welt");
+ expected.add("2,3,Hallo Welt wie");
+
+ StreamITCase.compareWithList(expected);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaPojos.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaPojos.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaPojos.java
new file mode 100644
index 0000000..6221834
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaPojos.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+/**
+ * POJOs for Table API testing.
+ */
+public class JavaPojos {
+
+ /**
+ * Pojo1 for test.
+ */
+ public static class Pojo1 implements Serializable {
+
+ public Timestamp ts;
+ public String msg;
+
+ @Override
+ public String toString() {
+ return "Pojo1{" +
+ "ts=" + ts +
+ ", msg='" + msg + '\'' +
+ '}';
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaStreamTestData.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaStreamTestData.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaStreamTestData.java
new file mode 100644
index 0000000..b42c119
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaStreamTestData.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils;
+
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.api.java.tuple.Tuple5;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Test data.
+ */
+public class JavaStreamTestData {
+
+ public static DataStream<Tuple3<Integer, Long, String>> getSmall3TupleDataSet(StreamExecutionEnvironment env) {
+
+ List<Tuple3<Integer, Long, String>> data = new ArrayList<>();
+ data.add(new Tuple3<>(1, 1L, "Hi"));
+ data.add(new Tuple3<>(2, 2L, "Hello"));
+ data.add(new Tuple3<>(3, 2L, "Hello world"));
+
+ Collections.shuffle(data);
+
+ return env.fromCollection(data);
+ }
+
+ public static DataStream<Tuple5<Integer, Long, Integer, String, Long>> get5TupleDataStream(StreamExecutionEnvironment env) {
+
+ List<Tuple5<Integer, Long, Integer, String, Long>> data = new ArrayList<>();
+ data.add(new Tuple5<>(1, 1L, 0, "Hallo", 1L));
+ data.add(new Tuple5<>(2, 2L, 1, "Hallo Welt", 2L));
+ data.add(new Tuple5<>(2, 3L, 2, "Hallo Welt wie", 1L));
+ data.add(new Tuple5<>(3, 4L, 3, "Hallo Welt wie gehts?", 2L));
+ data.add(new Tuple5<>(3, 5L, 4, "ABC", 2L));
+ data.add(new Tuple5<>(3, 6L, 5, "BCD", 3L));
+ data.add(new Tuple5<>(4, 7L, 6, "CDE", 2L));
+ data.add(new Tuple5<>(4, 8L, 7, "DEF", 1L));
+ data.add(new Tuple5<>(4, 9L, 8, "EFG", 1L));
+ data.add(new Tuple5<>(4, 10L, 9, "FGH", 2L));
+ data.add(new Tuple5<>(5, 11L, 10, "GHI", 1L));
+ data.add(new Tuple5<>(5, 12L, 11, "HIJ", 3L));
+ data.add(new Tuple5<>(5, 13L, 12, "IJK", 3L));
+ data.add(new Tuple5<>(5, 15L, 14, "KLM", 2L));
+ data.add(new Tuple5<>(5, 14L, 13, "JKL", 2L));
+ return env.fromCollection(data);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedAggFunctions.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedAggFunctions.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedAggFunctions.java
new file mode 100644
index 0000000..4d06bc2
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedAggFunctions.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils;
+
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.table.functions.AggregateFunction;
+
+import java.util.Iterator;
+
+/**
+ * Test aggregator functions.
+ */
+public class JavaUserDefinedAggFunctions {
+ /**
+ * Accumulator for test requiresOver.
+ */
+ public static class Accumulator0 extends Tuple2<Long, Integer>{}
+
+ /**
+ * Test for requiresOver.
+ */
+ public static class OverAgg0 extends AggregateFunction<Long, Accumulator0> {
+ @Override
+ public Accumulator0 createAccumulator() {
+ return new Accumulator0();
+ }
+
+ @Override
+ public Long getValue(Accumulator0 accumulator) {
+ return 1L;
+ }
+
+ //Overloaded accumulate method
+ public void accumulate(Accumulator0 accumulator, long iValue, int iWeight) {
+ }
+
+ @Override
+ public boolean requiresOver() {
+ return true;
+ }
+ }
+
+ /**
+ * Accumulator for WeightedAvg.
+ */
+ public static class WeightedAvgAccum {
+ public long sum = 0;
+ public int count = 0;
+ }
+
+ /**
+ * Base class for WeightedAvg.
+ */
+ public static class WeightedAvg extends AggregateFunction<Long, WeightedAvgAccum> {
+ @Override
+ public WeightedAvgAccum createAccumulator() {
+ return new WeightedAvgAccum();
+ }
+
+ @Override
+ public Long getValue(WeightedAvgAccum accumulator) {
+ if (accumulator.count == 0) {
+ return null;
+ } else {
+ return accumulator.sum / accumulator.count;
+ }
+ }
+
+ // overloaded accumulate method
+ public void accumulate(WeightedAvgAccum accumulator, long iValue, int iWeight) {
+ accumulator.sum += iValue * iWeight;
+ accumulator.count += iWeight;
+ }
+
+ //Overloaded accumulate method
+ public void accumulate(WeightedAvgAccum accumulator, int iValue, int iWeight) {
+ accumulator.sum += iValue * iWeight;
+ accumulator.count += iWeight;
+ }
+ }
+
+ /**
+ * A WeightedAvg class with merge method.
+ */
+ public static class WeightedAvgWithMerge extends WeightedAvg {
+ public void merge(WeightedAvgAccum acc, Iterable<WeightedAvgAccum> it) {
+ Iterator<WeightedAvgAccum> iter = it.iterator();
+ while (iter.hasNext()) {
+ WeightedAvgAccum a = iter.next();
+ acc.count += a.count;
+ acc.sum += a.sum;
+ }
+ }
+ }
+
+ /**
+ * A WeightedAvg class with merge and reset method.
+ */
+ public static class WeightedAvgWithMergeAndReset extends WeightedAvgWithMerge {
+ public void resetAccumulator(WeightedAvgAccum acc) {
+ acc.count = 0;
+ acc.sum = 0L;
+ }
+ }
+
+ /**
+ * A WeightedAvg class with retract method.
+ */
+ public static class WeightedAvgWithRetract extends WeightedAvg {
+ //Overloaded retract method
+ public void retract(WeightedAvgAccum accumulator, long iValue, int iWeight) {
+ accumulator.sum -= iValue * iWeight;
+ accumulator.count -= iWeight;
+ }
+
+ //Overloaded retract method
+ public void retract(WeightedAvgAccum accumulator, int iValue, int iWeight) {
+ accumulator.sum -= iValue * iWeight;
+ accumulator.count -= iWeight;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedScalarFunctions.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedScalarFunctions.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedScalarFunctions.java
new file mode 100644
index 0000000..a77ad9a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedScalarFunctions.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils;
+
+import org.apache.flink.table.functions.ScalarFunction;
+
+import java.util.Arrays;
+
+/**
+ * Test scalar functions.
+ */
+public class JavaUserDefinedScalarFunctions {
+
+ /**
+ * Increment input.
+ */
+ public static class JavaFunc0 extends ScalarFunction {
+ public long eval(Long l) {
+ return l + 1;
+ }
+ }
+
+ /**
+ * Concatenate inputs as strings.
+ */
+ public static class JavaFunc1 extends ScalarFunction {
+ public String eval(Integer a, int b, Long c) {
+ return a + " and " + b + " and " + c;
+ }
+ }
+
+ /**
+ * Append product to string.
+ */
+ public static class JavaFunc2 extends ScalarFunction {
+ public String eval(String s, Integer... a) {
+ int m = 1;
+ for (int n : a) {
+ m *= n;
+ }
+ return s + m;
+ }
+ }
+
+ /**
+ * Test overloading.
+ */
+ public static class JavaFunc3 extends ScalarFunction {
+ public int eval(String a, int... b) {
+ return b.length;
+ }
+
+ public String eval(String c) {
+ return c;
+ }
+ }
+
+ /**
+ * Concatenate arrays as strings.
+ */
+ public static class JavaFunc4 extends ScalarFunction {
+ public String eval(Integer[] a, String[] b) {
+ return Arrays.toString(a) + " and " + Arrays.toString(b);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedTableFunctions.java
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedTableFunctions.java b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedTableFunctions.java
new file mode 100644
index 0000000..cd92f49
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/java/org/apache/flink/table/runtime/utils/JavaUserDefinedTableFunctions.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils;
+
+import org.apache.flink.table.functions.TableFunction;
+
+/**
+ * Test functions.
+ */
+public class JavaUserDefinedTableFunctions {
+
+ /**
+ * Emit inputs as long.
+ */
+ public static class JavaTableFunc0 extends TableFunction<Long> {
+ public void eval(Integer a, Long b, Long c) {
+ collect(a.longValue());
+ collect(b);
+ collect(c);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala
deleted file mode 100644
index 9bc3e51..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/ExpressionReductionTest.scala
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.table.utils.TableTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.{Ignore, Test}
-
-class ExpressionReductionTest extends TableTestBase {
-
- @Test
- def testReduceCalcExpressionForBatchSQL(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceProjectExpressionForBatchSQL(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- )
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceFilterExpressionForBatchSQL(): Unit = {
- val util = batchTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "*" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceCalcExpressionForBatchTableAPI(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceProjectExpressionForBatchTableAPI(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceFilterExpressionForBatchTableAPI(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
-
- val expected = unaryNode(
- "DataSetCalc",
- batchTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceCalcExpressionForStreamSQL(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceProjectExpressionForStreamSQL(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "(3+4)+a, " +
- "b+(1+2), " +
- "CASE 11 WHEN 1 THEN 'a' ELSE 'b' END, " +
- "TRIM(BOTH ' STRING '), " +
- "'test' || 'string', " +
- "NULLIF(1, 1), " +
- "TIMESTAMP '1990-10-14 23:00:00.123' + INTERVAL '10 00:00:01' DAY TO SECOND, " +
- "EXTRACT(DAY FROM INTERVAL '19 12:10:10.123' DAY TO SECOND(3)), " +
- "1 IS NULL, " +
- "'TEST' LIKE '%EST', " +
- "FLOOR(2.5), " +
- "'TEST' IN ('west', 'TEST', 'rest'), " +
- "CAST(TRUE AS VARCHAR) || 'X'" +
- "FROM MyTable"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "+(7, a) AS EXPR$0",
- "+(b, 3) AS EXPR$1",
- "'b' AS EXPR$2",
- "'STRING' AS EXPR$3",
- "'teststring' AS EXPR$4",
- "null AS EXPR$5",
- "1990-10-24 23:00:01.123 AS EXPR$6",
- "19 AS EXPR$7",
- "false AS EXPR$8",
- "true AS EXPR$9",
- "2 AS EXPR$10",
- "true AS EXPR$11",
- "'trueX' AS EXPR$12"
- )
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceFilterExpressionForStreamSQL(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val sqlQuery = "SELECT " +
- "*" +
- "FROM MyTable WHERE a>(1+7)"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testReduceCalcExpressionForStreamTableAPI(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- ),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceProjectExpressionForStreamTableAPI(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .select((3 + 4).toExpr + 6,
- (11 === 1) ? ("a", "b"),
- " STRING ".trim,
- "test" + "string",
- "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
- 1.isNull,
- "TEST".like("%EST"),
- 2.5.toExpr.floor(),
- true.cast(Types.STRING) + "X")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select",
- "13 AS _c0",
- "'b' AS _c1",
- "'STRING' AS _c2",
- "'teststring' AS _c3",
- "1990-10-24 23:00:01.123 AS _c4",
- "false AS _c5",
- "true AS _c6",
- "2E0 AS _c7",
- "'trueX' AS _c8"
- )
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceFilterExpressionForStreamTableAPI(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .where('a > (1 + 7))
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c"),
- term("where", ">(a, 8)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testNestedTablesReductionStream(): Unit = {
- val util = streamTestUtil()
-
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
-
- util.tableEnv.registerTable("NewTable", newTable)
-
- val sqlQuery = "SELECT a FROM NewTable"
-
- // 1+1 should be normalized to 2
- val expected = unaryNode("DataStreamCalc", streamTableNode(0), term("select", "+(2, a) AS a"))
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testNestedTablesReductionBatch(): Unit = {
- val util = batchTestUtil()
-
- util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val newTable = util.tableEnv.sql("SELECT 1 + 1 + a AS a FROM MyTable")
-
- util.tableEnv.registerTable("NewTable", newTable)
-
- val sqlQuery = "SELECT a FROM NewTable"
-
- // 1+1 should be normalized to 2
- val expected = unaryNode("DataSetCalc", batchTableNode(0), term("select", "+(2, a) AS a"))
-
- util.verifySql(sqlQuery, expected)
- }
-
- // todo this NPE is caused by Calcite, it shall pass when [CALCITE-1860] is fixed
- @Ignore
- def testReduceDeterministicUDF(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- // if isDeterministic = true, will cause a Calcite NPE, which will be fixed in [CALCITE-1860]
- val result = table
- .select('a, 'b, 'c, DeterministicNullFunc() as 'd)
- .where("d.isNull")
- .select('a, 'b, 'c)
-
- val expected: String = streamTableNode(0)
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testReduceNonDeterministicUDF(): Unit = {
- val util = streamTestUtil()
- val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- val result = table
- .select('a, 'b, 'c, NonDeterministicNullFunc() as 'd)
- .where("d.isNull")
- .select('a, 'b, 'c)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "a", "b", "c"),
- term("where", s"IS NULL(${NonDeterministicNullFunc.functionIdentifier}())")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
-
-object NonDeterministicNullFunc extends ScalarFunction {
- def eval(): String = null
- override def isDeterministic = false
-}
-
-object DeterministicNullFunc extends ScalarFunction {
- def eval(): String = null
- override def isDeterministic = true
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/ExternalCatalogTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/ExternalCatalogTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/ExternalCatalogTest.scala
new file mode 100644
index 0000000..a2356a6
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/ExternalCatalogTest.scala
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api
+
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.CommonTestData
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+/**
+ * Test for external catalog query plan.
+ */
+class ExternalCatalogTest extends TableTestBase {
+ private val table1Path: Array[String] = Array("test", "db1", "tb1")
+ private val table1TopLevelPath: Array[String] = Array("test", "tb1")
+ private val table1ProjectedFields: Array[String] = Array("a", "b", "c")
+ private val table2Path: Array[String] = Array("test", "db2", "tb2")
+ private val table2ProjectedFields: Array[String] = Array("d", "e", "g")
+
+ @Test
+ def testBatchTableApi(): Unit = {
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val table1 = tableEnv.scan("test", "db1", "tb1")
+ val table2 = tableEnv.scan("test", "db2", "tb2")
+ val result = table2
+ .select('d * 2, 'e, 'g.upperCase())
+ .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
+ ),
+ term("union", "_c0", "e", "_c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testBatchSQL(): Unit = {
+ val util = batchTestUtil()
+
+ util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
+ "(SELECT a * 2, b, c FROM test.db1.tb1)"
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS EXPR$0", "e", "g"),
+ term("where", "<(d, 3)")),
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS EXPR$0", "b", "c")
+ ),
+ term("union", "EXPR$0", "e", "g"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testStreamTableApi(): Unit = {
+ val util = streamTestUtil()
+ val tableEnv = util.tableEnv
+
+ util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val table1 = tableEnv.scan("test", "db1", "tb1")
+ val table2 = tableEnv.scan("test", "db2", "tb2")
+
+ val result = table2.where("d < 3")
+ .select('d * 2, 'e, 'g.upperCase())
+ .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
+
+ val expected = binaryNode(
+ "DataStreamUnion",
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2"),
+ term("where", "<(d, 3)")
+ ),
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
+ ),
+ term("union all", "_c0", "e", "_c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testStreamSQL(): Unit = {
+ val util = streamTestUtil()
+
+ util.tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val sqlQuery = "SELECT d * 2, e, g FROM test.db2.tb2 WHERE d < 3 UNION ALL " +
+ "(SELECT a * 2, b, c FROM test.db1.tb1)"
+
+ val expected = binaryNode(
+ "DataStreamUnion",
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS EXPR$0", "e", "g"),
+ term("where", "<(d, 3)")),
+ unaryNode(
+ "DataStreamCalc",
+ sourceStreamTableNode(table1Path, table1ProjectedFields),
+ term("select", "*(a, 2) AS EXPR$0", "b", "c")
+ ),
+ term("union all", "EXPR$0", "e", "g"))
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testTopLevelTable(): Unit = {
+ val util = batchTestUtil()
+ val tableEnv = util.tableEnv
+
+ tableEnv.registerExternalCatalog("test", CommonTestData.getInMemoryTestCatalog)
+
+ val table1 = tableEnv.scan("test", "tb1")
+ val table2 = tableEnv.scan("test", "db2", "tb2")
+ val result = table2
+ .select('d * 2, 'e, 'g.upperCase())
+ .unionAll(table1.select('a * 2, 'b, 'c.upperCase()))
+
+ val expected = binaryNode(
+ "DataSetUnion",
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table2Path, table2ProjectedFields),
+ term("select", "*(d, 2) AS _c0", "e", "UPPER(g) AS _c2")
+ ),
+ unaryNode(
+ "DataSetCalc",
+ sourceBatchTableNode(table1TopLevelPath, table1ProjectedFields),
+ term("select", "*(a, 2) AS _c0", "b", "UPPER(c) AS _c2")
+ ),
+ term("union", "_c0", "e", "_c2")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ def sourceBatchTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
+ s"BatchTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
+ s"fields=[${fields.mkString(", ")}])"
+ }
+
+ def sourceStreamTableNode(sourceTablePath: Array[String], fields: Array[String]): String = {
+ s"StreamTableSourceScan(table=[[${sourceTablePath.mkString(", ")}]], " +
+ s"fields=[${fields.mkString(", ")}])"
+ }
+}
[26/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CalcITCase.scala
new file mode 100644
index 0000000..116f690
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CalcITCase.scala
@@ -0,0 +1,542 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import java.sql.{Date, Time, Timestamp}
+import java.util
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.Types._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.expressions.utils.{Func13, RichFunc1, RichFunc2, RichFunc3}
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.table.runtime.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.runtime.utils.UserDefinedFunctionTestUtils
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.test.util.TestBaseUtils.compareResultAsText
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+@RunWith(classOf[Parameterized])
+class CalcITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSimpleSelectAll(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).select('_1, '_2, '_3)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectAllWithAs(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('a, 'b, 'c)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectWithNaming(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
+ .select('a, 'b)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
+ "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectRenameAll(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1 as 'a, '_2 as 'b, '_3 as 'c)
+ .select('a, 'b)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
+ "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectStar(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('*)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(false) )
+
+ val expected = "\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( Literal(true) )
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
+ "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
+ "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
+ "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
+ "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
+ "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnStringTupleField(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val filterDs = ds.filter( 'c.like("%world%") )
+
+ val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnIntegerTupleField(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 === 0 )
+
+ val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
+ "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
+ "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
+ "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testNotEquals(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a % 2 !== 0)
+ val expected = "1,1,Hi\n" + "3,2,Hello world\n" +
+ "5,3,I am fine.\n" + "7,4,Comment#1\n" + "9,4,Comment#3\n" +
+ "11,5,Comment#5\n" + "13,5,Comment#7\n" + "15,5,Comment#9\n" +
+ "17,6,Comment#11\n" + "19,6,Comment#13\n" + "21,6,Comment#15\n"
+ val results = filterDs.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDisjunctivePredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter( 'a < 2 || 'a > 20)
+ val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
+ val results = filterDs.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testConsecutiveFilters(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val filterDs = ds.filter('a % 2 !== 0).filter('b % 2 === 0)
+ val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
+ "9,4,Comment#3\n" + "17,6,Comment#11\n" +
+ "19,6,Comment#13\n" + "21,6,Comment#15\n"
+ val results = filterDs.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterBasicType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.getStringDataSet(env)
+
+ val filterDs = ds.toTable(tEnv, 'a).filter( 'a.like("H%") )
+
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hello world, how are you?\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnCustomType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.getCustomTypeDataSet(env)
+ val filterDs = ds.toTable(tEnv, 'myInt as 'i, 'myLong as 'l, 'myString as 's)
+ .filter( 's.like("%a%") )
+
+ val expected = "3,3,Hello world, how are you?\n" + "3,4,I am fine.\n" + "3,5,Luke Skywalker\n"
+ val results = filterDs.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleCalc(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .where('_1 < 7)
+ .select('_1, '_3)
+
+ val expected = "1,Hi\n" + "2,Hello\n" + "3,Hello world\n" +
+ "4,Hello world, how are you?\n" + "5,I am fine.\n" + "6,Luke Skywalker\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCalcWithTwoFilters(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .where('_1 < 7 && '_2 === 3)
+ .select('_1, '_3)
+ .where('_1 === 4)
+ .select('_1)
+
+ val expected = "4\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCalcWithAggregation(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .where('_1 < 15)
+ .groupBy('_2)
+ .select('_1.min, '_2.count as 'cnt)
+ .where('cnt > 3)
+
+ val expected = "7,4\n" + "11,4\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCalcJoin(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.select('a, 'b).join(ds2).where('b === 'e).select('a, 'b, 'd, 'e, 'f)
+ .where('b > 1).select('a, 'd).where('d === 2)
+
+ val expected = "2,2\n" + "3,2\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAdvancedDataTypes(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env
+ .fromElements((
+ BigDecimal("78.454654654654654").bigDecimal,
+ BigDecimal("4E+9999").bigDecimal,
+ Date.valueOf("1984-07-12"),
+ Time.valueOf("14:34:24"),
+ Timestamp.valueOf("1984-07-12 14:34:24")))
+ .toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .select('a, 'b, 'c, 'd, 'e, BigDecimal("11.2"), BigDecimal("11.2").bigDecimal,
+ Date.valueOf("1984-07-12"), Time.valueOf("14:34:24"),
+ Timestamp.valueOf("1984-07-12 14:34:24"))
+
+ val expected = "78.454654654654654,4E+9999,1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
+ "11.2,11.2,1984-07-12,14:34:24,1984-07-12 14:34:24.0"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedScalarFunction() {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ tableEnv.registerFunction("hashCode", OldHashCode)
+ tableEnv.registerFunction("hashCode", HashCode)
+ val table = env.fromElements("a", "b", "c").toTable(tableEnv, 'text)
+ val result = table.select("text.hashCode()")
+ val results = result.toDataSet[Row].collect()
+ val expected = "97\n98\n99"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testNumericAutocastInArithmetic() {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements(
+ (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d, 1L, 1001.1)).toTable(tableEnv)
+ .select('_1 + 1, '_2 + 1, '_3 + 1L, '_4 + 1.0f,
+ '_5 + 1.0d, '_6 + 1, '_7 + 1.0d, '_8 + '_1)
+
+ val results = table.toDataSet[Row].collect()
+ val expected = "2,2,2,2.0,2.0,2.0,2.0,1002.1"
+ compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testNumericAutocastInComparison() {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements(
+ (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d),
+ (2.toByte, 2.toShort, 2, 2L, 2.0f, 2.0d))
+ .toTable(tableEnv, 'a, 'b, 'c, 'd, 'e, 'f)
+ .filter('a > 1 && 'b > 1 && 'c > 1L && 'd > 1.0f && 'e > 1.0d && 'f > 1)
+
+ val results = table.toDataSet[Row].collect()
+ val expected: String = "2,2,2,2,2.0,2.0"
+ compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCasting() {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val table = env.fromElements((1, 0.0, 1L, true)).toTable(tableEnv)
+ .select(
+ // * -> String
+ '_1.cast(STRING), '_2.cast(STRING), '_3.cast(STRING), '_4.cast(STRING),
+ // NUMERIC TYPE -> Boolean
+ '_1.cast(BOOLEAN), '_2.cast(BOOLEAN), '_3.cast(BOOLEAN),
+ // NUMERIC TYPE -> NUMERIC TYPE
+ '_1.cast(DOUBLE), '_2.cast(INT), '_3.cast(SHORT),
+ // Boolean -> NUMERIC TYPE
+ '_4.cast(DOUBLE),
+ // identity casting
+ '_1.cast(INT), '_2.cast(DOUBLE), '_3.cast(LONG), '_4.cast(BOOLEAN))
+
+ val results = table.toDataSet[Row].collect()
+ val expected = "1,0.0,1,true," + "true,false,true," +
+ "1.0,0,1," + "1.0," + "1,0.0,1,true\n"
+ compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCastFromString() {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env)
+ val table = env.fromElements(("1", "true", "2.0")).toTable(tableEnv)
+ .select('_1.cast(BYTE), '_1.cast(SHORT), '_1.cast(INT), '_1.cast(LONG),
+ '_3.cast(DOUBLE), '_3.cast(FLOAT), '_2.cast(BOOLEAN))
+
+ val results = table.toDataSet[Row].collect()
+ val expected = "1,1,1,1,2.0,2.0,true\n"
+ compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedScalarFunctionWithParameter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "ABC"))
+
+ val ds = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT c FROM t1 where RichFunc2(c)='ABC#Hello'"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedScalarFunctionWithDistributedCache(): Unit = {
+ val words = "Hello\nWord"
+ val filePath = UserDefinedFunctionTestUtils.writeCacheFile("test_words", words)
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ env.registerCachedFile(filePath, "words")
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc3", new RichFunc3)
+
+ val ds = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT c FROM t1 where RichFunc3(c)=true"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMultipleUserDefinedScalarFunctions(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ tEnv.registerFunction("RichFunc1", new RichFunc1)
+ tEnv.registerFunction("RichFunc2", new RichFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("string.value" -> "Abc"))
+
+ val ds = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT c FROM t1 where " +
+ "RichFunc2(c)='Abc#Hello' or RichFunc1(a)=3 and b=2"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello\nHello world"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testScalarFunctionConstructorWithParams(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Jack#22"))
+ data.+=((2, 2L, "John#19"))
+ data.+=((3, 2L, "Anna#44"))
+ data.+=((4, 3L, "nosharp"))
+ val in = env.fromCollection(data).toTable(tableEnv).as('a, 'b, 'c)
+
+ val func0 = new Func13("default")
+ val func1 = new Func13("Sunny")
+ val func2 = new Func13("kevin2")
+
+ val result = in.select(func0('c), func1('c),func2('c))
+
+ val results = result.collect()
+
+ val expected = "default-Anna#44,Sunny-Anna#44,kevin2-Anna#44\n" +
+ "default-Jack#22,Sunny-Jack#22,kevin2-Jack#22\n" +
+ "default-John#19,Sunny-John#19,kevin2-John#19\n" +
+ "default-nosharp,Sunny-nosharp,kevin2-nosharp"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
+
+object CalcITCase {
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](
+ Array(TableProgramsTestBase.DEFAULT),
+ Array(TableProgramsTestBase.NO_NULL)).asJava
+ }
+}
+
+object HashCode extends ScalarFunction {
+ def eval(s: String): Int = s.hashCode
+}
+
+object OldHashCode extends ScalarFunction {
+ def eval(s: String): Int = -1
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CorrelateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CorrelateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CorrelateITCase.scala
new file mode 100644
index 0000000..759b825
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/CorrelateITCase.scala
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import java.sql.{Date, Timestamp}
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.runtime.utils.JavaUserDefinedTableFunctions.JavaTableFunc0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.utils.{Func1, Func13, Func18, RichFunc2}
+import org.apache.flink.table.runtime.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.runtime.utils._
+import org.apache.flink.table.utils._
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+@RunWith(classOf[Parameterized])
+class CorrelateITCase(
+ mode: TestExecutionMode,
+ configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val func1 = new TableFunc1
+ val result = in.join(func1('c) as 's).select('c, 's).toDataSet[Row]
+ val results = result.collect()
+ val expected = "Jack#22,Jack\n" + "Jack#22,22\n" + "John#19,John\n" + "John#19,19\n" +
+ "Anna#44,Anna\n" + "Anna#44,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+
+ // with overloading
+ val result2 = in.join(func1('c, "$") as 's).select('c, 's).toDataSet[Row]
+ val results2 = result2.collect()
+ val expected2 = "Jack#22,$Jack\n" + "Jack#22,$22\n" + "John#19,$John\n" +
+ "John#19,$19\n" + "Anna#44,$Anna\n" + "Anna#44,$44\n"
+ TestBaseUtils.compareResultAsText(results2.asJava, expected2)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val func2 = new TableFunc2
+ val result = in.leftOuterJoin(func2('c) as ('s, 'l)).select('c, 's, 'l).toDataSet[Row]
+ val results = result.collect()
+ val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
+ "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n" + "nosharp,null,null"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testWithFilter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = in
+ .join(func0('c) as ('name, 'age))
+ .select('c, 'name, 'age)
+ .filter('age > 20)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCustomReturnType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func2 = new TableFunc2
+
+ val result = in
+ .join(func2('c) as ('name, 'len))
+ .select('c, 'name, 'len)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,4\n" + "Jack#22,22,2\n" + "John#19,John,4\n" +
+ "John#19,19,2\n" + "Anna#44,Anna,4\n" + "Anna#44,44,2\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testHierarchyType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val hierarchy = new HierarchyTableFunction
+ val result = in
+ .join(hierarchy('c) as ('name, 'adult, 'len))
+ .select('c, 'name, 'adult, 'len)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,true,22\n" + "John#19,John,false,19\n" +
+ "Anna#44,Anna,true,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testPojoType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+
+ val pojo = new PojoTableFunc()
+ val result = in
+ .join(pojo('c))
+ .where('age > 20)
+ .select('c, 'name, 'age)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,22\n" + "Anna#44,Anna,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunction(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func1 = new TableFunc1
+
+ val result = in
+ .join(func1('c.substring(2)) as 's)
+ .select('c, 's)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,ack\n" + "Jack#22,22\n" + "John#19,ohn\n" + "John#19,19\n" +
+ "Anna#44,nna\n" + "Anna#44,44\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunctionInCondition(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func0 = new TableFunc0
+
+ val result = in
+ .join(func0('c))
+ .where(Func18('name, "J") && (Func1('a) < 3) && Func1('age) > 20)
+ .select('c, 'name, 'age)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "Jack#22,Jack,22"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLongAndTemporalTypes(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func0 = new JavaTableFunc0
+
+ val result = in
+ .where('a === 1)
+ .select(Date.valueOf("1990-10-14") as 'x,
+ 1000L as 'y,
+ Timestamp.valueOf("1990-10-14 12:10:10") as 'z)
+ .join(func0('x, 'y, 'z) as 's)
+ .select('s)
+ .toDataSet[Row]
+
+ val results = result.collect()
+ val expected = "1000\n" + "655906210000\n" + "7591\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithParameter(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val richTableFunc1 = new RichTableFunc1
+ tEnv.registerFunction("RichTableFunc1", richTableFunc1)
+ UserDefinedFunctionTestUtils.setJobParameters(env, Map("word_separator" -> "#"))
+
+ val result = testData(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(richTableFunc1('c) as 's)
+ .select('a, 's)
+
+ val expected = "1,Jack\n" + "1,22\n" + "2,John\n" + "2,19\n" + "3,Anna\n" + "3,44"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedTableFunctionWithScalarFunctionWithParameters(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val richTableFunc1 = new RichTableFunc1
+ tEnv.registerFunction("RichTableFunc1", richTableFunc1)
+ val richFunc2 = new RichFunc2
+ tEnv.registerFunction("RichFunc2", richFunc2)
+ UserDefinedFunctionTestUtils.setJobParameters(
+ env,
+ Map("word_separator" -> "#", "string.value" -> "test"))
+
+ val result = CollectionDataSets.getSmall3TupleDataSet(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .join(richTableFunc1(richFunc2('c)) as 's)
+ .select('a, 's)
+
+ val expected = "1,Hi\n1,test\n2,Hello\n2,test\n3,Hello world\n3,test"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableFunctionConstructorWithParams(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val in = testData(env).toTable(tableEnv).as('a, 'b, 'c)
+ val func30 = new TableFunc3(null)
+ val func31 = new TableFunc3("OneConf_")
+ val func32 = new TableFunc3("TwoConf_")
+
+ val result = in
+ .join(func30('c) as('d, 'e))
+ .select('c, 'd, 'e)
+ .join(func31('c) as ('f, 'g))
+ .select('c, 'd, 'e, 'f, 'g)
+ .join(func32('c) as ('h, 'i))
+ .select('c, 'd, 'f, 'h, 'e, 'g, 'i)
+ .toDataSet[Row]
+
+ val results = result.collect()
+
+ val expected = "Anna#44,Anna,OneConf_Anna,TwoConf_Anna,44,44,44\n" +
+ "Jack#22,Jack,OneConf_Jack,TwoConf_Jack,22,22,22\n" +
+ "John#19,John,OneConf_John,TwoConf_John,19,19,19\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableFunctionWithVariableArguments(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val varArgsFunc0 = new VarArgsFunc0
+ tableEnv.registerFunction("VarArgsFunc0", varArgsFunc0)
+
+ val result = testData(env)
+ .toTable(tableEnv, 'a, 'b, 'c)
+ .select('c)
+ .join(varArgsFunc0("1", "2", 'c))
+
+ val expected = "Anna#44,1\n" +
+ "Anna#44,2\n" +
+ "Anna#44,Anna#44\n" +
+ "Jack#22,1\n" +
+ "Jack#22,2\n" +
+ "Jack#22,Jack#22\n" +
+ "John#19,1\n" +
+ "John#19,2\n" +
+ "John#19,John#19\n" +
+ "nosharp,1\n" +
+ "nosharp,2\n" +
+ "nosharp,nosharp"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+
+ // Test for empty cases
+ val result0 = testData(env)
+ .toTable(tableEnv, 'a, 'b, 'c)
+ .select('c)
+ .join(varArgsFunc0())
+ val results0 = result0.toDataSet[Row].collect()
+ assertTrue(results0.isEmpty)
+ }
+
+ private def testData(
+ env: ExecutionEnvironment)
+ : DataSet[(Int, Long, String)] = {
+
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Jack#22"))
+ data.+=((2, 2L, "John#19"))
+ data.+=((3, 2L, "Anna#44"))
+ data.+=((4, 3L, "nosharp"))
+ env.fromCollection(data)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/GroupWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/GroupWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/GroupWindowITCase.scala
new file mode 100644
index 0000000..718bc5c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/GroupWindowITCase.scala
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.runtime.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class GroupWindowITCase(
+ mode: TestExecutionMode,
+ configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ val data = List(
+ (1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"),
+ (2L, 2, 2d, 2f, new BigDecimal("2"), "Hallo"),
+ (3L, 2, 2d, 2f, new BigDecimal("2"), "Hello"),
+ (7L, 3, 3d, 3f, new BigDecimal("3"), "Hello"),
+ (4L, 5, 5d, 5f, new BigDecimal("5"), "Hello"),
+ (16L, 4, 4d, 4f, new BigDecimal("4"), "Hello world"),
+ (8L, 3, 3d, 3f, new BigDecimal("3"), "Hello world"))
+
+ @Test(expected = classOf[UnsupportedOperationException])
+ def testAllEventTimeTumblingWindowOverCount(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ // Count tumbling non-grouping window on event-time are currently not supported
+ table
+ .window(Tumble over 2.rows on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+ .toDataSet[Row]
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverCount(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 2.rows on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.sum, 'int.count, 'int.max, 'int.min, 'int.avg,
+ 'double.sum, 'double.count, 'double.max, 'double.min, 'double.avg,
+ 'float.sum, 'float.count, 'float.max, 'float.min, 'float.avg,
+ 'bigdec.sum, 'bigdec.count, 'bigdec.max, 'bigdec.min, 'bigdec.avg)
+
+ val expected = "Hello,7,2,5,2,3,7.0,2,5.0,2.0,3.5,7.0,2,5.0,2.0,3.5,7,2,5,2,3.5\n" +
+ "Hello world,7,2,4,3,3,7.0,2,4.0,3.0,3.5,7.0,2,4.0,3.0,3.5,7,2,4,3,3.5\n"
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeTumblingGroupWindowOverTime(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.sum, 'w.start, 'w.end)
+
+ val expected = "Hello world,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
+ "Hello world,4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n" +
+ "Hello,7,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello,3,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
+ "Hallo,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllEventTimeTumblingWindowOverTime(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.sum, 'w.start, 'w.end)
+
+ val expected = "10,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "6,1970-01-01 00:00:00.005,1970-01-01 00:00:00.01\n" +
+ "4,1970-01-01 00:00:00.015,1970-01-01 00:00:00.02\n"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSessionGroupWindow(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+ val windowedTable = table
+ .window(Session withGap 7.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'string.count, 'w.start, 'w.end)
+
+ val results = windowedTable.toDataSet[Row].collect()
+
+ val expected = "Hallo,1,1970-01-01 00:00:00.002,1970-01-01 00:00:00.009\n" +
+ "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.015\n" +
+ "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.023\n" +
+ "Hello,3,1970-01-01 00:00:00.003,1970-01-01 00:00:00.014\n" +
+ "Hi,1,1970-01-01 00:00:00.001,1970-01-01 00:00:00.008"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllEventTimeSessionGroupWindow(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val results =table
+ .window(Session withGap 2.milli on 'long as 'w)
+ .groupBy('w)
+ .select('string.count, 'w.start, 'w.end).toDataSet[Row].collect()
+
+ val expected = "4,1970-01-01 00:00:00.001,1970-01-01 00:00:00.006\n" +
+ "2,1970-01-01 00:00:00.007,1970-01-01 00:00:00.01\n" +
+ "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.018"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testMultiGroupWindow(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+ table
+ .window(Tumble over 5.milli on 'long as 'w)
+ .groupBy('w, 'string)
+ .select('string, 'int.count)
+ .window( Slide over 5.milli every 1.milli on 'int as 'w2)
+ .groupBy('w2)
+ .select('string)
+ .toDataSet[Row]
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Sliding windows
+ // ----------------------------------------------------------------------------------------------
+
+ @Test(expected = classOf[UnsupportedOperationException])
+ def testAllEventTimeSlidingGroupWindowOverCount(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ // Count sliding group window on event-time are currently not supported
+ table
+ .window(Slide over 2.rows every 2.rows on 'long as 'w)
+ .groupBy('w)
+ .select('int.count)
+ .toDataSet[Row]
+ }
+
+ @Test
+ def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 2.milli on 'long as 'w)
+ .groupBy('w)
+ .select('int.count, 'w.start, 'w.end)
+
+ val expected =
+ "1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
+ "1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
+ "1,1970-01-01 00:00:00.014,1970-01-01 00:00:00.019\n" +
+ "1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
+ "2,1969-12-31 23:59:59.998,1970-01-01 00:00:00.003\n" +
+ "2,1970-01-01 00:00:00.006,1970-01-01 00:00:00.011\n" +
+ "3,1970-01-01 00:00:00.002,1970-01-01 00:00:00.007\n" +
+ "3,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
+ "4,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 10.milli every 5.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
+ "Hello world,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
+ "Hello world,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
+ "Hello world,1,1970-01-01 00:00:00.01,1970-01-01 00:00:00.02\n" +
+ "Hello world,1,1970-01-01 00:00:00.015,1970-01-01 00:00:00.025\n" +
+ "Hello,1,1970-01-01 00:00:00.005,1970-01-01 00:00:00.015\n" +
+ "Hello,2,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
+ "Hello,3,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01\n" +
+ "Hi,1,1969-12-31 23:59:59.995,1970-01-01 00:00:00.005\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.01"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 4.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello world,1,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
+ "Hello world,1,1970-01-01 00:00:00.008,1970-01-01 00:00:00.013\n" +
+ "Hello world,1,1970-01-01 00:00:00.012,1970-01-01 00:00:00.017\n" +
+ "Hello world,1,1970-01-01 00:00:00.016,1970-01-01 00:00:00.021\n" +
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello,2,1970-01-01 00:00:00.004,1970-01-01 00:00:00.009\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingFullPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 5.milli every 10.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hello,2,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.005"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testEventTimeSlidingGroupWindowOverTimeNonOverlappingSplitPane(): Unit = {
+ // please keep this test in sync with the DataStream variant
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env
+ .fromCollection(data)
+ .toTable(tEnv, 'long, 'int, 'double, 'float, 'bigdec, 'string)
+
+ val windowedTable = table
+ .window(Slide over 3.milli every 10.milli on 'long as 'w)
+ .groupBy('string, 'w)
+ .select('string, 'int.count, 'w.start, 'w.end)
+
+ val expected =
+ "Hallo,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003\n" +
+ "Hi,1,1970-01-01 00:00:00.0,1970-01-01 00:00:00.003"
+
+ val results = windowedTable.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/JoinITCase.scala
new file mode 100644
index 0000000..ddf622c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/JoinITCase.scala
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.Literal
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.utils.TableFunc2
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class JoinITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testJoin(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithFilter(): Unit = {
+
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e && 'b < 2).select('c, 'g)
+
+ val expected = "Hi,Hallo\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithJoinFilter(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e && 'a < 6).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('b === 'e && 'a < 6 && 'h < 'b).select('c, 'g)
+
+ val results = joinT.toDataSet[Row].collect()
+ val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).filter('a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
+ "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithAggregation(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ // use different table env in order to let tmp table ids are the same
+ val tEnv2 = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).where('a === 'd).select('g.count)
+
+ val expected = "6"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithGroupedAggregation(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2)
+ .where('a === 'd)
+ .groupBy('a, 'd)
+ .select('b.sum, 'g.count)
+
+ val expected = "6,3\n" + "4,2\n" + "1,1"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinPushThroughJoin(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'j, 'k, 'l)
+
+ val joinT = ds1.join(ds2)
+ .where(Literal(true))
+ .join(ds3)
+ .where('a === 'd && 'e === 'k)
+ .select('a, 'f, 'l)
+
+ val expected = "2,1,Hello\n" + "2,1,Hello world\n" + "1,0,Hi"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithDisjunctivePred(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).filter('a === 'd && ('b === 'e || 'b === 'e - 10)).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" +
+ "Hello,Hallo Welt\n" +
+ "I am fine.,IJK"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithExpressionPreds(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.join(ds2).filter('b === 'h + 1 && 'a - 1 === 'd + 2).select('c, 'g)
+
+ val expected = "I am fine.,Hallo Welt\n" +
+ "Luke Skywalker,Hallo Welt wie gehts?\n" +
+ "Luke Skywalker,ABC\n" +
+ "Comment#2,HIJ\n" +
+ "Comment#2,IJK"
+ val results = joinT.toDataSet[Row] collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLeftJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.leftOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
+ "Hello world,ABC\n" + "Hello world, how are you?,null\n" + "I am fine.,HIJ\n" +
+ "I am fine.,IJK\n" + "Luke Skywalker,null\n" + "Comment#1,null\n" + "Comment#2,null\n" +
+ "Comment#3,null\n" + "Comment#4,null\n" + "Comment#5,null\n" + "Comment#6,null\n" +
+ "Comment#7,null\n" + "Comment#8,null\n" + "Comment#9,null\n" + "Comment#10,null\n" +
+ "Comment#11,null\n" + "Comment#12,null\n" + "Comment#13,null\n" + "Comment#14,null\n" +
+ "Comment#15,null\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.rightOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
+ "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
+ "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
+ "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFullOuterJoinWithMultipleKeys(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+
+ val joinT = ds1.fullOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
+ "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
+ "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
+ "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n" + "Luke Skywalker,null\n" +
+ "Comment#1,null\n" + "Comment#2,null\n" + "Comment#3,null\n" + "Comment#4,null\n" +
+ "Comment#5,null\n" + "Comment#6,null\n" + "Comment#7,null\n" + "Comment#8,null\n" +
+ "Comment#9,null\n" + "Comment#10,null\n" + "Comment#11,null\n" + "Comment#12,null\n" +
+ "Comment#13,null\n" + "Comment#14,null\n" + "Comment#15,null\n" +
+ "Hello world, how are you?,null\n"
+ val results = joinT.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUDTFJoinOnTuples(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List("hi#world", "how#are#you")
+
+ val ds1 = env.fromCollection(data).toTable(tEnv, 'a)
+ val func2 = new TableFunc2
+
+ val joinDs = ds1.join(func2('a) as ('name, 'len))
+
+ val results = joinDs.toDataSet[Row].collect()
+ val expected = Seq(
+ "hi#world,hi,2",
+ "hi#world,world,5",
+ "how#are#you,how,3",
+ "how#are#you,are,3",
+ "how#are#you,you,3").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SetOperatorsITCase.scala
new file mode 100644
index 0000000..39b1e7b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SetOperatorsITCase.scala
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+import scala.util.Random
+
+@RunWith(classOf[Parameterized])
+class SetOperatorsITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testUnionAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
+
+ val unionDs = ds1.unionAll(ds2).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
+
+ val unionDs = ds1.union(ds2).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTernaryUnionAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val unionDs = ds1.unionAll(ds2).unionAll(ds3).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" +
+ "Hi\n" + "Hello\n" + "Hello world\n" +
+ "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTernaryUnion(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+
+ val unionDs = ds1.union(ds2).union(ds3).select('c)
+
+ val results = unionDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMinusAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
+
+ val minusDs = ds1.unionAll(ds1).unionAll(ds1)
+ .minusAll(ds2.unionAll(ds2)).select('c)
+
+ val results = minusDs.toDataSet[Row].collect()
+ val expected = "Hi\n" +
+ "Hello\n" + "Hello world\n" +
+ "Hello\n" + "Hello world\n" +
+ "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMinus(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
+
+ val minusDs = ds1.unionAll(ds1).unionAll(ds1)
+ .minus(ds2.unionAll(ds2)).select('c)
+
+ val results = minusDs.toDataSet[Row].collect()
+ val expected = "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMinusDifferentFieldNames(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'd, 'e, 'f)
+
+ val minusDs = ds1.unionAll(ds1).unionAll(ds1)
+ .minus(ds2.unionAll(ds2)).select('c)
+
+ val results = minusDs.toDataSet[Row].collect()
+ val expected = "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersect(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Hi"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((3, 2L, "Hello world!"))
+ val ds2 = env.fromCollection(Random.shuffle(data)).toTable(tEnv, 'a, 'b, 'c)
+
+ val intersectDS = ds1.intersect(ds2).select('c).toDataSet[Row]
+
+ val results = intersectDS.collect()
+
+ val expected = "Hi\n" + "Hello\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data1 = new mutable.MutableList[Int]
+ data1 += (1, 1, 1, 2, 2)
+ val data2 = new mutable.MutableList[Int]
+ data2 += (1, 2, 2, 2, 3)
+ val ds1 = env.fromCollection(data1).toTable(tEnv, 'c)
+ val ds2 = env.fromCollection(data2).toTable(tEnv, 'c)
+
+ val intersectDS = ds1.intersectAll(ds2).select('c).toDataSet[Row]
+
+ val expected = "1\n2\n2"
+ val results = intersectDS.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectWithDifferentFieldNames(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'e, 'f, 'g)
+
+ val intersectDs = ds1.intersect(ds2).select('c)
+
+ val results = intersectDs.toDataSet[Row].collect()
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectWithScalarExpression(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a + 1, 'b, 'c)
+ val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a + 1, 'b, 'c)
+
+ val intersectDs = ds1.intersect(ds2)
+
+ val results = intersectDs.toDataSet[Row].collect()
+ val expected = "2,1,Hi\n" + "3,2,Hello\n" + "4,2,Hello world\n"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SortITCase.scala
new file mode 100644
index 0000000..568fad0
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/SortITCase.scala
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.api.scala.{ExecutionEnvironment, _}
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.SortTestUtils._
+import org.apache.flink.table.runtime.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+@RunWith(classOf[Parameterized])
+class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ private def getExecutionEnvironment = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ // set the parallelism explicitly to make sure the query is executed in
+ // a distributed manner
+ env.setParallelism(3)
+ env
+ }
+
+ @Test
+ def testOrderByDesc(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.desc)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ - x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByAsc(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.asc)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByMultipleFieldsDifferentDirections(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_2.asc, '_1.desc)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ (x.productElement(1).asInstanceOf[Long], - x.productElement(0).asInstanceOf[Int]) )
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ def rowOrdering = Ordering.by((r : Row) => {
+ // ordering for this tuple will fall into the previous defined tupleOrdering,
+ // so we just need to return the field by their defining sequence
+ (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
+ })
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(rowOrdering)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByOffset(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.asc).limit(3)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings, 3, 21)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByOffsetAndFetch(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.desc).limit(3, 5)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ - x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings, 3, 8)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByFetch(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ val t = ds.toTable(tEnv).orderBy('_1.asc).limit(0, 5)
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
+ // squash all rows inside a partition into one element
+ val results = t.toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ implicit def rowOrdering = Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int])
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+}
[34/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala
deleted file mode 100644
index 218cc89..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/validation/UserDefinedTableFunctionValidationTest.scala
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.stream.table.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils._
-import org.apache.flink.table.utils._
-import org.junit.Assert.{assertTrue, fail}
-import org.junit.Test
-
-class UserDefinedTableFunctionValidationTest extends TableTestBase {
-
- @Test
- def testRegisterFunctionException(): Unit ={
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]('a, 'b, 'c)
-
- // check scala object is forbidden
- expectExceptionThrown(
- util.tableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
- expectExceptionThrown(
- util.javaTableEnv.registerFunction("func3", ObjectTableFunction), "Scala object")
-
- expectExceptionThrown(t.join(ObjectTableFunction('a, 1)), "Scala object")
- }
-
- @Test
- def testInvalidTableFunctions(): Unit = {
- val util = streamTestUtil()
-
- val func1 = new TableFunc1
- util.javaTableEnv.registerFunction("func1", func1)
-
- // table function call select
- expectExceptionThrown(
- func1('c).select("f0"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call select
- expectExceptionThrown(
- func1('c).select('f0),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call writeToSink
- expectExceptionThrown(
- func1('c).writeToSink(null),
- "Cannot translate a query with an unbounded table function call."
- )
-
- // table function call distinct
- expectExceptionThrown(
- func1('c).distinct(),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call filter
- expectExceptionThrown(
- func1('c).filter('f0 === "?"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call filter
- expectExceptionThrown(
- func1('c).filter("f0 = '?'"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call limit
- expectExceptionThrown(
- func1('c).orderBy('f0).limit(3),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call limit
- expectExceptionThrown(
- func1('c).orderBy('f0).limit(0, 3),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call orderBy
- expectExceptionThrown(
- func1('c).orderBy("f0"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call orderBy
- expectExceptionThrown(
- func1('c).orderBy('f0),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call where
- expectExceptionThrown(
- func1('c).where("f0 = '?'"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- // table function call where
- expectExceptionThrown(
- func1('c).where('f0 === "?"),
- "TableFunction can only be used in join and leftOuterJoin."
- )
-
- }
-
- @Test
- def testInvalidTableFunction(): Unit = {
- val util = streamTestUtil()
- val t = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-
- //=================== check scala object is forbidden =====================
- // Scala table environment register
- expectExceptionThrown(util.addFunction("udtf", ObjectTableFunction), "Scala object")
- // Java table environment register
- expectExceptionThrown(
- util.tableEnv.registerFunction("udtf", ObjectTableFunction), "Scala object")
- // Scala Table API directly call
- expectExceptionThrown(t.join(ObjectTableFunction('a, 1)), "Scala object")
-
-
- //============ throw exception when table function is not registered =========
- // Java Table API call
- expectExceptionThrown(
- t.join(new Table(util.tableEnv, "nonexist(a)")
- ), "Undefined function: NONEXIST")
- // SQL API call
- expectExceptionThrown(
- util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(nonexist(a))"),
- "No match found for function signature nonexist(<NUMERIC>)")
-
-
- //========= throw exception when the called function is a scalar function ====
- util.tableEnv.registerFunction("func0", Func0)
-
- // Java Table API call
- expectExceptionThrown(
- t.join(new Table(util.tableEnv, "func0(a)")),
- "only accept String that define table function",
- classOf[TableException])
- // SQL API call
- // NOTE: it doesn't throw an exception but an AssertionError, maybe a Calcite bug
- expectExceptionThrown(
- util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func0(a))"),
- null,
- classOf[AssertionError])
-
- //========== throw exception when the parameters is not correct ===============
- // Java Table API call
- util.addFunction("func2", new TableFunc2)
- expectExceptionThrown(
- t.join(new Table(util.tableEnv, "func2(c, c)")),
- "Given parameters of function 'FUNC2' do not match any signature")
- // SQL API call
- expectExceptionThrown(
- util.tableEnv.sql("SELECT * FROM MyTable, LATERAL TABLE(func2(c, c))"),
- "No match found for function signature func2(<CHARACTER>, <CHARACTER>)")
- }
-
- // ----------------------------------------------------------------------------------------------
-
- private def expectExceptionThrown(
- function: => Unit,
- keywords: String,
- clazz: Class[_ <: Throwable] = classOf[ValidationException])
- : Unit = {
- try {
- function
- fail(s"Expected a $clazz, but no exception is thrown.")
- } catch {
- case e if e.getClass == clazz =>
- if (keywords != null) {
- assertTrue(
- s"The exception message '${e.getMessage}' doesn't contain keyword '$keywords'",
- e.getMessage.contains(keywords))
- }
- case e: Throwable => fail(s"Expected throw ${clazz.getSimpleName}, but is $e.")
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamTestData.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamTestData.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamTestData.scala
deleted file mode 100644
index 6745039..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/utils/StreamTestData.scala
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.utils
-
-import org.apache.flink.api.scala._
-import scala.collection.mutable
-import org.apache.flink.streaming.api.scala.DataStream
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-
-object StreamTestData {
-
- def getSmall3TupleDataStream(env: StreamExecutionEnvironment): DataStream[(Int, Long, String)] = {
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Hi"))
- data.+=((2, 2L, "Hello"))
- data.+=((3, 2L, "Hello world"))
- env.fromCollection(data)
- }
-
- def get3TupleDataStream(env: StreamExecutionEnvironment): DataStream[(Int, Long, String)] = {
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Hi"))
- data.+=((2, 2L, "Hello"))
- data.+=((3, 2L, "Hello world"))
- data.+=((4, 3L, "Hello world, how are you?"))
- data.+=((5, 3L, "I am fine."))
- data.+=((6, 3L, "Luke Skywalker"))
- data.+=((7, 4L, "Comment#1"))
- data.+=((8, 4L, "Comment#2"))
- data.+=((9, 4L, "Comment#3"))
- data.+=((10, 4L, "Comment#4"))
- data.+=((11, 5L, "Comment#5"))
- data.+=((12, 5L, "Comment#6"))
- data.+=((13, 5L, "Comment#7"))
- data.+=((14, 5L, "Comment#8"))
- data.+=((15, 5L, "Comment#9"))
- data.+=((16, 6L, "Comment#10"))
- data.+=((17, 6L, "Comment#11"))
- data.+=((18, 6L, "Comment#12"))
- data.+=((19, 6L, "Comment#13"))
- data.+=((20, 6L, "Comment#14"))
- data.+=((21, 6L, "Comment#15"))
- env.fromCollection(data)
- }
-
- def get5TupleDataStream(env: StreamExecutionEnvironment):
- DataStream[(Int, Long, Int, String, Long)] = {
-
- val data = new mutable.MutableList[(Int, Long, Int, String, Long)]
- data.+=((1, 1L, 0, "Hallo", 1L))
- data.+=((2, 2L, 1, "Hallo Welt", 2L))
- data.+=((2, 3L, 2, "Hallo Welt wie", 1L))
- data.+=((3, 4L, 3, "Hallo Welt wie gehts?", 2L))
- data.+=((3, 5L, 4, "ABC", 2L))
- data.+=((3, 6L, 5, "BCD", 3L))
- data.+=((4, 7L, 6, "CDE", 2L))
- data.+=((4, 8L, 7, "DEF", 1L))
- data.+=((4, 9L, 8, "EFG", 1L))
- data.+=((4, 10L, 9, "FGH", 2L))
- data.+=((5, 11L, 10, "GHI", 1L))
- data.+=((5, 12L, 11, "HIJ", 3L))
- data.+=((5, 13L, 12, "IJK", 3L))
- data.+=((5, 14L, 13, "JKL", 2L))
- data.+=((5, 15L, 14, "KLM", 2L))
- env.fromCollection(data)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala
deleted file mode 100644
index af8aff0..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/validation/TableEnvironmentValidationTest.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.validation
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableException
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class TableEnvironmentValidationTest extends TableTestBase {
- def testInvalidTimeAttributes(): Unit = {
- val util = streamTestUtil()
- // table definition makes no sense
- util.addTable[(Long, Int, String, Int, Long)]('a.rowtime.rowtime, 'b, 'c, 'd, 'e)
- }
-
- @Test(expected = classOf[TableException])
- def testInvalidProctimeAttribute(): Unit = {
- val util = streamTestUtil()
- // cannot replace an attribute with proctime
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b.proctime, 'c, 'd, 'e)
- }
-
- @Test(expected = classOf[TableException])
- def testRowtimeAttributeReplaceFieldOfInvalidType(): Unit = {
- val util = streamTestUtil()
- // cannot replace a non-time attribute with rowtime
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c.rowtime, 'd, 'e)
- }
-
- @Test(expected = classOf[TableException])
- def testRowtimeAndInvalidProctimeAttribute(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'pt.proctime)
- }
-
- @Test(expected = classOf[TableException])
- def testOnlyOneRowtimeAttribute1(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a.rowtime, 'b, 'c, 'd, 'e, 'rt.rowtime)
- }
-
- @Test(expected = classOf[TableException])
- def testOnlyOneProctimeAttribute1(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt1.proctime, 'pt2.proctime)
- }
-
- @Test(expected = classOf[TableException])
- def testRowtimeAttributeUsedName(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'a.rowtime)
- }
-
- @Test(expected = classOf[TableException])
- def testProctimeAttributeUsedName(): Unit = {
- val util = streamTestUtil()
- util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'b.proctime)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala
deleted file mode 100644
index e275d75..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/validation/TableSchemaValidationTest.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.api.scala.validation
-
-import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
-import org.apache.flink.table.api.{TableException, TableSchema}
-import org.apache.flink.table.utils.TableTestBase
-import org.junit.Test
-
-class TableSchemaValidationTest extends TableTestBase {
-
- @Test(expected = classOf[TableException])
- def testInvalidSchema() {
- val fieldNames = Array("a", "b", "c")
- val typeInfos: Array[TypeInformation[_]] = Array(
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO)
- new TableSchema(fieldNames, typeInfos)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala
new file mode 100644
index 0000000..820de08
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.junit.Assert.assertEquals
+import org.junit._
+
+class ExplainTest extends StreamingMultipleProgramsTestBase {
+
+ private val testFilePath = this.getClass.getResource("/").getFile
+
+ @Test
+ def testFilter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements((1, "hello"))
+ .toTable(tEnv, 'a, 'b)
+ .filter("a % 2 = 0")
+
+ val result = replaceString(tEnv.explain(table))
+
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testFilterStream0.out").mkString
+ val expect = replaceString(source)
+ assertEquals(result, expect)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table = table1.unionAll(table2)
+
+ val result = replaceString(tEnv.explain(table))
+
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testUnionStream0.out").mkString
+ val expect = replaceString(source)
+ assertEquals(result, expect)
+ }
+
+ def replaceString(s: String): String = {
+ /* Stage {id} is ignored, because id keeps incrementing in test class
+ * while StreamExecutionEnvironment is up
+ */
+ s.replaceAll("\\r\\n", "\n").replaceAll("Stage \\d+", "")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala
new file mode 100644
index 0000000..0943ea6
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream
+
+import java.lang.{Integer => JInt, Long => JLong}
+
+import org.apache.flink.api.java.tuple.{Tuple5 => JTuple5}
+import org.apache.flink.api.java.typeutils.TupleTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.TimeCharacteristic
+import org.apache.flink.streaming.api.datastream.DataStream
+import org.apache.flink.streaming.api.environment.{StreamExecutionEnvironment => JStreamExecEnv}
+import org.apache.flink.table.api.java.{StreamTableEnvironment => JStreamTableEnv}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, Types}
+import org.apache.flink.table.utils.TableTestUtil.{binaryNode, streamTableNode, term, unaryNode}
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+import org.mockito.Mockito.{mock, when}
+
+class StreamTableEnvironmentTest extends TableTestBase {
+
+ @Test
+ def testSqlWithoutRegistering(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]("tableName", 'a, 'b, 'c)
+
+ val sqlTable = util.tableEnv.sql(s"SELECT a, b, c FROM $table WHERE b > 12")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a, b, c"),
+ term("where", ">(b, 12)"))
+
+ util.verifyTable(sqlTable, expected)
+
+ val table2 = util.addTable[(Long, Int, String)]('d, 'e, 'f)
+
+ val sqlTable2 = util.tableEnv.sql(s"SELECT d, e, f FROM $table2 " +
+ s"UNION ALL SELECT a, b, c FROM $table")
+
+ val expected2 = binaryNode(
+ "DataStreamUnion",
+ streamTableNode(1),
+ streamTableNode(0),
+ term("union all", "d, e, f"))
+
+ util.verifyTable(sqlTable2, expected2)
+ }
+
+ @Test
+ def testProctimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ // cannot replace an attribute with proctime
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime)
+ }
+
+ @Test
+ def testReplacedRowtimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e)
+ }
+
+ @Test
+ def testAppendedRowtimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime)
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttribute1(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'rt.rowtime, 'pt.proctime)
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttribute2(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt.proctime, 'rt.rowtime)
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttribute3(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'e, 'pt.proctime)
+ }
+
+ @Test
+ def testProctimeAttributeParsed(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime")
+ }
+
+ @Test
+ def testReplacingRowtimeAttributeParsed(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a.rowtime, b, c, d, e")
+ }
+
+ @Test
+ def testAppedingRowtimeAttributeParsed(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a, b, c, d, e, rt.rowtime")
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttributeParsed1(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "a, b, c, d, e, pt.proctime, rt.rowtime")
+ }
+
+ @Test
+ def testRowtimeAndProctimeAttributeParsed2(): Unit = {
+ val (jTEnv, ds) = prepareSchemaExpressionParser
+ jTEnv.fromDataStream(ds, "rt.rowtime, b, c, d, e, pt.proctime")
+ }
+
+ private def prepareSchemaExpressionParser:
+ (JStreamTableEnv, DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]) = {
+
+ val jStreamExecEnv = mock(classOf[JStreamExecEnv])
+ when(jStreamExecEnv.getStreamTimeCharacteristic).thenReturn(TimeCharacteristic.EventTime)
+ val jTEnv = TableEnvironment.getTableEnvironment(jStreamExecEnv)
+
+ val sType = new TupleTypeInfo(Types.LONG, Types.INT, Types.STRING, Types.INT, Types.LONG)
+ .asInstanceOf[TupleTypeInfo[JTuple5[JLong, JInt, String, JInt, JLong]]]
+ val ds = mock(classOf[DataStream[JTuple5[JLong, JInt, String, JInt, JLong]]])
+ when(ds.getType).thenReturn(sType)
+
+ (jTEnv, ds)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentValidationTest.scala
new file mode 100644
index 0000000..1fd58cc
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentValidationTest.scala
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.{TableEnvironment, TableException}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.stream.TimeAttributesITCase.TimestampWithEqualWatermark
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class StreamTableEnvironmentValidationTest extends TableTestBase {
+
+ @Test(expected = classOf[TableException])
+ def testInvalidTimeAttributes(): Unit = {
+ val util = streamTestUtil()
+ // table definition makes no sense
+ util.addTable[(Long, Int, String, Int, Long)]('a.rowtime.rowtime, 'b, 'c, 'd, 'e)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testInvalidProctimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ // cannot replace an attribute with proctime
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b.proctime, 'c, 'd, 'e)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeAttributeReplaceFieldOfInvalidType(): Unit = {
+ val util = streamTestUtil()
+ // cannot replace a non-time attribute with rowtime
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c.rowtime, 'd, 'e)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeAndInvalidProctimeAttribute(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('rt.rowtime, 'b, 'c, 'd, 'pt.proctime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testOnlyOneRowtimeAttribute1(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a.rowtime, 'b, 'c, 'd, 'e, 'rt.rowtime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testOnlyOneProctimeAttribute1(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'pt1.proctime, 'pt2.proctime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testRowtimeAttributeUsedName(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'a.rowtime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testProctimeAttributeUsedName(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Long, Int, String, Int, Long)]('a, 'b, 'c, 'd, 'e, 'b.proctime)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testAsWithToManyFields(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]('a, 'b, 'c, 'd)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testAsWithAmbiguousFields(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]('a, 'b, 'b)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testOnlyFieldRefInAs(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]('a, 'b as 'c, 'd)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testInvalidTimeCharacteristic(): Unit = {
+ val data = List((1L, 1, 1d, 1f, new BigDecimal("1"), "Hi"))
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val stream = env
+ .fromCollection(data)
+ .assignTimestampsAndWatermarks(new TimestampWithEqualWatermark())
+ stream.toTable(tEnv, 'rowtime.rowtime, 'int, 'double, 'float, 'bigdec, 'string)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala
new file mode 100644
index 0000000..70d1d21
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.typeutils.CaseClassTypeInfo
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.AggFunctionCall
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.utils.TableTestUtil.{streamTableNode, term, unaryNode}
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert.{assertEquals, assertTrue}
+import org.junit.{Ignore, Test}
+
+class AggregateTest extends TableTestBase {
+
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)](
+ "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
+
+ @Test
+ def testGroupbyWithoutWindow() = {
+ val sql = "SELECT COUNT(a) FROM MyTable GROUP BY b"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "b", "a")
+ ),
+ term("groupBy", "b"),
+ term("select", "b", "COUNT(a) AS EXPR$0")
+ ),
+ term("select", "EXPR$0")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testDistinct(): Unit = {
+ val sql = "SELECT DISTINCT a, b, c FROM MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a, b, c")
+ ),
+ term("groupBy", "a, b, c"),
+ term("select", "a, b, c")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ // TODO: this query should be optimized to only have a single DataStreamGroupAggregate
+ // TODO: reopen this until FLINK-7144 fixed
+ @Ignore
+ @Test
+ def testDistinctAfterAggregate(): Unit = {
+ val sql = "SELECT DISTINCT a FROM MyTable GROUP BY a, b, c"
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a")
+ ),
+ term("groupBy", "a"),
+ term("select", "a")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+
+ @Test
+ def testUserDefinedAggregateFunctionWithScalaAccumulator(): Unit = {
+ streamUtil.addFunction("udag", new MyAgg)
+ val call = streamUtil
+ .tableEnv
+ .functionCatalog
+ .lookupFunction("udag", Seq())
+ .asInstanceOf[AggFunctionCall]
+
+ val typeInfo = call.accTypeInfo
+ assertTrue(typeInfo.isInstanceOf[CaseClassTypeInfo[_]])
+ assertEquals(2, typeInfo.getTotalFields)
+ val caseTypeInfo = typeInfo.asInstanceOf[CaseClassTypeInfo[_]]
+ assertEquals(Types.LONG, caseTypeInfo.getTypeAt(0))
+ assertEquals(Types.LONG, caseTypeInfo.getTypeAt(1))
+
+ streamUtil.addFunction("udag2", new MyAgg2)
+ val call2 = streamUtil
+ .tableEnv
+ .functionCatalog
+ .lookupFunction("udag2", Seq())
+ .asInstanceOf[AggFunctionCall]
+
+ val typeInfo2 = call2.accTypeInfo
+ assertTrue(s"actual type: $typeInfo2", typeInfo2.isInstanceOf[RowTypeInfo])
+ assertEquals(2, typeInfo2.getTotalFields)
+ val rowTypeInfo = typeInfo2.asInstanceOf[RowTypeInfo]
+ assertEquals(Types.LONG, rowTypeInfo.getTypeAt(0))
+ assertEquals(Types.INT, rowTypeInfo.getTypeAt(1))
+ }
+}
+
+case class MyAccumulator(var sum: Long, var count: Long)
+
+class MyAgg extends AggregateFunction[Long, MyAccumulator] {
+
+ //Overloaded accumulate method
+ def accumulate(acc: MyAccumulator, value: Long): Unit = {
+ }
+
+ override def createAccumulator(): MyAccumulator = MyAccumulator(0, 0)
+
+ override def getValue(accumulator: MyAccumulator): Long = 1L
+}
+
+class MyAgg2 extends AggregateFunction[Long, Row] {
+
+ def accumulate(acc: Row, value: Long): Unit = {}
+
+ override def createAccumulator(): Row = new Row(2)
+
+ override def getValue(accumulator: Row): Long = 1L
+
+ def getAccumulatorType: TypeInformation[_] = new RowTypeInfo(Types.LONG, Types.INT)
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala
new file mode 100644
index 0000000..52d1320
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{HierarchyTableFunction, PojoTableFunc, TableFunc2, _}
+import org.junit.Test
+
+class CorrelateTest extends TableTestBase {
+
+ @Test
+ def testCrossJoin(): Unit = {
+ val util = streamTestUtil()
+ val func1 = new TableFunc1
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func1", func1)
+
+ val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c)) AS T(s)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "func1($cor0.c)"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery, expected)
+
+ // test overloading
+
+ val sqlQuery2 = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c, '$')) AS T(s)"
+
+ val expected2 = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "func1($cor0.c, '$')"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery2, expected2)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+ val util = streamTestUtil()
+ val func1 = new TableFunc1
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func1", func1)
+
+ val sqlQuery = "SELECT c, s FROM MyTable LEFT JOIN LATERAL TABLE(func1(c)) AS T(s) ON TRUE"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "func1($cor0.c)"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "LEFT")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testCustomType(): Unit = {
+ val util = streamTestUtil()
+ val func2 = new TableFunc2
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func2", func2)
+
+ val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "func2($cor0.c)"),
+ term("function", func2.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
+ "VARCHAR(2147483647) f0, INTEGER f1)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS name", "f1 AS len")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testHierarchyType(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = new HierarchyTableFunction
+ util.addFunction("hierarchy", function)
+
+ val sqlQuery = "SELECT c, T.* FROM MyTable, LATERAL TABLE(hierarchy(c)) AS T(name, adult, len)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "hierarchy($cor0.c)"),
+ term("function", function.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
+ " VARCHAR(2147483647) f0, BOOLEAN f1, INTEGER f2)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS name", "f1 AS adult", "f2 AS len")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testPojoType(): Unit = {
+ val util = streamTestUtil()
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ val function = new PojoTableFunc
+ util.addFunction("pojo", function)
+
+ val sqlQuery = "SELECT c, name, age FROM MyTable, LATERAL TABLE(pojo(c))"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "pojo($cor0.c)"),
+ term("function", function.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c," +
+ " INTEGER age, VARCHAR(2147483647) name)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "name", "age")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testFilter(): Unit = {
+ val util = streamTestUtil()
+ val func2 = new TableFunc2
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func2", func2)
+
+ val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len) " +
+ "WHERE len > 2"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "func2($cor0.c)"),
+ term("function", func2.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, " +
+ "VARCHAR(2147483647) f0, INTEGER f1)"),
+ term("joinType", "INNER"),
+ term("condition", ">($1, 2)")
+ ),
+ term("select", "c", "f0 AS name", "f1 AS len")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testScalarFunction(): Unit = {
+ val util = streamTestUtil()
+ val func1 = new TableFunc1
+ util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+ util.addFunction("func1", func1)
+
+ val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(SUBSTRING(c, 2))) AS T(s)"
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamCorrelate",
+ streamTableNode(0),
+ term("invocation", "func1(SUBSTRING($cor0.c, 2))"),
+ term("function", func1.getClass.getCanonicalName),
+ term("rowType",
+ "RecordType(INTEGER a, BIGINT b, VARCHAR(2147483647) c, VARCHAR(2147483647) f0)"),
+ term("joinType", "INNER")
+ ),
+ term("select", "c", "f0 AS s")
+ )
+
+ util.verifySql(sqlQuery, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala
new file mode 100644
index 0000000..4823903
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.plan.logical._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMerge
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class GroupWindowTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)](
+ "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
+
+ @Test
+ def testTumbleFunction() = {
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+
+ val sql =
+ "SELECT " +
+ " COUNT(*), weightedAvg(c, a) AS wAvg, " +
+ " TUMBLE_START(rowtime, INTERVAL '15' MINUTE), " +
+ " TUMBLE_END(rowtime, INTERVAL '15' MINUTE)" +
+ "FROM MyTable " +
+ "GROUP BY TUMBLE(rowtime, INTERVAL '15' MINUTE)"
+ val expected =
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "rowtime", "c", "a")
+ ),
+ term("window", TumblingGroupWindow('w$, 'rowtime, 900000.millis)),
+ term("select",
+ "COUNT(*) AS EXPR$0, " +
+ "weightedAvg(c, a) AS wAvg, " +
+ "start('w$) AS w$start, " +
+ "end('w$) AS w$end")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testHoppingFunction() = {
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+
+ val sql =
+ "SELECT COUNT(*), weightedAvg(c, a) AS wAvg, " +
+ " HOP_START(proctime, INTERVAL '15' MINUTE, INTERVAL '1' HOUR), " +
+ " HOP_END(proctime, INTERVAL '15' MINUTE, INTERVAL '1' HOUR) " +
+ "FROM MyTable " +
+ "GROUP BY HOP(proctime, INTERVAL '15' MINUTE, INTERVAL '1' HOUR)"
+ val expected =
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "proctime", "c", "a")
+ ),
+ term("window", SlidingGroupWindow('w$, 'proctime, 3600000.millis, 900000.millis)),
+ term("select",
+ "COUNT(*) AS EXPR$0, " +
+ "weightedAvg(c, a) AS wAvg, " +
+ "start('w$) AS w$start, " +
+ "end('w$) AS w$end")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testSessionFunction() = {
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+
+ val sql =
+ "SELECT " +
+ " COUNT(*), weightedAvg(c, a) AS wAvg, " +
+ " SESSION_START(proctime, INTERVAL '15' MINUTE), " +
+ " SESSION_END(proctime, INTERVAL '15' MINUTE) " +
+ "FROM MyTable " +
+ "GROUP BY SESSION(proctime, INTERVAL '15' MINUTE)"
+ val expected =
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "proctime", "c", "a")
+ ),
+ term("window", SessionGroupWindow('w$, 'proctime, 900000.millis)),
+ term("select",
+ "COUNT(*) AS EXPR$0, " +
+ "weightedAvg(c, a) AS wAvg, " +
+ "start('w$) AS w$start, " +
+ "end('w$) AS w$end")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testExpressionOnWindowAuxFunction() = {
+ val sql =
+ "SELECT " +
+ " COUNT(*), " +
+ " TUMBLE_END(rowtime, INTERVAL '15' MINUTE) + INTERVAL '1' MINUTE " +
+ "FROM MyTable " +
+ "GROUP BY TUMBLE(rowtime, INTERVAL '15' MINUTE)"
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "rowtime")
+ ),
+ term("window", TumblingGroupWindow('w$, 'rowtime, 900000.millis)),
+ term("select", "COUNT(*) AS EXPR$0", "start('w$) AS w$start", "end('w$) AS w$end")
+ ),
+ term("select", "EXPR$0", "DATETIME_PLUS(w$end, 60000) AS $f1")
+ )
+
+ streamUtil.verifySql(sql, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala
new file mode 100644
index 0000000..eea395c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala
@@ -0,0 +1,505 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class OverWindowTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)](
+ "MyTable",
+ 'a, 'b, 'c,
+ 'proctime.proctime, 'rowtime.rowtime)
+
+ @Test
+ def testProcTimeBoundedPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN 2 preceding AND " +
+ "CURRENT ROW) as cnt1, " +
+ "sum(a) OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN 2 preceding AND " +
+ "CURRENT ROW) as sum1 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS cnt1, CASE(>(w0$o0, 0), CAST(w0$o1), null) AS sum1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testProcTimeBoundedPartitionedRangeOver() = {
+
+ val sqlQuery =
+ "SELECT a, " +
+ " AVG(c) OVER (PARTITION BY a ORDER BY proctime " +
+ " RANGE BETWEEN INTERVAL '2' HOUR PRECEDING AND CURRENT ROW) AS avgA " +
+ "FROM MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("partitionBy", "a"),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN 7200000 PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "proctime",
+ "COUNT(c) AS w0$o0",
+ "$SUM0(c) AS w0$o1"
+ )
+ ),
+ term("select", "a", "/(CASE(>(w0$o0, 0)", "CAST(w0$o1), null), w0$o0) AS avgA")
+ )
+
+ streamUtil.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testProcTimeBoundedNonPartitionedRangeOver() = {
+
+ val sqlQuery =
+ "SELECT a, " +
+ " COUNT(c) OVER (ORDER BY proctime " +
+ " RANGE BETWEEN INTERVAL '10' SECOND PRECEDING AND CURRENT ROW) " +
+ "FROM MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN 10000 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(c) AS w0$o0")
+ ),
+ term("select", "a", "w0$o0 AS $1")
+ )
+
+ streamUtil.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testProcTimeBoundedNonPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY proctime ROWS BETWEEN 2 preceding AND " +
+ "CURRENT ROW)" +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN 2 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS $1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+
+ @Test
+ def testProcTimeUnboundedPartitionedRangeOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) as cnt1, " +
+ "sum(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) as cnt2 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testProcTimeUnboundedPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND " +
+ "CURRENT ROW) " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ streamTableNode(0),
+ term("partitionBy", "c"),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "b", "c", "proctime", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS $1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRangeOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) as cnt1, " +
+ "sum(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) as cnt2 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "proctime")
+ ),
+ term("orderBy", "proctime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "proctime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testProcTimeUnboundedNonPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND " +
+ "CURRENT ROW) " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ streamTableNode(0),
+ term("orderBy", "proctime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "b", "c", "proctime", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS $1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 5 preceding AND " +
+ "CURRENT ROW) " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN 5 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS $1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedPartitionedRangeOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY rowtime " +
+ "RANGE BETWEEN INTERVAL '1' SECOND preceding AND CURRENT ROW) " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN 1000 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS $1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY rowtime ROWS BETWEEN 5 preceding AND " +
+ "CURRENT ROW) " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN 5 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS $1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeBoundedNonPartitionedRangeOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY rowtime " +
+ "RANGE BETWEEN INTERVAL '1' SECOND preceding AND CURRENT ROW) as cnt1 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN 1000 PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0")
+ ),
+ term("select", "c", "w0$o0 AS $1")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedPartitionedRangeOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt1, " +
+ "sum(a) OVER (PARTITION BY c ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt2 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt1, " +
+ "sum(a) OVER (PARTITION BY c ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt2 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("partitionBy", "c"),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "rowtime",
+ "COUNT(a) AS w0$o0",
+ "$SUM0(a) AS w0$o1"
+ )
+ ),
+ term(
+ "select",
+ "c",
+ "w0$o0 AS cnt1",
+ "CASE(>(w0$o0, 0)",
+ "CAST(w0$o1), null) AS cnt2"
+ )
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedNonPartitionedRangeOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt1, " +
+ "sum(a) OVER (ORDER BY rowtime RANGE UNBOUNDED preceding) as cnt2 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("range", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term("select", "a", "c", "rowtime", "COUNT(a) AS w0$o0", "$SUM0(a) AS w0$o1")
+ ),
+ term("select", "c", "w0$o0 AS cnt1", "CASE(>(w0$o0, 0)", "CAST(w0$o1), null) AS cnt2")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ @Test
+ def testRowTimeUnboundedNonPartitionedRowsOver() = {
+ val sql = "SELECT " +
+ "c, " +
+ "count(a) OVER (ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt1, " +
+ "sum(a) OVER (ORDER BY rowtime ROWS UNBOUNDED preceding) as cnt2 " +
+ "from MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamOverAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "c", "rowtime")
+ ),
+ term("orderBy", "rowtime"),
+ term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
+ term(
+ "select",
+ "a",
+ "c",
+ "rowtime",
+ "COUNT(a) AS w0$o0",
+ "$SUM0(a) AS w0$o1"
+ )
+ ),
+ term(
+ "select",
+ "c",
+ "w0$o0 AS cnt1",
+ "CASE(>(w0$o0, 0)",
+ "CAST(w0$o1), null) AS cnt2"
+ )
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala
new file mode 100644
index 0000000..a5a1319
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class SortTest extends TableTestBase {
+
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c,
+ 'proctime.proctime, 'rowtime.rowtime)
+
+ @Test
+ def testSortProcessingTime() = {
+
+ val sqlQuery = "SELECT a FROM MyTable ORDER BY proctime, c"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode("DataStreamSort",
+ streamTableNode(0),
+ term("orderBy", "proctime ASC", "c ASC")),
+ term("select", "a", "TIME_MATERIALIZATION(proctime) AS proctime", "c"))
+
+ streamUtil.verifySql(sqlQuery, expected)
+ }
+
+ @Test
+ def testSortRowTime() = {
+
+ val sqlQuery = "SELECT a FROM MyTable ORDER BY rowtime, c"
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode("DataStreamSort",
+ streamTableNode(0),
+ term("orderBy", "rowtime ASC, c ASC")),
+ term("select", "a", "TIME_MATERIALIZATION(rowtime) AS rowtime", "c"))
+
+ streamUtil.verifySql(sqlQuery, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/OverWindowValidationTest.scala
new file mode 100644
index 0000000..413cca7
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/OverWindowValidationTest.scala
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.OverAgg0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class OverWindowValidationTest extends TableTestBase {
+
+ private val streamUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)]("T1", 'a, 'b, 'c, 'proctime.proctime)
+
+ /**
+ * All aggregates must be computed on the same window.
+ */
+ @Test(expected = classOf[TableException])
+ def testMultiWindow(): Unit = {
+
+ val sqlQuery = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
+ "sum(a) OVER (PARTITION BY b ORDER BY proctime RANGE UNBOUNDED preceding) " +
+ "from T1"
+
+ streamUtil.tableEnv.sql(sqlQuery).toAppendStream[Row]
+ }
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation(): Unit = {
+ streamUtil.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
+
+ streamUtil.tableEnv.sql(sqlQuery)
+ }
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testInvalidOverAggregation2(): Unit = {
+ streamUtil.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
+ streamUtil.tableEnv.sql(sqlQuery)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/SortValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/SortValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/SortValidationTest.scala
new file mode 100644
index 0000000..ae7486d
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/SortValidationTest.scala
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class SortValidationTest extends TableTestBase {
+
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c,
+ 'proctime.proctime, 'rowtime.rowtime)
+
+ // test should fail because time order is descending
+ @Test(expected = classOf[TableException])
+ def testSortProcessingTimeDesc() = {
+
+ val sqlQuery = "SELECT a FROM MyTable ORDER BY proctime DESC, c"
+ streamUtil.verifySql(sqlQuery, "")
+ }
+
+
+ // test should fail because time is not the primary order field
+ @Test(expected = classOf[TableException])
+ def testSortProcessingTimeSecondaryField() = {
+
+ val sqlQuery = "SELECT a FROM MyTable ORDER BY c, proctime"
+ streamUtil.verifySql(sqlQuery, "")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/WindowAggregateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/WindowAggregateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/WindowAggregateValidationTest.scala
new file mode 100644
index 0000000..e7cf597
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/sql/validation/WindowAggregateValidationTest.scala
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMerge
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class WindowAggregateValidationTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)](
+ "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
+
+ @Test(expected = classOf[TableException])
+ def testTumbleWindowNoOffset(): Unit = {
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM MyTable " +
+ "GROUP BY TUMBLE(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testHopWindowNoOffset(): Unit = {
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM MyTable " +
+ "GROUP BY HOP(proctime, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testSessionWindowNoOffset(): Unit = {
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM MyTable " +
+ "GROUP BY SESSION(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testVariableWindowSize() = {
+ val sql = "SELECT COUNT(*) FROM MyTable GROUP BY TUMBLE(proctime, c * INTERVAL '1' MINUTE)"
+ streamUtil.verifySql(sql, "n/a")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testWindowUdAggInvalidArgs(): Unit = {
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, weightedAvg(a, b) AS wAvg " +
+ "FROM MyTable " +
+ "GROUP BY TUMBLE(proctime(), INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala
new file mode 100644
index 0000000..533235a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.stream.table
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.TableTestBase
+import org.junit.Test
+
+class AggregateTest extends TableTestBase {
+
+ @Test
+ def testGroupAggregate() = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val resultTable = table
+ .groupBy('b)
+ .select('a.count)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b")
+ ),
+ term("groupBy", "b"),
+ term("select", "b", "COUNT(a) AS TMP_0")
+ ),
+ term("select", "TMP_0")
+ )
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testGroupAggregateWithConstant1(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val resultTable = table
+ .select('a, 4 as 'four, 'b)
+ .groupBy('four, 'a)
+ .select('four, 'b.sum)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "4 AS four", "b", "a")
+ ),
+ term("groupBy", "four", "a"),
+ term("select", "four", "a", "SUM(b) AS TMP_0")
+ ),
+ term("select", "4 AS four", "TMP_0")
+ )
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testGroupAggregateWithConstant2(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val resultTable = table
+ .select('b, 4 as 'four, 'a)
+ .groupBy('b, 'four)
+ .select('four, 'a.sum)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "4 AS four", "a", "b")
+ ),
+ term("groupBy", "four", "b"),
+ term("select", "four", "b", "SUM(a) AS TMP_0")
+ ),
+ term("select", "4 AS four", "TMP_0")
+ )
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testGroupAggregateWithExpressionInSelect(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val resultTable = table
+ .select('a as 'a, 'b % 3 as 'd, 'c as 'c)
+ .groupBy('d)
+ .select('c.min, 'a.avg)
+
+ val expected =
+ unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "MOD(b, 3) AS d", "c")
+ ),
+ term("groupBy", "d"),
+ term("select", "d", "MIN(c) AS TMP_0", "AVG(a) AS TMP_1")
+ ),
+ term("select", "TMP_0", "TMP_1")
+ )
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testGroupAggregateWithFilter(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val resultTable = table
+ .groupBy('b)
+ .select('b, 'a.sum)
+ .where('b === 2)
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "b", "a"),
+ term("where", "=(b, 2)")
+ ),
+ term("groupBy", "b"),
+ term("select", "b", "SUM(a) AS TMP_0")
+ )
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testGroupAggregateWithAverage(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Long, Int, String)]('a, 'b, 'c)
+
+ val resultTable = table
+ .groupBy('b)
+ .select('b, 'a.cast(BasicTypeInfo.DOUBLE_TYPE_INFO).avg)
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "b", "a", "CAST(a) AS a0")
+ ),
+ term("groupBy", "b"),
+ term("select", "b", "AVG(a0) AS TMP_0")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+}
[18/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsTestBase.scala
new file mode 100644
index 0000000..e2d0473
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TableProgramsTestBase.scala
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import org.apache.flink.table.api.TableConfig
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.MultipleProgramsTestBase
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+
+class TableProgramsTestBase(
+ mode: TestExecutionMode,
+ tableConfigMode: TableConfigMode)
+ extends MultipleProgramsTestBase(mode) {
+
+ def config: TableConfig = {
+ val conf = new TableConfig
+ tableConfigMode match {
+ case TableProgramsTestBase.NO_NULL =>
+ conf.setNullCheck(false)
+ case _ => // keep default
+ }
+ conf
+ }
+}
+
+object TableProgramsTestBase {
+ case class TableConfigMode(nullCheck: Boolean)
+
+ val DEFAULT = TableConfigMode(nullCheck = true)
+ val NO_NULL = TableConfigMode(nullCheck = false)
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TimeTestUtil.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TimeTestUtil.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TimeTestUtil.scala
new file mode 100644
index 0000000..fab1e4a
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/TimeTestUtil.scala
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import org.apache.flink.streaming.api.functions.source.SourceFunction
+import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
+import org.apache.flink.streaming.api.watermark.Watermark
+
+object TimeTestUtil {
+
+ class EventTimeSourceFunction[T](
+ dataWithTimestampList: Seq[Either[(Long, T), Long]]) extends SourceFunction[T] {
+ override def run(ctx: SourceContext[T]): Unit = {
+ dataWithTimestampList.foreach {
+ case Left(t) => ctx.collectWithTimestamp(t._2, t._1)
+ case Right(w) => ctx.emitWatermark(new Watermark(w))
+ }
+ }
+
+ override def cancel(): Unit = ???
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/UserDefinedFunctionTestUtils.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/UserDefinedFunctionTestUtils.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/UserDefinedFunctionTestUtils.scala
new file mode 100644
index 0000000..176afcd
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/utils/UserDefinedFunctionTestUtils.scala
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.utils
+
+import java.io.File
+
+import com.google.common.base.Charsets
+import com.google.common.io.Files
+import org.apache.flink.api.scala.ExecutionEnvironment
+import org.apache.flink.configuration.Configuration
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+
+object UserDefinedFunctionTestUtils {
+
+ def setJobParameters(env: ExecutionEnvironment, parameters: Map[String, String]): Unit = {
+ val conf = new Configuration()
+ parameters.foreach {
+ case (k, v) => conf.setString(k, v)
+ }
+ env.getConfig.setGlobalJobParameters(conf)
+ }
+
+ def setJobParameters(env: StreamExecutionEnvironment, parameters: Map[String, String]): Unit = {
+ val conf = new Configuration()
+ parameters.foreach {
+ case (k, v) => conf.setString(k, v)
+ }
+ env.getConfig.setGlobalJobParameters(conf)
+ }
+
+ def writeCacheFile(fileName: String, contents: String): String = {
+ val tempFile = File.createTempFile(this.getClass.getName + "-" + fileName, "tmp")
+ tempFile.deleteOnExit()
+ Files.write(contents, tempFile, Charsets.UTF_8)
+ tempFile.getAbsolutePath
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala
deleted file mode 100644
index c800289..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sinks/validation/TableSinksValidationTest.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.sinks.validation
-
-import org.apache.flink.table.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.table.api.scala.stream.utils.StreamTestData
-import org.apache.flink.table.runtime.datastream.table.TestAppendSink
-import org.junit.Test
-
-class TableSinksValidationTest extends StreamingMultipleProgramsTestBase {
-
- @Test(expected = classOf[TableException])
- def testAppendSinkOnUpdatingTable(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'id, 'num, 'text)
-
- t.groupBy('text)
- .select('text, 'id.count, 'num.sum)
- .writeToSink(new TestAppendSink)
-
- // must fail because table is not append-only
- env.execute()
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala
deleted file mode 100644
index b01453d..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTest.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.sources
-
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.{Assert, Test}
-
-class TableSourceTest extends TableSourceTestBase {
-
- @Test
- def testTableSourceScanToString(): Unit = {
- val (tableSource1, _) = filterableTableSource
- val (tableSource2, _) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource("table1", tableSource1)
- tEnv.registerTableSource("table2", tableSource2)
-
- val table1 = tEnv.scan("table1").where("amount > 2")
- val table2 = tEnv.scan("table2").where("amount > 2")
- val result = table1.unionAll(table2)
-
- val expected = binaryNode(
- "DataSetUnion",
- batchFilterableSourceTableNode(
- "table1",
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- batchFilterableSourceTableNode(
- "table2",
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("union", "name, id, amount, price")
- )
- util.verifyTable(result, expected)
- }
-
- @Test
- def testCsvTableSourceBuilder(): Unit = {
- val source1 = CsvTableSource.builder()
- .path("/path/to/csv")
- .field("myfield", Types.STRING)
- .field("myfield2", Types.INT)
- .quoteCharacter(';')
- .fieldDelimiter("#")
- .lineDelimiter("\r\n")
- .commentPrefix("%%")
- .ignoreFirstLine()
- .ignoreParseErrors()
- .build()
-
- val source2 = new CsvTableSource(
- "/path/to/csv",
- Array("myfield", "myfield2"),
- Array(Types.STRING, Types.INT),
- "#",
- "\r\n",
- ';',
- true,
- "%%",
- true)
-
- Assert.assertEquals(source1, source2)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala
deleted file mode 100644
index d408694..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/TableSourceTestBase.scala
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.flink.table.sources
-
-import org.apache.flink.table.utils.{CommonTestData, TableTestBase, TestFilterableTableSource}
-
-class TableSourceTestBase extends TableTestBase {
-
- protected val projectedFields: Array[String] = Array("last", "id", "score")
- protected val noCalcFields: Array[String] = Array("id", "score", "first")
-
- def filterableTableSource:(TableSource[_], String) = {
- val tableSource = new TestFilterableTableSource
- (tableSource, "filterableTable")
- }
-
- def csvTable: (CsvTableSource, String) = {
- val csvTable = CommonTestData.getCsvTableSource
- val tableName = "csvTable"
- (csvTable, tableName)
- }
-
- def batchSourceTableNode(sourceName: String, fields: Array[String]): String = {
- s"BatchTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
- }
-
- def streamSourceTableNode(sourceName: String, fields: Array[String] ): String = {
- s"StreamTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
- }
-
- def batchFilterableSourceTableNode(
- sourceName: String,
- fields: Array[String],
- exp: String): String = {
- "BatchTableSourceScan(" +
- s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
- }
-
- def streamFilterableSourceTableNode(
- sourceName: String,
- fields: Array[String],
- exp: String): String = {
- "StreamTableSourceScan(" +
- s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala
deleted file mode 100644
index f670452..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/batch/TableSourceTest.scala
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.sources.batch
-
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.expressions.utils._
-import org.apache.flink.table.sources.{CsvTableSource, TableSource}
-import org.apache.flink.table.utils.TableTestUtil._
-import org.apache.flink.table.utils.{CommonTestData, TableTestBase, TestFilterableTableSource}
-import org.junit.{Assert, Test}
-
-class TableSourceTest extends TableTestBase {
-
- private val projectedFields: Array[String] = Array("last", "id", "score")
- private val noCalcFields: Array[String] = Array("id", "score", "first")
-
- @Test
- def testTableSourceScanToString(): Unit = {
- val (tableSource1, _) = filterableTableSource
- val (tableSource2, _) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource("table1", tableSource1)
- tEnv.registerTableSource("table2", tableSource2)
-
- val table1 = tEnv.scan("table1").where("amount > 2")
- val table2 = tEnv.scan("table2").where("amount > 2")
- val result = table1.unionAll(table2)
-
- val expected = binaryNode(
- "DataSetUnion",
- batchFilterableSourceTableNode(
- "table1",
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- batchFilterableSourceTableNode(
- "table2",
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("union", "name, id, amount, price")
- )
- util.verifyTable(result, expected)
- }
-
- // batch plan
-
- @Test
- def testBatchProjectableSourceScanPlanTableApi(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('last.upperCase(), 'id.floor(), 'score * 2)
-
- val expected = unaryNode(
- "DataSetCalc",
- batchSourceTableNode(tableName, projectedFields),
- term("select", "UPPER(last) AS _c0", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchProjectableSourceScanPlanSQL(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = batchTestUtil()
-
- util.tableEnv.registerTableSource(tableName, tableSource)
-
- val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
-
- val expected = unaryNode(
- "DataSetCalc",
- batchSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testBatchProjectableSourceScanNoIdentityCalc(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('id, 'score, 'first)
-
- val expected = batchSourceTableNode(tableName, noCalcFields)
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableWithoutPushDown(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("price * 2 < 32")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price")),
- term("select", "price", "id", "amount"),
- term("where", "<(*(price, 2), 32)")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterablePartialPushDown(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .where("amount > 2 && price * 2 < 32")
- .select('price, 'name.lowerCase(), 'amount)
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "LOWER(name) AS _c1", "amount"),
- term("where", "<(*(price, 2), 32)")
- )
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableFullyPushedDown(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && amount < 32")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2 && 'amount < 32"),
- term("select", "price", "id", "amount")
- )
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableWithUnconvertedExpression(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && (amount < 32 || amount.cast(LONG) > 10)") // cast can not be converted
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "id", "amount"),
- term("where", "OR(<(amount, 32), >(CAST(amount), 10))")
- )
- util.verifyTable(result, expected)
- }
-
- @Test
- def testBatchFilterableWithUDF(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = batchTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
- val func = Func0
- tEnv.registerFunction("func0", func)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && func0(amount) < 32")
-
- val expected = unaryNode(
- "DataSetCalc",
- batchFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "id", "amount"),
- term("where", s"<(${func.functionIdentifier}(amount), 32)")
- )
-
- util.verifyTable(result, expected)
- }
-
- // stream plan
-
- @Test
- def testStreamProjectableSourceScanPlanTableApi(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('last, 'id.floor(), 'score * 2)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testStreamProjectableSourceScanPlanSQL(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
-
- util.tableEnv.registerTableSource(tableName, tableSource)
-
- val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
- @Test
- def testStreamProjectableSourceScanNoIdentityCalc(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('id, 'score, 'first)
-
- val expected = streamSourceTableNode(tableName, noCalcFields)
- util.verifyTable(result, expected)
- }
-
- @Test
- def testStreamFilterableSourceScanPlanTableApi(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = streamTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && price * 2 < 32")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "id", "amount"),
- term("where", "<(*(price, 2), 32)")
- )
-
- util.verifyTable(result, expected)
- }
-
- // csv builder
-
- @Test
- def testCsvTableSourceBuilder(): Unit = {
- val source1 = CsvTableSource.builder()
- .path("/path/to/csv")
- .field("myfield", Types.STRING)
- .field("myfield2", Types.INT)
- .quoteCharacter(';')
- .fieldDelimiter("#")
- .lineDelimiter("\r\n")
- .commentPrefix("%%")
- .ignoreFirstLine()
- .ignoreParseErrors()
- .build()
-
- val source2 = new CsvTableSource(
- "/path/to/csv",
- Array("myfield", "myfield2"),
- Array(Types.STRING, Types.INT),
- "#",
- "\r\n",
- ';',
- true,
- "%%",
- true)
-
- Assert.assertEquals(source1, source2)
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithNullPath(): Unit = {
- CsvTableSource.builder()
- .field("myfield", Types.STRING)
- // should fail, path is not defined
- .build()
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithDuplicateFieldName(): Unit = {
- CsvTableSource.builder()
- .path("/path/to/csv")
- .field("myfield", Types.STRING)
- // should fail, field name must no be duplicate
- .field("myfield", Types.INT)
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithEmptyField(): Unit = {
- CsvTableSource.builder()
- .path("/path/to/csv")
- // should fail, field can be empty
- .build()
- }
-
- // utils
-
- def filterableTableSource:(TableSource[_], String) = {
- val tableSource = new TestFilterableTableSource
- (tableSource, "filterableTable")
- }
-
- def csvTable: (CsvTableSource, String) = {
- val csvTable = CommonTestData.getCsvTableSource
- val tableName = "csvTable"
- (csvTable, tableName)
- }
-
- def batchSourceTableNode(sourceName: String, fields: Array[String]): String = {
- s"BatchTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
- }
-
- def streamSourceTableNode(sourceName: String, fields: Array[String] ): String = {
- s"StreamTableSourceScan(table=[[$sourceName]], fields=[${fields.mkString(", ")}])"
- }
-
- def batchFilterableSourceTableNode(
- sourceName: String,
- fields: Array[String],
- exp: String): String = {
- "BatchTableSourceScan(" +
- s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
- }
-
- def streamFilterableSourceTableNode(
- sourceName: String,
- fields: Array[String],
- exp: String): String = {
- "StreamTableSourceScan(" +
- s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala
deleted file mode 100644
index e6d6480..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/sql/TableSourceTest.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.sources.stream.sql
-
-import org.apache.flink.table.sources.TableSourceTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class TableSourceTest extends TableSourceTestBase {
-
- @Test
- def testProjectableSourceScanPlan(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
-
- util.tableEnv.registerTableSource(tableName, tableSource)
-
- val sqlQuery = s"SELECT `last`, floor(id), score * 2 FROM $tableName"
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS EXPR$1", "*(score, 2) AS EXPR$2")
- )
-
- util.verifySql(sqlQuery, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala
deleted file mode 100644
index c43913b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/stream/table/TableSourceTest.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.sources.stream.table
-
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.sources.TableSourceTestBase
-import org.apache.flink.table.utils.TableTestUtil._
-import org.junit.Test
-
-class TableSourceTest extends TableSourceTestBase {
-
- @Test
- def testProjectableSourceScanPlan(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('last, 'id.floor(), 'score * 2)
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamSourceTableNode(tableName, projectedFields),
- term("select", "last", "FLOOR(id) AS _c1", "*(score, 2) AS _c2")
- )
-
- util.verifyTable(result, expected)
- }
-
- @Test
- def testProjectableSourceScanNoIdentityCalc(): Unit = {
- val (tableSource, tableName) = csvTable
- val util = streamTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('id, 'score, 'first)
-
- val expected = streamSourceTableNode(tableName, noCalcFields)
- util.verifyTable(result, expected)
- }
-
- @Test
- def testFilterableSourceScanPlan(): Unit = {
- val (tableSource, tableName) = filterableTableSource
- val util = streamTestUtil()
- val tEnv = util.tableEnv
-
- tEnv.registerTableSource(tableName, tableSource)
-
- val result = tEnv
- .scan(tableName)
- .select('price, 'id, 'amount)
- .where("amount > 2 && price * 2 < 32")
-
- val expected = unaryNode(
- "DataStreamCalc",
- streamFilterableSourceTableNode(
- tableName,
- Array("name", "id", "amount", "price"),
- "'amount > 2"),
- term("select", "price", "id", "amount"),
- term("where", "<(*(price, 2), 32)")
- )
-
- util.verifyTable(result, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala
deleted file mode 100644
index e575ab8..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/sources/validation/TableSourceBalidationTest.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.sources.validation
-
-import org.apache.flink.table.api.Types
-import org.apache.flink.table.sources.CsvTableSource
-import org.apache.flink.table.sources.TableSourceTestBase
-import org.junit.Test
-
-class TableSourceBalidationTest extends TableSourceTestBase {
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithNullPath(): Unit = {
- CsvTableSource.builder()
- .field("myfield", Types.STRING)
- // should fail, path is not defined
- .build()
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithDuplicateFieldName(): Unit = {
- CsvTableSource.builder()
- .path("/path/to/csv")
- .field("myfield", Types.STRING)
- // should fail, field name must no be duplicate
- .field("myfield", Types.INT)
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def testCsvTableSourceBuilderWithEmptyField(): Unit = {
- CsvTableSource.builder()
- .path("/path/to/csv")
- // should fail, field can be empty
- .build()
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/CommonTestData.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/CommonTestData.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/CommonTestData.scala
deleted file mode 100644
index 6a5c52f..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/CommonTestData.scala
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.utils
-
-import java.io.{File, FileOutputStream, OutputStreamWriter}
-import java.util
-
-import org.apache.flink.api.common.typeinfo.{BasicTypeInfo, TypeInformation}
-import org.apache.flink.api.java.typeutils.TypeExtractor
-import org.apache.flink.api.java.{DataSet, ExecutionEnvironment}
-import org.apache.flink.table.api.TableSchema
-import org.apache.flink.table.sources.{BatchTableSource, CsvTableSource}
-import org.apache.flink.table.catalog._
-
-object CommonTestData {
-
- def getCsvTableSource: CsvTableSource = {
- val csvRecords = Seq(
- "First#Id#Score#Last",
- "Mike#1#12.3#Smith",
- "Bob#2#45.6#Taylor",
- "Sam#3#7.89#Miller",
- "Peter#4#0.12#Smith",
- "% Just a comment",
- "Liz#5#34.5#Williams",
- "Sally#6#6.78#Miller",
- "Alice#7#90.1#Smith",
- "Kelly#8#2.34#Williams"
- )
-
- val tempFilePath = writeToTempFile(csvRecords.mkString("$"), "csv-test", "tmp")
- new CsvTableSource(
- tempFilePath,
- Array("first", "id", "score", "last"),
- Array(
- BasicTypeInfo.STRING_TYPE_INFO,
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.DOUBLE_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO
- ),
- fieldDelim = "#",
- rowDelim = "$",
- ignoreFirstLine = true,
- ignoreComments = "%"
- )
- }
-
- def getInMemoryTestCatalog: ExternalCatalog = {
- val csvRecord1 = Seq(
- "1#1#Hi",
- "2#2#Hello",
- "3#2#Hello world"
- )
- val tempFilePath1 = writeToTempFile(csvRecord1.mkString("$"), "csv-test1", "tmp")
- val properties1 = new util.HashMap[String, String]()
- properties1.put("path", tempFilePath1)
- properties1.put("fieldDelim", "#")
- properties1.put("rowDelim", "$")
- val externalCatalogTable1 = ExternalCatalogTable(
- "csv",
- new TableSchema(
- Array("a", "b", "c"),
- Array(
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.LONG_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO)),
- properties1
- )
-
- val csvRecord2 = Seq(
- "1#1#0#Hallo#1",
- "2#2#1#Hallo Welt#2",
- "2#3#2#Hallo Welt wie#1",
- "3#4#3#Hallo Welt wie gehts?#2",
- "3#5#4#ABC#2",
- "3#6#5#BCD#3",
- "4#7#6#CDE#2",
- "4#8#7#DEF#1",
- "4#9#8#EFG#1",
- "4#10#9#FGH#2",
- "5#11#10#GHI#1",
- "5#12#11#HIJ#3",
- "5#13#12#IJK#3",
- "5#14#13#JKL#2",
- "5#15#14#KLM#2"
- )
- val tempFilePath2 = writeToTempFile(csvRecord2.mkString("$"), "csv-test2", "tmp")
- val properties2 = new util.HashMap[String, String]()
- properties2.put("path", tempFilePath2)
- properties2.put("fieldDelim", "#")
- properties2.put("rowDelim", "$")
- val externalCatalogTable2 = ExternalCatalogTable(
- "csv",
- new TableSchema(
- Array("d", "e", "f", "g", "h"),
- Array(
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.LONG_TYPE_INFO,
- BasicTypeInfo.INT_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO,
- BasicTypeInfo.LONG_TYPE_INFO)
- ),
- properties2
- )
- val catalog = new InMemoryExternalCatalog("test")
- val db1 = new InMemoryExternalCatalog("db1")
- val db2 = new InMemoryExternalCatalog("db2")
- catalog.createSubCatalog("db1", db1, ignoreIfExists = false)
- catalog.createSubCatalog("db2", db2, ignoreIfExists = false)
-
- // Register the table with both catalogs
- catalog.createTable("tb1", externalCatalogTable1, ignoreIfExists = false)
- db1.createTable("tb1", externalCatalogTable1, ignoreIfExists = false)
- db2.createTable("tb2", externalCatalogTable2, ignoreIfExists = false)
- catalog
- }
-
- private def writeToTempFile(
- contents: String,
- filePrefix: String,
- fileSuffix: String,
- charset: String = "UTF-8"): String = {
- val tempFile = File.createTempFile(filePrefix, fileSuffix)
- tempFile.deleteOnExit()
- val tmpWriter = new OutputStreamWriter(new FileOutputStream(tempFile), charset)
- tmpWriter.write(contents)
- tmpWriter.close()
- tempFile.getAbsolutePath
- }
-
- def getNestedTableSource: BatchTableSource[Person] = {
- new BatchTableSource[Person] {
- override def getDataSet(execEnv: ExecutionEnvironment): DataSet[Person] = {
- val executionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- executionEnvironment.fromCollection(
- util.Arrays.asList(
- new Person("Mike", "Smith", new Address("5th Ave", "New-York")),
- new Person("Sally", "Miller", new Address("Potsdamer Platz", "Berlin")),
- new Person("Bob", "Taylor", new Address("Pearse Street", "Dublin"))),
- getReturnType
- )
- }
-
- override def getReturnType: TypeInformation[Person] = {
- TypeExtractor.getForClass(classOf[Person])
- }
- }
- }
-
- class Person(var firstName: String, var lastName: String, var address: Address) {
- def this() {
- this(null, null, null)
- }
- }
-
- class Address(var street: String, var city: String) {
- def this() {
- this(null, null)
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/LogicalPlanFormatUtils.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/LogicalPlanFormatUtils.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/LogicalPlanFormatUtils.scala
new file mode 100644
index 0000000..92d8100
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/LogicalPlanFormatUtils.scala
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.utils
+
+object LogicalPlanFormatUtils {
+ private val tempPattern = """TMP_\d+""".r
+
+ def formatTempTableId(preStr: String): String = {
+ val str = preStr.replaceAll("ArrayBuffer\\(", "List\\(")
+ val minId = getMinTempTableId(str)
+ tempPattern.replaceAllIn(str, s => "TMP_" + (s.matched.substring(4).toInt - minId) )
+ }
+
+ private def getMinTempTableId(logicalStr: String): Long = {
+ val found = tempPattern.findAllIn(logicalStr).map(s => {
+ s.substring(4).toInt
+ })
+ if (found.isEmpty) {
+ 0L
+ } else {
+ found.min
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
index 6657d50..d99aac1 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
@@ -20,19 +20,16 @@ package org.apache.flink.table.utils
import org.apache.calcite.plan.RelOptUtil
import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.java.{DataSet => JDataSet}
-import org.apache.flink.table.api.{Table, TableEnvironment}
-import org.apache.flink.table.api.scala._
+import org.apache.flink.api.java.{DataSet => JDataSet, ExecutionEnvironment => JExecutionEnvironment}
import org.apache.flink.api.scala.{DataSet, ExecutionEnvironment}
-import org.apache.flink.api.java.{ExecutionEnvironment => JExecutionEnvironment}
import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.table.expressions.Expression
-import org.apache.flink.table.functions.{ScalarFunction, TableFunction}
import org.apache.flink.streaming.api.datastream.{DataStream => JDataStream}
import org.apache.flink.streaming.api.environment.{StreamExecutionEnvironment => JStreamExecutionEnvironment}
import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
-import org.apache.flink.table.api.scala.batch.utils.LogicalPlanFormatUtils
-import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{Table, TableEnvironment}
+import org.apache.flink.table.expressions.Expression
+import org.apache.flink.table.functions.{AggregateFunction, ScalarFunction, TableFunction}
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.rules.ExpectedException
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/UserDefinedFunctionTestUtils.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/UserDefinedFunctionTestUtils.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/UserDefinedFunctionTestUtils.scala
deleted file mode 100644
index deaedc9..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/utils/UserDefinedFunctionTestUtils.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.utils
-
-import java.io.File
-
-import com.google.common.base.Charsets
-import com.google.common.io.Files
-import org.apache.flink.api.scala.ExecutionEnvironment
-import org.apache.flink.configuration.Configuration
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-
-object UserDefinedFunctionTestUtils {
-
- def setJobParameters(env: ExecutionEnvironment, parameters: Map[String, String]): Unit = {
- val conf = new Configuration()
- parameters.foreach {
- case (k, v) => conf.setString(k, v)
- }
- env.getConfig.setGlobalJobParameters(conf)
- }
-
- def setJobParameters(env: StreamExecutionEnvironment, parameters: Map[String, String]): Unit = {
- val conf = new Configuration()
- parameters.foreach {
- case (k, v) => conf.setString(k, v)
- }
- env.getConfig.setGlobalJobParameters(conf)
- }
-
- def writeCacheFile(fileName: String, contents: String): String = {
- val tempFile = File.createTempFile(this.getClass.getName + "-" + fileName, "tmp")
- tempFile.deleteOnExit()
- Files.write(contents, tempFile, Charsets.UTF_8)
- tempFile.getAbsolutePath
- }
-}
[27/44] flink git commit: [FLINK-6617] [table] Restructuring of tests
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/CalcITCase.scala
new file mode 100644
index 0000000..711182c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/CalcITCase.scala
@@ -0,0 +1,323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql
+
+import java.sql.{Date, Time, Timestamp}
+import java.util
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableEnvironment, ValidationException}
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.table.runtime.batch.table.OldHashCode
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.table.runtime.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class CalcITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSelectStarFromTable(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectStarFromDataSet(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSimpleSelectAll(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT a, b, c FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
+ "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
+ "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
+ "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
+ "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
+ "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectWithNaming(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT _1 as a, _2 as b FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
+ "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
+ "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testInvalidFields(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT a, foo FROM MyTable"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ tEnv.sql(sqlQuery)
+ }
+
+ @Test
+ def testAllRejectingFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE false"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAllPassingFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE true"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
+ "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
+ "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
+ "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
+ "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
+ "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnString(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE c LIKE '%world%'"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterOnInteger(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)=0"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
+ "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
+ "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
+ "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDisjunctivePredicate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE a < 2 OR a > 20"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFilterWithAnd(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE MOD(a,2)<>0 AND MOD(b,2)=0"
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
+ "9,4,Comment#3\n" + "17,6,Comment#11\n" +
+ "19,6,Comment#13\n" + "21,6,Comment#15\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAdvancedDataTypes(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT a, b, c, DATE '1984-07-12', TIME '14:34:24', " +
+ "TIMESTAMP '1984-07-12 14:34:24' FROM MyTable"
+
+ val ds = env.fromElements((
+ Date.valueOf("1984-07-12"),
+ Time.valueOf("14:34:24"),
+ Timestamp.valueOf("1984-07-12 14:34:24")))
+ tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
+ "1984-07-12,14:34:24,1984-07-12 14:34:24.0"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUserDefinedScalarFunction(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ tEnv.registerFunction("hashCode", OldHashCode)
+ tEnv.registerFunction("hashCode", MyHashCode)
+
+ val ds = env.fromElements("a", "b", "c")
+ tEnv.registerDataSet("MyTable", ds, 'text)
+
+ val result = tEnv.sql("SELECT hashCode(text) FROM MyTable")
+
+ val expected = "97\n98\n99"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
+
+object MyHashCode extends ScalarFunction {
+ def eval(s: String): Int = s.hashCode()
+}
+
+object CalcITCase {
+
+ @Parameterized.Parameters(name = "Table config = {0}")
+ def parameters(): util.Collection[Array[java.lang.Object]] = {
+ Seq[Array[AnyRef]](
+ Array(TableProgramsTestBase.DEFAULT),
+ Array(TableProgramsTestBase.NO_NULL)).asJava
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/JoinITCase.scala
new file mode 100644
index 0000000..681b4b5
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/JoinITCase.scala
@@ -0,0 +1,520 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit.Assert.assertEquals
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class JoinITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND b < 2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi,Hallo\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE b = e AND a < 6 AND h < b"
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithMultipleKeys(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c, g FROM Table3, Table5 WHERE a = d AND b = h"
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
+ "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testJoinWithAlias(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT Table5.c, Table3.c FROM Table3, Table5 WHERE a = d AND a < 4"
+
+ val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'c)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = "1,Hi\n" + "2,Hello\n" + "1,Hello\n" +
+ "2,Hello world\n" + "2,Hello world\n" + "3,Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDataSetJoinWithAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT COUNT(g), COUNT(b) FROM Table3, Table5 WHERE a = d"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("Table3", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("Table5", ds2, 'd, 'e, 'f, 'g, 'h)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "6,6"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableJoinWithAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT COUNT(b), COUNT(g) FROM Table3, Table5 WHERE a = d"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "6,6"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testFullOuterJoin(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val sqlQuery = "SELECT c, g FROM Table3 FULL OUTER JOIN Table5 ON b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
+ "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
+ "null,IJK\n" + "null,JKL\n" + "null,KLM"
+
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLeftOuterJoin(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val sqlQuery = "SELECT c, g FROM Table5 LEFT OUTER JOIN Table3 ON b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
+ "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
+ "null,IJK\n" + "null,JKL\n" + "null,KLM"
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightOuterJoin(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ tEnv.getConfig.setNullCheck(true)
+
+ val sqlQuery = "SELECT c, g FROM Table3 RIGHT OUTER JOIN Table5 ON b = e"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
+ tEnv.registerTable("Table3", ds1)
+ tEnv.registerTable("Table5", ds2)
+
+ val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
+ "null,Hallo Welt wie\n" + "null,Hallo Welt wie gehts?\n" + "null,ABC\n" + "null,BCD\n" +
+ "null,CDE\n" + "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "null,HIJ\n" +
+ "null,IJK\n" + "null,JKL\n" + "null,KLM"
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCrossJoinWithLeftSingleRowInput(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
+ tEnv.registerTable("A", table)
+
+ val sqlQuery2 = "SELECT * FROM (SELECT count(*) FROM A) CROSS JOIN A"
+ val expected =
+ "3,1,1,Hi\n" +
+ "3,2,2,Hello\n" +
+ "3,3,2,Hello world"
+ val result = tEnv.sql(sqlQuery2).collect()
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testCrossJoinWithRightSingleRowInput(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
+ tEnv.registerTable("A", table)
+
+ val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A)"
+ val expected =
+ "1,1,Hi,3\n" +
+ "2,2,Hello,3\n" +
+ "3,2,Hello world,3"
+ val result = tEnv.sql(sqlQuery1).collect()
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testCrossJoinWithEmptySingleRowInput(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val table = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a1, 'a2, 'a3)
+ tEnv.registerTable("A", table)
+
+ val sqlQuery1 = "SELECT * FROM A CROSS JOIN (SELECT count(*) FROM A HAVING count(*) < 0)"
+ val result = tEnv.sql(sqlQuery1).count()
+ Assert.assertEquals(0, result)
+ }
+
+ @Test
+ def testLeftNullRightJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt " +
+ "FROM (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) RIGHT JOIN A ON a < cnt"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,null",
+ "2,null", "2,null",
+ "3,null", "3,null", "3,null",
+ "4,null", "4,null", "4,null", "4,null",
+ "5,null", "5,null", "5,null", "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+
+ @Test
+ def testLeftSingleRightJoinEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt = a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,null", "2,null", "2,null", "3,3", "3,3",
+ "3,3", "4,null", "4,null", "4,null",
+ "4,null", "5,null", "5,null", "5,null",
+ "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testLeftSingleRightJoinNotEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM (SELECT COUNT(*) AS cnt FROM B) RIGHT JOIN A ON cnt > a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,3", "2,3", "2,3", "3,null", "3,null",
+ "3,null", "4,null", "4,null", "4,null",
+ "4,null", "5,null", "5,null", "5,null",
+ "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightNullLeftJoin(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt " +
+ "FROM A LEFT JOIN (SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM B) WHERE cnt < 0) ON cnt > a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
+ tEnv.registerTable("A", ds2)
+ tEnv.registerTable("B", ds1)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = Seq(
+ "2,null", "3,null", "1,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt = a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = Seq(
+ "1,null", "2,null", "2,null", "3,3", "3,3",
+ "3,3", "4,null", "4,null", "4,null",
+ "4,null", "5,null", "5,null", "5,null",
+ "5,null", "5,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinNotEqualPredicate(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt FROM A LEFT JOIN (SELECT COUNT(*) AS cnt FROM B) ON cnt < a"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("A", ds1)
+ tEnv.registerTable("B", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = Seq(
+ "1,null", "2,null", "2,null", "3,null", "3,null",
+ "3,null", "4,3", "4,3", "4,3",
+ "4,3", "5,3", "5,3", "5,3",
+ "5,3", "5,3").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testRightSingleLeftJoinTwoFields(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val sqlQuery =
+ "SELECT a, cnt, cnt2 " +
+ "FROM t1 LEFT JOIN (SELECT COUNT(*) AS cnt,COUNT(*) AS cnt2 FROM t2 ) AS x ON a = cnt"
+
+ val ds1 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c, 'd, 'e)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv)
+ tEnv.registerTable("t1", ds1)
+ tEnv.registerTable("t2", ds2)
+
+ val result = tEnv.sql(sqlQuery)
+ val expected = Seq(
+ "1,null,null",
+ "2,null,null", "2,null,null",
+ "3,3,3", "3,3,3", "3,3,3",
+ "4,null,null", "4,null,null", "4,null,null", "4,null,null",
+ "5,null,null", "5,null,null", "5,null,null", "5,null,null", "5,null,null").mkString("\n")
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testCrossWithUnnest(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ (1, 1L, Array("Hi", "w")),
+ (2, 2L, Array("Hello", "k")),
+ (3, 2L, Array("Hello world", "x"))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataSet("T", stream, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) as A (s)"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = List("1,Hi", "1,w", "2,Hello", "2,k", "3,Hello world", "3,x")
+ val results = result.toDataSet[Row].collect().toList
+ assertEquals(expected.toString(), results.sortWith(_.toString < _.toString).toString())
+ }
+
+ @Test
+ def testJoinWithUnnestOfTuple(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val data = List(
+ (1, Array((12, "45.6"), (2, "45.612"))),
+ (2, Array((13, "41.6"), (1, "45.2136"))),
+ (3, Array((18, "42.6")))
+ )
+ val stream = env.fromCollection(data)
+ tEnv.registerDataSet("T", stream, 'a, 'b)
+
+ val sqlQuery = "" +
+ "SELECT a, b, x, y " +
+ "FROM " +
+ " (SELECT a, b FROM T WHERE a < 3) as tf, " +
+ " UNNEST(tf.b) as A (x, y) " +
+ "WHERE x > a"
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = List(
+ "1,[(12,45.6), (2,45.612)],12,45.6",
+ "1,[(12,45.6), (2,45.612)],2,45.612",
+ "2,[(13,41.6), (1,45.2136)],13,41.6").mkString(", ")
+ val results = result.toDataSet[Row].collect().map(_.toString)
+ assertEquals(expected, results.sorted.mkString(", "))
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SetOperatorsITCase.scala
new file mode 100644
index 0000000..8a59feb
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SetOperatorsITCase.scala
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+import scala.util.Random
+
+@RunWith(classOf[Parameterized])
+class SetOperatorsITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testUnionAll(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 UNION ALL (SELECT f FROM t2)"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 UNION (SELECT f FROM t2)"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.getSmall3TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'd, 'e, 'f)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnionWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM (" +
+ "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))" +
+ "WHERE b < 2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hallo\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testUnionWithAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT count(c) FROM (" +
+ "SELECT * FROM t1 UNION ALL (SELECT a, b, c FROM t2))"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "18"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testExcept(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 EXCEPT (SELECT c FROM t2)"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = env.fromElements((1, 1L, "Hi"))
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ @Ignore
+ // calcite sql parser doesn't support EXCEPT ALL
+ def testExceptAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 EXCEPT ALL SELECT c FROM t2"
+
+ val data1 = new mutable.MutableList[Int]
+ data1 += (1, 1, 1, 2, 2)
+ val data2 = new mutable.MutableList[Int]
+ data2 += (1, 2, 2, 3)
+ val ds1 = env.fromCollection(data1)
+ val ds2 = env.fromCollection(data2)
+
+ tEnv.registerDataSet("t1", ds1, 'c)
+ tEnv.registerDataSet("t2", ds2, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1\n1"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testExceptWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM (" +
+ "SELECT * FROM t1 EXCEPT (SELECT a, b, c FROM t2))" +
+ "WHERE b < 2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get5TupleDataSet(env)
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'd, 'c, 'e)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersect(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 INTERSECT SELECT c FROM t2"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val data = new mutable.MutableList[(Int, Long, String)]
+ data.+=((1, 1L, "Hi"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((2, 2L, "Hello"))
+ data.+=((3, 2L, "Hello world!"))
+ val ds2 = env.fromCollection(Random.shuffle(data))
+
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hi\n" + "Hello\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ @Ignore
+ // calcite sql parser doesn't support INTERSECT ALL
+ def testIntersectAll(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM t1 INTERSECT ALL SELECT c FROM t2"
+
+ val data1 = new mutable.MutableList[Int]
+ data1 += (1, 1, 1, 2, 2)
+ val data2 = new mutable.MutableList[Int]
+ data2 += (1, 2, 2, 3)
+ val ds1 = env.fromCollection(data1)
+ val ds2 = env.fromCollection(data2)
+
+ tEnv.registerDataSet("t1", ds1, 'c)
+ tEnv.registerDataSet("t2", ds2, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "1\n2\n2"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testIntersectWithFilter(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT c FROM ((SELECT * FROM t1) INTERSECT (SELECT * FROM t2)) WHERE a > 1"
+
+ val ds1 = CollectionDataSets.getSmall3TupleDataSet(env)
+ val ds2 = CollectionDataSets.get3TupleDataSet(env)
+
+ tEnv.registerDataSet("t1", ds1, 'a, 'b, 'c)
+ tEnv.registerDataSet("t2", ds2, 'a, 'b, 'c)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello\n" + "Hello world\n"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SortITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SortITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SortITCase.scala
new file mode 100644
index 0000000..4672ec3
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/SortITCase.scala
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql
+
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.api.scala.{ExecutionEnvironment, _}
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.SortTestUtils._
+import org.apache.flink.table.runtime.utils.TableProgramsClusterTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+import scala.collection.mutable
+
+@RunWith(classOf[Parameterized])
+class SortITCase(mode: TestExecutionMode, configMode: TableConfigMode)
+ extends TableProgramsClusterTestBase(mode, configMode) {
+
+ private def getExecutionEnvironment = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ // set the parallelism explicitly to make sure the query is executed in
+ // a distributed manner
+ env.setParallelism(3)
+ env
+ }
+
+ @Test
+ def testOrderByMultipleFieldsWithSql(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC, _2 DESC"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ (- x.productElement(0).asInstanceOf[Int], - x.productElement(1).asInstanceOf[Long]))
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ def rowOrdering = Ordering.by((r : Row) => {
+ // ordering for this tuple will fall into the previous defined tupleOrdering,
+ // so we just need to return the field by their defining sequence
+ (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
+ })
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(rowOrdering)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByWithOffset(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 DESC OFFSET 2 ROWS"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ - x.productElement(0).asInstanceOf[Int] )
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings, 2, 21)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results.
+ filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => -r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByWithOffsetAndFetch(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _1 OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ x.productElement(0).asInstanceOf[Int] )
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings, 2, 7)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(Ordering.by((r : Row) => r.getField(0).asInstanceOf[Int]))
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testOrderByLimit(): Unit = {
+ val env = getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT * FROM MyTable ORDER BY _2, _1 LIMIT 5"
+
+ implicit def tupleOrdering[T <: Product] = Ordering.by((x : T) =>
+ (x.productElement(1).asInstanceOf[Long], x.productElement(0).asInstanceOf[Int]) )
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds)
+
+ val expected = sortExpectedly(tupleDataSetStrings, 0, 5)
+ // squash all rows inside a partition into one element
+ val results = tEnv.sql(sqlQuery).toDataSet[Row].mapPartition(rows => {
+ // the rows need to be copied in object reuse mode
+ val copied = new mutable.ArrayBuffer[Row]
+ rows.foreach(r => copied += Row.copy(r))
+ Seq(copied)
+ }).collect()
+
+ def rowOrdering = Ordering.by((r : Row) => {
+ // ordering for this tuple will fall into the previous defined tupleOrdering,
+ // so we just need to return the field by their defining sequence
+ (r.getField(0).asInstanceOf[Int], r.getField(1).asInstanceOf[Long])
+ })
+
+ val result = results
+ .filterNot(_.isEmpty)
+ // sort all partitions by their head element to verify the order across partitions
+ .sortBy(_.head)(rowOrdering)
+ .reduceLeft(_ ++ _)
+
+ TestBaseUtils.compareOrderedResultAsText(result.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableEnvironmentITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableEnvironmentITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableEnvironmentITCase.scala
new file mode 100644
index 0000000..b7f1bb1
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableEnvironmentITCase.scala
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableEnvironmentITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testSQLTable(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env)
+ tEnv.registerDataSet("MyTable", ds, 'a, 'b, 'c)
+
+ val sqlQuery = "SELECT * FROM MyTable WHERE a > 9"
+
+ val result = tEnv.sql(sqlQuery).select('a.avg, 'b.sum, 'c.count)
+
+ val expected = "15,65,12"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testTableSQLTable(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val t1 = ds.filter('a > 9)
+
+ tEnv.registerTable("MyTable", t1)
+
+ val sqlQuery = "SELECT avg(a) as a1, sum(b) as b1, count(c) as c1 FROM MyTable"
+
+ val result = tEnv.sql(sqlQuery).select('a1 + 1, 'b1 - 5, 'c1)
+
+ val expected = "16,60,12"
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testMultipleSQLQueries(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ tEnv.registerTable("MyTable", t)
+
+ val sqlQuery = "SELECT a as aa FROM MyTable WHERE b = 6"
+ val result1 = tEnv.sql(sqlQuery)
+ tEnv.registerTable("ResTable", result1)
+
+ val sqlQuery2 = "SELECT count(aa) FROM ResTable"
+ val result2 = tEnv.sql(sqlQuery2)
+
+ val expected = "6"
+ val results = result2.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testSelectWithCompositeType(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val sqlQuery = "SELECT MyTable.a2, MyTable.a1._2 FROM MyTable"
+
+ val ds = env.fromElements(((12, true), "Hello")).toTable(tEnv).as('a1, 'a2)
+ tEnv.registerTable("MyTable", ds)
+
+ val result = tEnv.sql(sqlQuery)
+
+ val expected = "Hello,true\n"
+
+ val results = result.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableSourceITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableSourceITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableSourceITCase.scala
new file mode 100644
index 0000000..504ab90
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/sql/TableSourceITCase.scala
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.sql
+
+import org.apache.flink.api.scala.ExecutionEnvironment
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.runtime.utils.{CommonTestData, TableProgramsCollectionTestBase}
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class TableSourceITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testCsvTableSource(): Unit = {
+
+ val csvTable = CommonTestData.getCsvTableSource
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ tEnv.registerTableSource("csvTable", csvTable)
+ val results = tEnv.sql(
+ "SELECT id, `first`, `last`, score FROM csvTable").collect()
+
+ val expected = Seq(
+ "1,Mike,Smith,12.3",
+ "2,Bob,Taylor,45.6",
+ "3,Sam,Miller,7.89",
+ "4,Peter,Smith,0.12",
+ "5,Liz,Williams,34.5",
+ "6,Sally,Miller,6.78",
+ "7,Alice,Smith,90.1",
+ "8,Kelly,Williams,2.34").mkString("\n")
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testNested(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tableEnv = TableEnvironment.getTableEnvironment(env, config)
+ val nestedTable = CommonTestData.getNestedTableSource
+
+ tableEnv.registerTableSource("NestedPersons", nestedTable)
+
+ val result = tableEnv.sql("SELECT NestedPersons.firstName, NestedPersons.lastName," +
+ "NestedPersons.address.street, NestedPersons.address.city AS city " +
+ "FROM NestedPersons " +
+ "WHERE NestedPersons.address.city LIKE 'Dublin'").collect()
+
+ val expected = "Bob,Taylor,Pearse Street,Dublin"
+
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/f1fafc0e/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/AggregateITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/AggregateITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/AggregateITCase.scala
new file mode 100644
index 0000000..457142c
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/runtime/batch/table/AggregateITCase.scala
@@ -0,0 +1,379 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.runtime.batch.table
+
+import java.math.BigDecimal
+
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.util.CollectionDataSets
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.runtime.utils.JavaUserDefinedAggFunctions.WeightedAvgWithMergeAndReset
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.functions.aggfunctions.CountAggFunction
+import org.apache.flink.table.runtime.utils.TableProgramsCollectionTestBase
+import org.apache.flink.table.runtime.utils.TableProgramsTestBase.TableConfigMode
+import org.apache.flink.test.util.TestBaseUtils
+import org.apache.flink.types.Row
+import org.junit._
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+import scala.collection.JavaConverters._
+
+@RunWith(classOf[Parameterized])
+class AggregationsITCase(
+ configMode: TableConfigMode)
+ extends TableProgramsCollectionTestBase(configMode) {
+
+ @Test
+ def testAggregationTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
+ .select('_1.sum, '_1.sum0, '_1.min, '_1.max, '_1.count, '_1.avg)
+
+ val results = t.toDataSet[Row].collect()
+ val expected = "231,231,1,21,21,11"
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testWorkingAggregationDataTypes(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ .select('_1.avg, '_2.avg, '_3.avg, '_4.avg, '_5.avg, '_6.avg, '_7.count)
+
+ val expected = "1,1,1,1,1.5,1.5,2"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements(
+ (1: Byte, 1: Short),
+ (2: Byte, 2: Short)).toTable(tEnv)
+ .select('_1.avg, '_1.sum, '_1.count, '_2.avg, '_2.sum)
+
+ val expected = "1,3,2,1,3"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationWithArithmetic(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ .select(('_1 + 2).avg + 2, '_2.count + 5)
+
+ val expected = "5.5,7"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationWithTwoCount(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements((1f, "Hello"), (2f, "Ciao")).toTable(tEnv)
+ .select('_1.count, '_2.count)
+
+ val expected = "2,2"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAggregationAfterProjection(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, "Hello"),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, "Ciao")).toTable(tEnv)
+ .select('_1, '_2, '_3)
+ .select('_1.avg, '_2.sum, '_3.count)
+
+ val expected = "1,3,2"
+ val result = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(result.asJava, expected)
+ }
+
+ @Test
+ def testSQLStyleAggregations(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select(
+ """Sum( a) as a1, a.sum as a2,
+ |Min (a) as b1, a.min as b2,
+ |Max (a ) as c1, a.max as c2,
+ |Avg ( a ) as d1, a.avg as d2,
+ |Count(a) as e1, a.count as e2
+ """.stripMargin)
+
+ val expected = "231,231,1,1,21,21,11,11,21,21"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testPojoAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val input = env.fromElements(
+ WC("hello", 1),
+ WC("hello", 1),
+ WC("ciao", 1),
+ WC("hola", 1),
+ WC("hola", 1))
+ val expr = input.toTable(tEnv)
+ val result = expr
+ .groupBy('word)
+ .select('word, 'frequency.sum as 'frequency)
+ .filter('frequency === 2)
+ .toDataSet[WC]
+
+ val mappedResult = result.map(w => (w.word, w.frequency * 10)).collect()
+ val expected = "(hello,20)\n" + "(hola,20)"
+ TestBaseUtils.compareResultAsText(mappedResult.asJava, expected)
+ }
+
+ @Test
+ def testDistinct(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ val distinct = ds.select('b).distinct()
+
+ val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
+ val results = distinct.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testDistinctAfterAggregate(): Unit = {
+ val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ val distinct = ds.groupBy('a, 'e).select('e).distinct()
+
+ val expected = "1\n" + "2\n" + "3\n"
+ val results = distinct.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregate(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+ val countFun = new CountAggFunction
+ val wAvgFun = new WeightedAvgWithMergeAndReset
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('b, 'a.sum, countFun('c), wAvgFun('b, 'a), wAvgFun('a, 'a))
+
+ val expected = "1,1,1,1,1\n" + "2,5,2,2,2\n" + "3,15,3,3,5\n" + "4,34,4,4,8\n" +
+ "5,65,5,5,13\n" + "6,111,6,6,18\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupingKeyForwardIfNotUsed(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('a.sum)
+
+ val expected = "1\n" + "5\n" + "15\n" + "34\n" + "65\n" + "111\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupNoAggregation(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env)
+ .toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('a.sum as 'd, 'b)
+ .groupBy('b, 'd)
+ .select('b)
+
+ val expected = "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithLongKeys(): Unit = {
+ // This uses very long keys to force serialized comparison.
+ // With short keys, the normalized key is sufficient.
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val ds = env.fromElements(
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhaa", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2),
+ ("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhab", 1, 2))
+ .rebalance().setParallelism(2).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('a, 'b)
+ .select('c.sum)
+
+ val expected = "10\n" + "8\n"
+ val results = ds.collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithConstant1(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('a, 4 as 'four, 'b)
+ .groupBy('four, 'a)
+ .select('four, 'b.sum)
+
+ val expected = "4,2\n" + "4,3\n" + "4,5\n" + "4,5\n" + "4,5\n" + "4,6\n" +
+ "4,6\n" + "4,6\n" + "4,3\n" + "4,4\n" + "4,6\n" + "4,1\n" + "4,4\n" +
+ "4,4\n" + "4,5\n" + "4,6\n" + "4,2\n" + "4,3\n" + "4,4\n" + "4,5\n" + "4,6\n"
+ val results = t.toDataSet[Row].collect()
+
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithConstant2(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .select('b, 4 as 'four, 'a)
+ .groupBy('b, 'four)
+ .select('four, 'a.sum)
+
+ val expected = "4,1\n" + "4,5\n" + "4,15\n" + "4,34\n" + "4,65\n" + "4,111\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithExpression(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
+ .groupBy('e, 'b % 3)
+ .select('c.min, 'e, 'a.avg, 'd.count)
+
+ val expected = "0,1,1,1\n" + "3,2,3,3\n" + "7,1,4,2\n" + "14,2,5,1\n" +
+ "5,3,4,2\n" + "2,1,3,2\n" + "1,2,3,3\n" + "12,3,5,1"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testGroupedAggregateWithFilter(): Unit = {
+
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env, config)
+
+ val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
+ .groupBy('b)
+ .select('b, 'a.sum)
+ .where('b === 2)
+
+ val expected = "2,5\n"
+ val results = t.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+
+ @Test
+ def testAnalyticAggregation(): Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+ val ds = env.fromElements(
+ (1: Byte, 1: Short, 1, 1L, 1.0f, 1.0d, BigDecimal.ONE),
+ (2: Byte, 2: Short, 2, 2L, 2.0f, 2.0d, new BigDecimal(2))).toTable(tEnv)
+ val res = ds.select(
+ '_1.stddevPop, '_2.stddevPop, '_3.stddevPop, '_4.stddevPop, '_5.stddevPop,
+ '_6.stddevPop, '_7.stddevPop,
+ '_1.stddevSamp, '_2.stddevSamp, '_3.stddevSamp, '_4.stddevSamp, '_5.stddevSamp,
+ '_6.stddevSamp, '_7.stddevSamp,
+ '_1.varPop, '_2.varPop, '_3.varPop, '_4.varPop, '_5.varPop,
+ '_6.varPop, '_7.varPop,
+ '_1.varSamp, '_2.varSamp, '_3.varSamp, '_4.varSamp, '_5.varSamp,
+ '_6.varSamp, '_7.varSamp)
+ val expected =
+ "0,0,0," +
+ "0,0.5,0.5,0.5," +
+ "1,1,1," +
+ "1,0.70710677,0.7071067811865476,0.7071067811865476," +
+ "0,0,0," +
+ "0,0.25,0.25,0.25," +
+ "1,1,1," +
+ "1,0.5,0.5,0.5"
+ val results = res.toDataSet[Row].collect()
+ TestBaseUtils.compareResultAsText(results.asJava, expected)
+ }
+}
+
+case class WC(word: String, frequency: Long)
[14/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala
new file mode 100644
index 0000000..6ca607b
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/AggregationsTest.scala
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+/**
+ * Test for testing aggregate plans.
+ */
+class AggregationsTest extends TableTestBase {
+
+ @Test
+ def testGroupAggregateWithFilter(): Unit = {
+
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val resultTable = sourceTable.groupBy('a)
+ .select('a, 'a.avg, 'b.sum, 'c.count)
+ .where('a === 1)
+
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", "=(a, 1)")
+ )
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ calcNode,
+ term("groupBy", "a"),
+ term("select",
+ "a",
+ "AVG(a) AS TMP_0",
+ "SUM(b) AS TMP_1",
+ "COUNT(c) AS TMP_2")
+ )
+
+ util.verifyTable(resultTable,expected)
+ }
+
+ @Test
+ def testAggregate(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+ val resultTable = sourceTable.select('a.avg,'b.sum,'c.count)
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ batchTableNode(0),
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS TMP_0",
+ "SUM(b) AS TMP_1",
+ "COUNT(c) AS TMP_2")
+ )
+ util.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testAggregateWithFilter(): Unit = {
+ val util = batchTestUtil()
+ val sourceTable = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+
+ val resultTable = sourceTable.select('a,'b,'c).where('a === 1)
+ .select('a.avg,'b.sum,'c.count)
+
+ val calcNode = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ // ReduceExpressionsRule will add cast for Project node by force
+ // if the input of the Project node has constant expression.
+ term("select", "CAST(1) AS a", "b", "c"),
+ term("where", "=(a, 1)")
+ )
+
+ val setValues = unaryNode(
+ "DataSetValues",
+ calcNode,
+ tuples(List(null,null,null)),
+ term("values","a","b","c")
+ )
+
+ val union = unaryNode(
+ "DataSetUnion",
+ setValues,
+ term("union","a","b","c")
+ )
+
+ val expected = unaryNode(
+ "DataSetAggregate",
+ union,
+ term("select",
+ "AVG(a) AS TMP_0",
+ "SUM(b) AS TMP_1",
+ "COUNT(c) AS TMP_2")
+ )
+
+ util.verifyTable(resultTable, expected)
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CalcITCase.scala
deleted file mode 100644
index b78dd91..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CalcITCase.scala
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import java.sql.{Date, Time, Timestamp}
-import java.util
-
-import org.apache.flink.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala.batch.utils.{TableProgramsCollectionTestBase, TableProgramsTestBase}
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.test.util.TestBaseUtils
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class CalcITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testSimpleSelectAll(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv).select('_1, '_2, '_3)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectAllWithAs(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('a, 'b, 'c)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectWithNaming(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
- .select('a, 'b)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
- "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleSelectRenameAll(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1 as 'a, '_2 as 'b, '_3 as 'c)
- .select('a, 'b)
-
- val expected = "1,1\n" + "2,2\n" + "3,2\n" + "4,3\n" + "5,3\n" + "6,3\n" + "7,4\n" +
- "8,4\n" + "9,4\n" + "10,4\n" + "11,5\n" + "12,5\n" + "13,5\n" + "14,5\n" + "15,5\n" +
- "16,6\n" + "17,6\n" + "18,6\n" + "19,6\n" + "20,6\n" + "21,6\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSelectStar(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c).select('*)
-
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" +
- "4,3,Hello world, how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" +
- "7,4,Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" +
- "11,5,Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" +
- "15,5,Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" +
- "19,6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(false) )
-
- val expected = "\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(true) )
- val expected = "1,1,Hi\n" + "2,2,Hello\n" + "3,2,Hello world\n" + "4,3,Hello world, " +
- "how are you?\n" + "5,3,I am fine.\n" + "6,3,Luke Skywalker\n" + "7,4," +
- "Comment#1\n" + "8,4,Comment#2\n" + "9,4,Comment#3\n" + "10,4,Comment#4\n" + "11,5," +
- "Comment#5\n" + "12,5,Comment#6\n" + "13,5,Comment#7\n" + "14,5,Comment#8\n" + "15,5," +
- "Comment#9\n" + "16,6,Comment#10\n" + "17,6,Comment#11\n" + "18,6,Comment#12\n" + "19," +
- "6,Comment#13\n" + "20,6,Comment#14\n" + "21,6,Comment#15\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnStringTupleField(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val filterDs = ds.filter( 'c.like("%world%") )
-
- val expected = "3,2,Hello world\n" + "4,3,Hello world, how are you?\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnIntegerTupleField(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 === 0 )
-
- val expected = "2,2,Hello\n" + "4,3,Hello world, how are you?\n" +
- "6,3,Luke Skywalker\n" + "8,4," + "Comment#2\n" + "10,4,Comment#4\n" +
- "12,5,Comment#6\n" + "14,5,Comment#8\n" + "16,6," +
- "Comment#10\n" + "18,6,Comment#12\n" + "20,6,Comment#14\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testNotEquals(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 !== 0)
- val expected = "1,1,Hi\n" + "3,2,Hello world\n" +
- "5,3,I am fine.\n" + "7,4,Comment#1\n" + "9,4,Comment#3\n" +
- "11,5,Comment#5\n" + "13,5,Comment#7\n" + "15,5,Comment#9\n" +
- "17,6,Comment#11\n" + "19,6,Comment#13\n" + "21,6,Comment#15\n"
- val results = filterDs.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testDisjunctivePredicate(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a < 2 || 'a > 20)
- val expected = "1,1,Hi\n" + "21,6,Comment#15\n"
- val results = filterDs.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testConsecutiveFilters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter('a % 2 !== 0).filter('b % 2 === 0)
- val expected = "3,2,Hello world\n" + "7,4,Comment#1\n" +
- "9,4,Comment#3\n" + "17,6,Comment#11\n" +
- "19,6,Comment#13\n" + "21,6,Comment#15\n"
- val results = filterDs.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterBasicType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.getStringDataSet(env)
-
- val filterDs = ds.toTable(tEnv, 'a).filter( 'a.like("H%") )
-
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hello world, how are you?\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testFilterOnCustomType(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds = CollectionDataSets.getCustomTypeDataSet(env)
- val filterDs = ds.toTable(tEnv, 'myInt as 'i, 'myLong as 'l, 'myString as 's)
- .filter( 's.like("%a%") )
-
- val expected = "3,3,Hello world, how are you?\n" + "3,4,I am fine.\n" + "3,5,Luke Skywalker\n"
- val results = filterDs.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testSimpleCalc(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1, '_2, '_3)
- .where('_1 < 7)
- .select('_1, '_3)
-
- val expected = "1,Hi\n" + "2,Hello\n" + "3,Hello world\n" +
- "4,Hello world, how are you?\n" + "5,I am fine.\n" + "6,Luke Skywalker\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCalcWithTwoFilters(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1, '_2, '_3)
- .where('_1 < 7 && '_2 === 3)
- .select('_1, '_3)
- .where('_1 === 4)
- .select('_1)
-
- val expected = "4\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCalcWithAggregation(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv)
- .select('_1, '_2, '_3)
- .where('_1 < 15)
- .groupBy('_2)
- .select('_1.min, '_2.count as 'cnt)
- .where('cnt > 3)
-
- val expected = "7,4\n" + "11,4\n"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testCalcJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.select('a, 'b).join(ds2).where('b === 'e).select('a, 'b, 'd, 'e, 'f)
- .where('b > 1).select('a, 'd).where('d === 2)
-
- val expected = "2,2\n" + "3,2\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testAdvancedDataTypes(): Unit = {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val t = env
- .fromElements((
- BigDecimal("78.454654654654654").bigDecimal,
- BigDecimal("4E+9999").bigDecimal,
- Date.valueOf("1984-07-12"),
- Time.valueOf("14:34:24"),
- Timestamp.valueOf("1984-07-12 14:34:24")))
- .toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .select('a, 'b, 'c, 'd, 'e, BigDecimal("11.2"), BigDecimal("11.2").bigDecimal,
- Date.valueOf("1984-07-12"), Time.valueOf("14:34:24"),
- Timestamp.valueOf("1984-07-12 14:34:24"))
-
- val expected = "78.454654654654654,4E+9999,1984-07-12,14:34:24,1984-07-12 14:34:24.0," +
- "11.2,11.2,1984-07-12,14:34:24,1984-07-12 14:34:24.0"
- val results = t.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUserDefinedScalarFunction() {
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env, config)
- tableEnv.registerFunction("hashCode", OldHashCode)
- tableEnv.registerFunction("hashCode", HashCode)
- val table = env.fromElements("a", "b", "c").toTable(tableEnv, 'text)
- val result = table.select("text.hashCode()")
- val results = result.toDataSet[Row].collect()
- val expected = "97\n98\n99"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
-
-object CalcITCase {
-
- @Parameterized.Parameters(name = "Table config = {0}")
- def parameters(): util.Collection[Array[java.lang.Object]] = {
- Seq[Array[AnyRef]](
- Array(TableProgramsTestBase.DEFAULT),
- Array(TableProgramsTestBase.NO_NULL)).asJava
- }
-}
-
-object HashCode extends ScalarFunction {
- def eval(s: String): Int = s.hashCode
-}
-
-object OldHashCode extends ScalarFunction {
- def eval(s: String): Int = -1
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CastingITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CastingITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CastingITCase.scala
deleted file mode 100644
index 0076b8e..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CastingITCase.scala
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.Types._
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.test.util.TestBaseUtils.compareResultAsText
-import org.apache.flink.types.Row
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class CastingITCase(configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testNumericAutocastInArithmetic() {
-
- val env = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements(
- (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d, 1L, 1001.1)).toTable(tableEnv)
- .select('_1 + 1, '_2 + 1, '_3 + 1L, '_4 + 1.0f,
- '_5 + 1.0d, '_6 + 1, '_7 + 1.0d, '_8 + '_1)
-
- val results = table.toDataSet[Row].collect()
- val expected = "2,2,2,2.0,2.0,2.0,2.0,1002.1"
- compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @throws[Exception]
- def testNumericAutocastInComparison() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
-
- val table = env.fromElements(
- (1.toByte, 1.toShort, 1, 1L, 1.0f, 1.0d),
- (2.toByte, 2.toShort, 2, 2L, 2.0f, 2.0d))
- .toTable(tableEnv, 'a, 'b, 'c, 'd, 'e, 'f)
- .filter('a > 1 && 'b > 1 && 'c > 1L && 'd > 1.0f && 'e > 1.0d && 'f > 1)
-
- val results = table.toDataSet[Row].collect()
- val expected: String = "2,2,2,2,2.0,2.0"
- compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @throws[Exception]
- def testCasting() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements((1, 0.0, 1L, true)).toTable(tableEnv)
- .select(
- // * -> String
- '_1.cast(STRING), '_2.cast(STRING), '_3.cast(STRING), '_4.cast(STRING),
- // NUMERIC TYPE -> Boolean
- '_1.cast(BOOLEAN), '_2.cast(BOOLEAN), '_3.cast(BOOLEAN),
- // NUMERIC TYPE -> NUMERIC TYPE
- '_1.cast(DOUBLE), '_2.cast(INT), '_3.cast(SHORT),
- // Boolean -> NUMERIC TYPE
- '_4.cast(DOUBLE),
- // identity casting
- '_1.cast(INT), '_2.cast(DOUBLE), '_3.cast(LONG), '_4.cast(BOOLEAN))
-
- val results = table.toDataSet[Row].collect()
- val expected = "1,0.0,1,true," + "true,false,true," +
- "1.0,0,1," + "1.0," + "1,0.0,1,true\n"
- compareResultAsText(results.asJava, expected)
- }
-
- @Test
- @throws[Exception]
- def testCastFromString() {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tableEnv = TableEnvironment.getTableEnvironment(env)
- val table = env.fromElements(("1", "true", "2.0")).toTable(tableEnv)
- .select('_1.cast(BYTE), '_1.cast(SHORT), '_1.cast(INT), '_1.cast(LONG),
- '_3.cast(DOUBLE), '_3.cast(FLOAT), '_2.cast(BOOLEAN))
-
- val results = table.toDataSet[Row].collect()
- val expected = "1,1,1,1,2.0,2.0,true\n"
- compareResultAsText(results.asJava, expected)
- }
-}
-
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala
new file mode 100644
index 0000000..ece9acc
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/CompositeFlatteningTest.scala
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.batch.table
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.scala.createTypeInformation
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.batch.table.CompositeFlatteningTest.{TestCaseClass, giveMeCaseClass}
+import org.apache.flink.table.functions.ScalarFunction
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+
+class CompositeFlatteningTest extends TableTestBase {
+
+ @Test
+ def testMultipleFlatteningsTable(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table.select('a.flatten(), 'c, 'b.flatten())
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "a._1 AS a$_1",
+ "a._2 AS a$_2",
+ "c",
+ "b._1 AS b$_1",
+ "b._2 AS b$_2"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testNestedFlattening(): Unit = {
+ val util = batchTestUtil()
+ val table = util
+ .addTable[((((String, TestCaseClass), Boolean), String), String)]("MyTable", 'a, 'b)
+
+ val result = table.select('a.flatten(), 'b.flatten())
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "a._1 AS a$_1",
+ "a._2 AS a$_2",
+ "b"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testScalarFunctionAccess(): Unit = {
+ val util = batchTestUtil()
+ val table = util
+ .addTable[(String, Int)]("MyTable", 'a, 'b)
+
+ val result = table.select(
+ giveMeCaseClass().get("my"),
+ giveMeCaseClass().get("clazz"),
+ giveMeCaseClass().flatten())
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ s"${giveMeCaseClass.functionIdentifier}().my AS _c0",
+ s"${giveMeCaseClass.functionIdentifier}().clazz AS _c1",
+ s"${giveMeCaseClass.functionIdentifier}().my AS _c2",
+ s"${giveMeCaseClass.functionIdentifier}().clazz AS _c3"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
+
+object CompositeFlatteningTest {
+
+ case class TestCaseClass(my: String, clazz: Int)
+
+ object giveMeCaseClass extends ScalarFunction {
+ def eval(): TestCaseClass = {
+ TestCaseClass("hello", 42)
+ }
+
+ override def getResultType(signature: Array[Class[_]]): TypeInformation[_] = {
+ createTypeInformation[TestCaseClass]
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala
new file mode 100644
index 0000000..4a38741
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExplainTest.scala
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.apache.flink.test.util.MultipleProgramsTestBase
+import org.junit.Assert.assertEquals
+import org.junit._
+
+class ExplainTest
+ extends MultipleProgramsTestBase(MultipleProgramsTestBase.TestExecutionMode.CLUSTER) {
+
+ val testFilePath = ExplainTest.this.getClass.getResource("/").getFile
+
+ @Test
+ def testFilterWithoutExtended() : Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements((1, "hello"))
+ .toTable(tEnv, 'a, 'b)
+ .filter("a % 2 = 0")
+
+ val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testFilter0.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testFilterWithExtended() : Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements((1, "hello"))
+ .toTable(tEnv, 'a, 'b)
+ .filter("a % 2 = 0")
+
+ val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testFilter1.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testJoinWithoutExtended() : Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
+ val table = table1.join(table2).where("b = d").select("a, c")
+
+ val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testJoin0.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testJoinWithExtended() : Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'c, 'd)
+ val table = table1.join(table2).where("b = d").select("a, c")
+
+ val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testJoin1.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testUnionWithoutExtended() : Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table = table1.unionAll(table2)
+
+ val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testUnion0.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+ @Test
+ def testUnionWithExtended() : Unit = {
+ val env = ExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table = table1.unionAll(table2)
+
+ val result = tEnv.explain(table, true).replaceAll("\\r\\n", "\n")
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testUnion1.out").mkString.replaceAll("\\r\\n", "\n")
+ assertEquals(source, result)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala
new file mode 100644
index 0000000..c35a454
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/ExpressionReductionTest.scala
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.batch.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = batchTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+
+ val expected = unaryNode(
+ "DataSetCalc",
+ batchTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala
index 93e25f8..a174c8b 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/FieldProjectionTest.scala
@@ -20,9 +20,8 @@ package org.apache.flink.table.api.scala.batch.table
import org.apache.flink.api.scala._
import org.apache.flink.table.api.scala._
import org.apache.flink.table.api.scala.batch.table.FieldProjectionTest._
-import org.apache.flink.table.expressions.{Upper, WindowReference}
+import org.apache.flink.table.expressions.Upper
import org.apache.flink.table.functions.ScalarFunction
-import org.apache.flink.table.plan.logical.TumblingGroupWindow
import org.apache.flink.table.utils.TableTestUtil._
import org.apache.flink.table.utils.{TableTestBase, _}
import org.junit.Test
@@ -33,12 +32,9 @@ import org.junit.Test
*/
class FieldProjectionTest extends TableTestBase {
- val util: BatchTableTestUtil = batchTestUtil()
-
- val streamUtil: StreamTableTestUtil = streamTestUtil()
-
@Test
def testSimpleSelect(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable = sourceTable.select('a, 'b)
@@ -53,6 +49,7 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectAllFields(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable1 = sourceTable.select('*)
val resultTable2 = sourceTable.select('a, 'b, 'c, 'd)
@@ -65,6 +62,7 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectAggregation(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable = sourceTable.select('a.sum, 'b.max)
@@ -92,9 +90,10 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectFunction(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
- util.tEnv.registerFunction("hashCode", MyHashCode)
+ util.tableEnv.registerFunction("hashCode", MyHashCode)
val resultTable = sourceTable.select("hashCode(c), b")
@@ -109,6 +108,7 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectFromGroupedTable(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable = sourceTable.groupBy('a, 'c).select('a)
@@ -131,6 +131,7 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectAllFieldsFromGroupedTable(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable = sourceTable.groupBy('a, 'c).select('a, 'c)
@@ -149,6 +150,7 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectAggregationFromGroupedTable(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable = sourceTable.groupBy('c).select('a.sum)
@@ -173,6 +175,7 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectFromGroupedTableWithNonTrivialKey(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable = sourceTable.groupBy(Upper('c) as 'k).select('a.sum)
@@ -197,6 +200,7 @@ class FieldProjectionTest extends TableTestBase {
@Test
def testSelectFromGroupedTableWithFunctionKey(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd)
val resultTable = sourceTable.groupBy(MyHashCode('c) as 'k).select('a.sum)
@@ -220,67 +224,8 @@ class FieldProjectionTest extends TableTestBase {
}
@Test
- def testSelectFromStreamingWindow(): Unit = {
- val sourceTable = streamUtil
- .addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
- val resultTable = sourceTable
- .window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w)
- .select(Upper('c).count, 'a.sum)
-
- val expected =
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "c", "a", "rowtime", "UPPER(c) AS $f3")
- ),
- term("window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'rowtime,
- 5.millis)),
- term("select", "COUNT($f3) AS TMP_0", "SUM(a) AS TMP_1")
- )
-
- streamUtil.verifyTable(resultTable, expected)
- }
-
- @Test
- def testSelectFromStreamingGroupedWindow(): Unit = {
- val sourceTable = streamUtil
- .addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
- val resultTable = sourceTable
- .window(Tumble over 5.millis on 'rowtime as 'w)
- .groupBy('w, 'b)
- .select(Upper('c).count, 'a.sum, 'b)
-
- val expected = unaryNode(
- "DataStreamCalc",
- unaryNode(
- "DataStreamGroupWindowAggregate",
- unaryNode(
- "DataStreamCalc",
- streamTableNode(0),
- term("select", "c", "a", "b", "rowtime", "UPPER(c) AS $f4")
- ),
- term("groupBy", "b"),
- term("window",
- TumblingGroupWindow(
- WindowReference("w"),
- 'rowtime,
- 5.millis)),
- term("select", "b", "COUNT($f4) AS TMP_0", "SUM(a) AS TMP_1")
- ),
- term("select", "TMP_0", "TMP_1", "b")
- )
-
- streamUtil.verifyTable(resultTable, expected)
- }
-
- @Test
def testSelectFromAggregatedPojoTable(): Unit = {
+ val util = batchTestUtil()
val sourceTable = util.addTable[WC]("MyTable", 'word, 'frequency)
val resultTable = sourceTable
.groupBy('word)
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala
index 12e8897..84a6738 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/GroupWindowTest.scala
@@ -18,9 +18,8 @@
package org.apache.flink.table.api.scala.batch.table
import org.apache.flink.api.scala._
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMerge
import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.ValidationException
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
import org.apache.flink.table.expressions.WindowReference
import org.apache.flink.table.plan.logical._
import org.apache.flink.table.utils.TableTestBase
@@ -33,84 +32,6 @@ class GroupWindowTest extends TableTestBase {
// Common test
//===============================================================================================
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
- val overAgg = new OverAgg0
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('string,'w)
- .select(overAgg('long, 'int))
- }
-
- @Test(expected = classOf[ValidationException])
- def testGroupByWithoutWindowAlias(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('string)
- .select('string, 'int.count)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidRowTimeRef(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- table
- .window(Tumble over 5.milli on 'long as 'w)
- .groupBy('w, 'string)
- .select('string, 'int.count)
- .window(Slide over 5.milli every 1.milli on 'int as 'w2) // 'Int does not exist in input.
- .groupBy('w2)
- .select('string)
- }
-
- //===============================================================================================
- // Tumbling Windows
- //===============================================================================================
-
- @Test(expected = classOf[ValidationException])
- def testInvalidProcessingTimeDefinition(): Unit = {
- val util = batchTestUtil()
- // proctime is not allowed
- util.addTable[(Long, Int, String)]('long.proctime, 'int, 'string)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidProcessingTimeDefinition2(): Unit = {
- val util = batchTestUtil()
- // proctime is not allowed
- util.addTable[(Long, Int, String)]('long, 'int, 'string, 'proctime.proctime)
- }
-
- @Test(expected = classOf[ValidationException])
- def testInvalidEventTimeDefinition(): Unit = {
- val util = batchTestUtil()
- // definition must not extend schema
- util.addTable[(Long, Int, String)]('long, 'int, 'string, 'rowtime.rowtime)
- }
-
- @Test(expected = classOf[ValidationException])
- def testTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Tumble over 2.minutes on 'rowtime as 'w)
- .groupBy('w, 'long)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
@Test
def testEventTimeTumblingGroupWindowOverCount(): Unit = {
val util = batchTestUtil()
@@ -176,20 +97,6 @@ class GroupWindowTest extends TableTestBase {
util.verifyTable(windowedTable, expected)
}
- @Test(expected = classOf[ValidationException])
- def testAllTumblingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Tumble over 2.minutes on 'rowtime as 'w)
- .groupBy('w)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
@Test
def testAllEventTimeTumblingGroupWindowOverTime(): Unit = {
val util = batchTestUtil()
@@ -242,20 +149,6 @@ class GroupWindowTest extends TableTestBase {
// Sliding Windows
//===============================================================================================
- @Test(expected = classOf[ValidationException])
- def testSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Slide over 2.minutes every 1.minute on 'rowtime as 'w)
- .groupBy('w, 'long)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
@Test
def testEventTimeSlidingGroupWindowOverTime(): Unit = {
val util = batchTestUtil()
@@ -324,20 +217,6 @@ class GroupWindowTest extends TableTestBase {
util.verifyTable(windowedTable, expected)
}
- @Test(expected = classOf[ValidationException])
- def testAllSlidingGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Slide over 2.minutes every 1.minute on 'long as 'w)
- .groupBy('w)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
@Test
def testAllEventTimeSlidingGroupWindowOverTime(): Unit = {
val util = batchTestUtil()
@@ -436,32 +315,4 @@ class GroupWindowTest extends TableTestBase {
util.verifyTable(windowedTable, expected)
}
- @Test(expected = classOf[ValidationException])
- def testSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Session withGap 2.minutes on 'rowtime as 'w)
- .groupBy('w, 'long)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
- @Test(expected = classOf[ValidationException])
- def testAllSessionGroupWindowWithInvalidUdAggArgs(): Unit = {
- val util = batchTestUtil()
- val table = util.addTable[(Long, Int, String)]('long, 'int, 'string)
-
- val myWeightedAvg = new WeightedAvgWithMerge
-
- table
- .window(Session withGap 2.minutes on 'rowtime as 'w)
- .groupBy('w)
- // invalid function arguments
- .select(myWeightedAvg('int, 'string))
- }
-
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/JoinITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/JoinITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/JoinITCase.scala
deleted file mode 100644
index 8085a3c..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/JoinITCase.scala
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.{TableEnvironment, ValidationException}
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.table.utils.TableFunc2
-import org.apache.flink.test.util.MultipleProgramsTestBase.TestExecutionMode
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-
-@RunWith(classOf[Parameterized])
-class JoinITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithFilter(): Unit = {
-
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv).as('a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv).as('d, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e && 'b < 2).select('c, 'g)
-
- val expected = "Hi,Hallo\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithJoinFilter(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e && 'a < 6).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt\n" +
- "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testInnerJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('b === 'e && 'a < 6 && 'h < 'b).select('c, 'g)
-
- val results = joinT.toDataSet[Row].collect()
- val expected = "Hello world, how are you?,Hallo Welt wie\n" + "I am fine.,Hallo Welt wie\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).filter('a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
- "Hello world,ABC\n" + "I am fine.,HIJ\n" + "I am fine.,IJK\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithAggregation(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- // use different table env in order to let tmp table ids are the same
- val tEnv2 = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).where('a === 'd).select('g.count)
-
- val expected = "6"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithGroupedAggregation(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2)
- .where('a === 'd)
- .groupBy('a, 'd)
- .select('b.sum, 'g.count)
-
- val expected = "6,3\n" + "4,2\n" + "1,1"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinPushThroughJoin(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
- val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'j, 'k, 'l)
-
- val joinT = ds1.join(ds2)
- .where(Literal(true))
- .join(ds3)
- .where('a === 'd && 'e === 'k)
- .select('a, 'f, 'l)
-
- val expected = "2,1,Hello\n" + "2,1,Hello world\n" + "1,0,Hi"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithDisjunctivePred(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).filter('a === 'd && ('b === 'e || 'b === 'e - 10)).select('c, 'g)
-
- val expected = "Hi,Hallo\n" +
- "Hello,Hallo Welt\n" +
- "I am fine.,IJK"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testJoinWithExpressionPreds(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.join(ds2).filter('b === 'h + 1 && 'a - 1 === 'd + 2).select('c, 'g)
-
- val expected = "I am fine.,Hallo Welt\n" +
- "Luke Skywalker,Hallo Welt wie gehts?\n" +
- "Luke Skywalker,ABC\n" +
- "Comment#2,HIJ\n" +
- "Comment#2,IJK"
- val results = joinT.toDataSet[Row] collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testLeftJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.leftOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "Hello world,Hallo Welt wie gehts?\n" +
- "Hello world,ABC\n" + "Hello world, how are you?,null\n" + "I am fine.,HIJ\n" +
- "I am fine.,IJK\n" + "Luke Skywalker,null\n" + "Comment#1,null\n" + "Comment#2,null\n" +
- "Comment#3,null\n" + "Comment#4,null\n" + "Comment#5,null\n" + "Comment#6,null\n" +
- "Comment#7,null\n" + "Comment#8,null\n" + "Comment#9,null\n" + "Comment#10,null\n" +
- "Comment#11,null\n" + "Comment#12,null\n" + "Comment#13,null\n" + "Comment#14,null\n" +
- "Comment#15,null\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testRightJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.rightOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
- "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
- "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
- "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test(expected = classOf[ValidationException])
- def testLeftJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testFullJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testRightJoinWithNonEquiJoinPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 'h).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testLeftJoinWithLocalPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.leftOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testFullJoinWithLocalPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.fullOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test(expected = classOf[ValidationException])
- def testRightJoinWithLocalPredicate(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- ds1.rightOuterJoin(ds2, 'a === 'd && 'b < 3).select('c, 'g).toDataSet[Row].collect()
- }
-
- @Test
- def testFullOuterJoinWithMultipleKeys(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
- tEnv.getConfig.setNullCheck(true)
-
- val ds1 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get5TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f, 'g, 'h)
-
- val joinT = ds1.fullOuterJoin(ds2, 'a === 'd && 'b === 'h).select('c, 'g)
-
- val expected = "Hi,Hallo\n" + "Hello,Hallo Welt\n" + "null,Hallo Welt wie\n" +
- "Hello world,Hallo Welt wie gehts?\n" + "Hello world,ABC\n" + "null,BCD\n" + "null,CDE\n" +
- "null,DEF\n" + "null,EFG\n" + "null,FGH\n" + "null,GHI\n" + "I am fine.,HIJ\n" +
- "I am fine.,IJK\n" + "null,JKL\n" + "null,KLM\n" + "Luke Skywalker,null\n" +
- "Comment#1,null\n" + "Comment#2,null\n" + "Comment#3,null\n" + "Comment#4,null\n" +
- "Comment#5,null\n" + "Comment#6,null\n" + "Comment#7,null\n" + "Comment#8,null\n" +
- "Comment#9,null\n" + "Comment#10,null\n" + "Comment#11,null\n" + "Comment#12,null\n" +
- "Comment#13,null\n" + "Comment#14,null\n" + "Comment#15,null\n" +
- "Hello world, how are you?,null\n"
- val results = joinT.toDataSet[Row].collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUDTFJoinOnTuples(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data = List("hi#world", "how#are#you")
-
- val ds1 = env.fromCollection(data).toTable(tEnv, 'a)
- val func2 = new TableFunc2
-
- val joinDs = ds1.join(func2('a) as ('name, 'len))
-
- val results = joinDs.toDataSet[Row].collect()
- val expected = Seq(
- "hi#world,hi,2",
- "hi#world,world,5",
- "how#are#you,how,3",
- "how#are#you,are,3",
- "how#are#you,you,3").mkString("\n")
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SetOperatorsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SetOperatorsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SetOperatorsITCase.scala
deleted file mode 100644
index 67da532..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/batch/table/SetOperatorsITCase.scala
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.batch.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsCollectionTestBase
-import org.apache.flink.table.api.scala.batch.utils.TableProgramsTestBase.TableConfigMode
-import org.apache.flink.table.api.scala._
-import org.apache.flink.api.scala.util.CollectionDataSets
-import org.apache.flink.types.Row
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.test.util.TestBaseUtils
-import org.junit._
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-import scala.util.Random
-
-@RunWith(classOf[Parameterized])
-class SetOperatorsITCase(
- configMode: TableConfigMode)
- extends TableProgramsCollectionTestBase(configMode) {
-
- @Test
- def testUnionAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
-
- val unionDs = ds1.unionAll(ds2).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" + "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testUnion(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'd, 'e, 'f)
-
- val unionDs = ds1.union(ds2).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTernaryUnionAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val unionDs = ds1.unionAll(ds2).unionAll(ds3).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n" +
- "Hi\n" + "Hello\n" + "Hello world\n" +
- "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testTernaryUnion(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds3 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
-
- val unionDs = ds1.union(ds2).union(ds3).select('c)
-
- val results = unionDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMinusAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
-
- val minusDs = ds1.unionAll(ds1).unionAll(ds1)
- .minusAll(ds2.unionAll(ds2)).select('c)
-
- val results = minusDs.toDataSet[Row].collect()
- val expected = "Hi\n" +
- "Hello\n" + "Hello world\n" +
- "Hello\n" + "Hello world\n" +
- "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMinus(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'a, 'b, 'c)
-
- val minusDs = ds1.unionAll(ds1).unionAll(ds1)
- .minus(ds2.unionAll(ds2)).select('c)
-
- val results = minusDs.toDataSet[Row].collect()
- val expected = "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testMinusDifferentFieldNames(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = env.fromElements((1, 1L, "Hi")).toTable(tEnv, 'd, 'e, 'f)
-
- val minusDs = ds1.unionAll(ds1).unionAll(ds1)
- .minus(ds2.unionAll(ds2)).select('c)
-
- val results = minusDs.toDataSet[Row].collect()
- val expected = "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersect(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val data = new mutable.MutableList[(Int, Long, String)]
- data.+=((1, 1L, "Hi"))
- data.+=((2, 2L, "Hello"))
- data.+=((2, 2L, "Hello"))
- data.+=((3, 2L, "Hello world!"))
- val ds2 = env.fromCollection(Random.shuffle(data)).toTable(tEnv, 'a, 'b, 'c)
-
- val intersectDS = ds1.intersect(ds2).select('c).toDataSet[Row]
-
- val results = intersectDS.collect()
-
- val expected = "Hi\n" + "Hello\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectAll(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val data1 = new mutable.MutableList[Int]
- data1 += (1, 1, 1, 2, 2)
- val data2 = new mutable.MutableList[Int]
- data2 += (1, 2, 2, 2, 3)
- val ds1 = env.fromCollection(data1).toTable(tEnv, 'c)
- val ds2 = env.fromCollection(data2).toTable(tEnv, 'c)
-
- val intersectDS = ds1.intersectAll(ds2).select('c).toDataSet[Row]
-
- val expected = "1\n2\n2"
- val results = intersectDS.collect()
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectWithDifferentFieldNames(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'e, 'f, 'g)
-
- val intersectDs = ds1.intersect(ds2).select('c)
-
- val results = intersectDs.toDataSet[Row].collect()
- val expected = "Hi\n" + "Hello\n" + "Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-
- @Test
- def testIntersectWithScalarExpression(): Unit = {
- val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env, config)
-
- val ds1 = CollectionDataSets.getSmall3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a + 1, 'b, 'c)
- val ds2 = CollectionDataSets.get3TupleDataSet(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a + 1, 'b, 'c)
-
- val intersectDs = ds1.intersect(ds2)
-
- val results = intersectDs.toDataSet[Row].collect()
- val expected = "2,1,Hi\n" + "3,2,Hello\n" + "4,2,Hello world\n"
- TestBaseUtils.compareResultAsText(results.asJava, expected)
- }
-}
[11/44] flink git commit: [FLINK-6617][table] Improve JAVA and SCALA
logical plans consistent test
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowITCase.scala
deleted file mode 100644
index 253d54a..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/OverWindowITCase.scala
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.common.time.Time
-import org.apache.flink.api.scala._
-import org.apache.flink.table.api.scala.stream.sql.TimeTestUtil.EventTimeSourceFunction
-import org.apache.flink.streaming.api.functions.source.SourceFunction
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.api.watermark.Watermark
-import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment, TableException}
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamTestData, StreamingWithStateTestBase}
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit._
-import org.apache.flink.streaming.api.TimeCharacteristic
-import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
-
-import scala.collection.mutable
-
-class OverWindowITCase extends StreamingWithStateTestBase {
-
- val data = List(
- (1L, 1, "Hello"),
- (2L, 2, "Hello"),
- (3L, 3, "Hello"),
- (4L, 4, "Hello"),
- (5L, 5, "Hello"),
- (6L, 6, "Hello"),
- (7L, 7, "Hello World"),
- (8L, 8, "Hello World"),
- (20L, 20, "Hello World"))
-
- /**
- * All aggregates must be computed on the same window.
- */
- @Test(expected = classOf[TableException])
- def testMultiWindow(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
- "sum(a) OVER (PARTITION BY b ORDER BY proctime RANGE UNBOUNDED preceding) " +
- "from T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
- }
-
- @Test
- def testProcTimeBoundedPartitionedRowsOver(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setParallelism(1)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
- tEnv.registerTable("MyTable", t)
-
- val sqlQuery = "SELECT a, " +
- " SUM(c) OVER (" +
- " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW), " +
- " MIN(c) OVER (" +
- " PARTITION BY a ORDER BY proctime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) " +
- "FROM MyTable"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,0,0",
- "2,1,1",
- "2,3,1",
- "3,3,3",
- "3,7,3",
- "3,12,3",
- "4,6,6",
- "4,13,6",
- "4,21,6",
- "4,30,6",
- "5,10,10",
- "5,21,10",
- "5,33,10",
- "5,46,10",
- "5,60,10")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeBoundedNonPartitionedRowsOver(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env)
- .toTable(tEnv, 'a, 'b, 'c, 'd, 'e, 'proctime.proctime)
- tEnv.registerTable("MyTable", t)
-
- val sqlQuery = "SELECT a, " +
- " SUM(c) OVER (" +
- " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW), " +
- " MIN(c) OVER (" +
- " ORDER BY proctime ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) " +
- "FROM MyTable"
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,0,0",
- "2,1,0",
- "2,3,0",
- "3,6,0",
- "3,10,0",
- "3,15,0",
- "4,21,0",
- "4,28,0",
- "4,36,0",
- "4,45,0",
- "5,55,0",
- "5,66,1",
- "5,77,2",
- "5,88,3",
- "5,99,4")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeUnboundedPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- // for sum aggregation ensure that every time the order of each element is consistent
- env.setParallelism(1)
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "c, " +
- "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
- "sum(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding) " +
- "from T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello World,1,7", "Hello World,2,15", "Hello World,3,35",
- "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeUnboundedPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT c, cnt1 from " +
- "(SELECT " +
- "c, " +
- "count(a) " +
- " OVER (PARTITION BY c ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
- "as cnt1 from T1)"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello World,1", "Hello World,2", "Hello World,3",
- "Hello,1", "Hello,2", "Hello,3", "Hello,4", "Hello,5", "Hello,6")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRangeOver(): Unit = {
- val queryConfig =
- new StreamQueryConfig().withIdleStateRetentionTime(Time.hours(2), Time.hours(3))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- // for sum aggregation ensure that every time the order of each element is consistent
- env.setParallelism(1)
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "c, " +
- "count(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding), " +
- "sum(a) OVER (ORDER BY proctime RANGE UNBOUNDED preceding) " +
- "from T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row](queryConfig)
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello World,7,28", "Hello World,8,36", "Hello World,9,56",
- "Hello,1,1", "Hello,2,3", "Hello,3,6", "Hello,4,10", "Hello,5,15", "Hello,6,21")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testProcTimeUnboundedNonPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env.fromCollection(data).toTable(tEnv, 'a, 'b, 'c, 'proctime.proctime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "count(a) OVER (ORDER BY proctime ROWS BETWEEN UNBOUNDED preceding AND CURRENT ROW) " +
- "from T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("1", "2", "3", "4", "5", "6", "7", "8", "9")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRangeOver(): Unit = {
- val data = Seq(
- Left((1500L, (1L, 15, "Hello"))),
- Left((1600L, (1L, 16, "Hello"))),
- Left((1000L, (1L, 1, "Hello"))),
- Left((2000L, (2L, 2, "Hello"))),
- Right(1000L),
- Left((2000L, (2L, 2, "Hello"))),
- Left((2000L, (2L, 3, "Hello"))),
- Left((3000L, (3L, 3, "Hello"))),
- Right(2000L),
- Left((4000L, (4L, 4, "Hello"))),
- Right(3000L),
- Left((5000L, (5L, 5, "Hello"))),
- Right(5000L),
- Left((6000L, (6L, 6, "Hello"))),
- Left((6500L, (6L, 65, "Hello"))),
- Right(7000L),
- Left((9000L, (6L, 9, "Hello"))),
- Left((9500L, (6L, 18, "Hello"))),
- Left((9000L, (6L, 9, "Hello"))),
- Right(10000L),
- Left((10000L, (7L, 7, "Hello World"))),
- Left((11000L, (7L, 17, "Hello World"))),
- Left((11000L, (7L, 77, "Hello World"))),
- Right(12000L),
- Left((14000L, (7L, 18, "Hello World"))),
- Right(14000L),
- Left((15000L, (8L, 8, "Hello World"))),
- Right(17000L),
- Left((20000L, (20L, 20, "Hello World"))),
- Right(19000L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- " c, b, " +
- " COUNT(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
- " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
- " SUM(a) OVER (PARTITION BY c ORDER BY rowtime RANGE " +
- " BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW)" +
- " FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
- "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
- "Hello,3,4,9",
- "Hello,4,2,7",
- "Hello,5,2,9",
- "Hello,6,2,11", "Hello,65,2,12",
- "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
- "Hello World,7,1,7", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
- "Hello World,8,2,15",
- "Hello World,20,1,20")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedPartitionedRowsOver(): Unit = {
- val data = Seq(
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((3L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Left((1L, (7L, 7, "Hello World"))),
- Right(2L),
- Left((3L, (3L, 3, "Hello"))),
- Left((4L, (4L, 4, "Hello"))),
- Left((5L, (5L, 5, "Hello"))),
- Left((6L, (6L, 6, "Hello"))),
- Left((20L, (20L, 20, "Hello World"))),
- Right(6L),
- Left((8L, (8L, 8, "Hello World"))),
- Left((7L, (7L, 7, "Hello World"))),
- Right(20L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- " c, a, " +
- " COUNT(a) " +
- " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), " +
- " SUM(a) " +
- " OVER (PARTITION BY c ORDER BY rowtime ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
- "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
- "Hello,3,3,7", "Hello,4,3,9", "Hello,5,3,12",
- "Hello,6,3,15",
- "Hello World,7,1,7", "Hello World,7,2,14", "Hello World,7,3,21",
- "Hello World,7,3,21", "Hello World,8,3,22", "Hello World,20,3,35")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRangeOver(): Unit = {
- val data = Seq(
- Left((1500L, (1L, 15, "Hello"))),
- Left((1600L, (1L, 16, "Hello"))),
- Left((1000L, (1L, 1, "Hello"))),
- Left((2000L, (2L, 2, "Hello"))),
- Right(1000L),
- Left((2000L, (2L, 2, "Hello"))),
- Left((2000L, (2L, 3, "Hello"))),
- Left((3000L, (3L, 3, "Hello"))),
- Right(2000L),
- Left((4000L, (4L, 4, "Hello"))),
- Right(3000L),
- Left((5000L, (5L, 5, "Hello"))),
- Right(5000L),
- Left((6000L, (6L, 6, "Hello"))),
- Left((6500L, (6L, 65, "Hello"))),
- Right(7000L),
- Left((9000L, (6L, 9, "Hello"))),
- Left((9500L, (6L, 18, "Hello"))),
- Left((9000L, (6L, 9, "Hello"))),
- Right(10000L),
- Left((10000L, (7L, 7, "Hello World"))),
- Left((11000L, (7L, 17, "Hello World"))),
- Left((11000L, (7L, 77, "Hello World"))),
- Right(12000L),
- Left((14000L, (7L, 18, "Hello World"))),
- Right(14000L),
- Left((15000L, (8L, 8, "Hello World"))),
- Right(17000L),
- Left((20000L, (20L, 20, "Hello World"))),
- Right(19000L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- " c, b, " +
- " COUNT(a) " +
- " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW), " +
- " SUM(a) " +
- " OVER (ORDER BY rowtime RANGE BETWEEN INTERVAL '1' SECOND PRECEDING AND CURRENT ROW) " +
- " FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,15,2,2", "Hello,16,3,3",
- "Hello,2,6,9", "Hello,3,6,9", "Hello,2,6,9",
- "Hello,3,4,9",
- "Hello,4,2,7",
- "Hello,5,2,9",
- "Hello,6,2,11", "Hello,65,2,12",
- "Hello,9,2,12", "Hello,9,2,12", "Hello,18,3,18",
- "Hello World,7,4,25", "Hello World,17,3,21", "Hello World,77,3,21", "Hello World,18,1,7",
- "Hello World,8,2,15",
- "Hello World,20,1,20")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeBoundedNonPartitionedRowsOver(): Unit = {
-
- val data = Seq(
- Left((2L, (2L, 2, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((2L, (2L, 2, "Hello"))),
- Left((1L, (1L, 1, "Hello"))),
- Left((20L, (20L, 20, "Hello World"))), // early row
- Right(3L),
- Left((2L, (2L, 2, "Hello"))), // late row
- Left((3L, (3L, 3, "Hello"))),
- Left((4L, (4L, 4, "Hello"))),
- Left((5L, (5L, 5, "Hello"))),
- Left((6L, (6L, 6, "Hello"))),
- Left((7L, (7L, 7, "Hello World"))),
- Right(7L),
- Left((9L, (9L, 9, "Hello World"))),
- Left((8L, (8L, 8, "Hello World"))),
- Left((8L, (8L, 8, "Hello World"))),
- Right(20L))
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t1 = env
- .addSource[(Long, Int, String)](new EventTimeSourceFunction[(Long, Int, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val sqlQuery = "SELECT " +
- "c, a, " +
- " COUNT(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW), " +
- " SUM(a) OVER (ORDER BY rowtime ROWS BETWEEN 2 preceding AND CURRENT ROW) " +
- "FROM T1"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "Hello,1,1,1", "Hello,1,2,2", "Hello,1,3,3",
- "Hello,2,3,4", "Hello,2,3,5", "Hello,2,3,6",
- "Hello,3,3,7",
- "Hello,4,3,9", "Hello,5,3,12",
- "Hello,6,3,15", "Hello World,7,3,18",
- "Hello World,8,3,21", "Hello World,8,3,23",
- "Hello World,9,3,25",
- "Hello World,20,3,37")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- StreamITCase.clear
-
- val sqlQuery = "SELECT a, b, c, " +
- " SUM(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " COUNT(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " AVG(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MAX(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MIN(b) OVER (" +
- " PARTITION BY a ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (1, 1L, "Hello")),
- Left(14000002L, (1, 2L, "Hello")),
- Left(14000002L, (1, 3L, "Hello world")),
- Left(14000003L, (2, 2L, "Hello world")),
- Left(14000003L, (2, 3L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 4L, "Hello world")),
- Left(14000022L, (1, 5L, "Hello world")),
- Left(14000022L, (1, 6L, "Hello world")),
- Left(14000022L, (1, 7L, "Hello world")),
- Left(14000023L, (2, 4L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000030L))
-
- val t1 = env
- .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,1,Hello,6,3,2,3,1",
- "1,2,Hello,6,3,2,3,1",
- "1,3,Hello world,6,3,2,3,1",
- "1,1,Hi,7,4,1,3,1",
- "2,1,Hello,1,1,1,1,1",
- "2,2,Hello world,6,3,2,3,1",
- "2,3,Hello world,6,3,2,3,1",
- "1,4,Hello world,11,5,2,4,1",
- "1,5,Hello world,29,8,3,7,1",
- "1,6,Hello world,29,8,3,7,1",
- "1,7,Hello world,29,8,3,7,1",
- "2,4,Hello world,15,5,3,5,1",
- "2,5,Hello world,15,5,3,5,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.testResults = mutable.MutableList()
-
- val sqlQuery = "SELECT a, b, c, " +
- "SUM(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "count(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "avg(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "max(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "min(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row) " +
- "from T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (3, 1L, "Hello")),
- Left(14000003L, (1, 2L, "Hello")),
- Left(14000004L, (1, 3L, "Hello world")),
- Left(14000007L, (3, 2L, "Hello world")),
- Left(14000008L, (2, 2L, "Hello world")),
- Right(14000010L),
- Left(14000012L, (1, 5L, "Hello world")),
- Left(14000021L, (1, 6L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000020L),
- Left(14000024L, (3, 5L, "Hello world")),
- Left(14000026L, (1, 7L, "Hello world")),
- Left(14000025L, (1, 8L, "Hello world")),
- Left(14000022L, (1, 9L, "Hello world")),
- Right(14000030L))
-
- val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,2,Hello,2,1,2,2,2",
- "1,3,Hello world,5,2,2,3,2",
- "1,1,Hi,6,3,2,3,1",
- "2,1,Hello,1,1,1,1,1",
- "2,2,Hello world,3,2,1,2,1",
- "3,1,Hello,1,1,1,1,1",
- "3,2,Hello world,3,2,1,2,1",
- "1,5,Hello world,11,4,2,5,1",
- "1,6,Hello world,17,5,3,6,1",
- "1,9,Hello world,26,6,4,9,1",
- "1,8,Hello world,34,7,4,9,1",
- "1,7,Hello world,41,8,5,9,1",
- "2,5,Hello world,8,3,2,5,1",
- "3,5,Hello world,8,3,2,5,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedNonPartitionedRangeOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- env.setParallelism(1)
- StreamITCase.clear
-
- val sqlQuery = "SELECT a, b, c, " +
- " SUM(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " COUNT(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " AVG(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MAX(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MIN(b) OVER (ORDER BY rowtime RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (1, 1L, "Hello")),
- Left(14000002L, (1, 2L, "Hello")),
- Left(14000002L, (1, 3L, "Hello world")),
- Left(14000003L, (2, 2L, "Hello world")),
- Left(14000003L, (2, 3L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 4L, "Hello world")),
- Left(14000022L, (1, 5L, "Hello world")),
- Left(14000022L, (1, 6L, "Hello world")),
- Left(14000022L, (1, 7L, "Hello world")),
- Left(14000023L, (2, 4L, "Hello world")),
- Left(14000023L, (2, 5L, "Hello world")),
- Right(14000030L))
-
- val t1 = env
- .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "2,1,Hello,1,1,1,1,1",
- "1,1,Hello,7,4,1,3,1",
- "1,2,Hello,7,4,1,3,1",
- "1,3,Hello world,7,4,1,3,1",
- "2,2,Hello world,12,6,2,3,1",
- "2,3,Hello world,12,6,2,3,1",
- "1,1,Hi,13,7,1,3,1",
- "1,4,Hello world,17,8,2,4,1",
- "1,5,Hello world,35,11,3,7,1",
- "1,6,Hello world,35,11,3,7,1",
- "1,7,Hello world,35,11,3,7,1",
- "2,4,Hello world,44,13,3,7,1",
- "2,5,Hello world,44,13,3,7,1")
-
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testRowTimeUnBoundedNonPartitionedRowsOver(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.clear
- env.setParallelism(1)
-
- val sqlQuery = "SELECT a, b, c, " +
- " SUM(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " COUNT(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " AVG(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MAX(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), " +
- " MIN(b) OVER (ORDER BY rowtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) " +
- "FROM T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 2L, "Hello")),
- Left(14000002L, (3, 5L, "Hello")),
- Left(14000003L, (1, 3L, "Hello")),
- Left(14000004L, (3, 7L, "Hello world")),
- Left(14000007L, (4, 9L, "Hello world")),
- Left(14000008L, (5, 8L, "Hello world")),
- Right(14000010L),
- // this element will be discard because it is late
- Left(14000008L, (6, 8L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (6, 8L, "Hello world")),
- Right(14000030L)
- )
-
- val t1 = env
- .addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "2,2,Hello,2,1,2,2,2",
- "3,5,Hello,7,2,3,5,2",
- "1,3,Hello,10,3,3,5,2",
- "3,7,Hello world,17,4,4,7,2",
- "1,1,Hi,18,5,3,7,1",
- "4,9,Hello world,27,6,4,9,1",
- "5,8,Hello world,35,7,5,9,1",
- "6,8,Hello world,43,8,5,9,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test sliding event-time unbounded window with partition by **/
- @Test
- def testRowTimeUnBoundedPartitionedRowsOver2(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- env.setStateBackend(getStateBackend)
- StreamITCase.clear
- env.setParallelism(1)
-
- val sqlQuery = "SELECT a, b, c, " +
- "SUM(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "count(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "avg(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "max(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row), " +
- "min(b) over (" +
- "partition by a order by rowtime rows between unbounded preceding and current row) " +
- "from T1"
-
- val data = Seq(
- Left(14000005L, (1, 1L, "Hi")),
- Left(14000000L, (2, 1L, "Hello")),
- Left(14000002L, (3, 1L, "Hello")),
- Left(14000003L, (1, 2L, "Hello")),
- Left(14000004L, (1, 3L, "Hello world")),
- Left(14000007L, (3, 2L, "Hello world")),
- Left(14000008L, (2, 2L, "Hello world")),
- Right(14000010L),
- // the next 3 elements are late
- Left(14000008L, (1, 4L, "Hello world")),
- Left(14000008L, (2, 3L, "Hello world")),
- Left(14000008L, (3, 3L, "Hello world")),
- Left(14000012L, (1, 5L, "Hello world")),
- Right(14000020L),
- Left(14000021L, (1, 6L, "Hello world")),
- // the next 3 elements are late
- Left(14000019L, (1, 6L, "Hello world")),
- Left(14000018L, (2, 4L, "Hello world")),
- Left(14000018L, (3, 4L, "Hello world")),
- Left(14000022L, (2, 5L, "Hello world")),
- Left(14000022L, (3, 5L, "Hello world")),
- Left(14000024L, (1, 7L, "Hello world")),
- Left(14000023L, (1, 8L, "Hello world")),
- Left(14000021L, (1, 9L, "Hello world")),
- Right(14000030L)
- )
-
- val t1 = env.addSource(new EventTimeSourceFunction[(Int, Long, String)](data))
- .toTable(tEnv, 'a, 'b, 'c, 'rowtime.rowtime)
-
- tEnv.registerTable("T1", t1)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,2,Hello,2,1,2,2,2",
- "1,3,Hello world,5,2,2,3,2",
- "1,1,Hi,6,3,2,3,1",
- "2,1,Hello,1,1,1,1,1",
- "2,2,Hello world,3,2,1,2,1",
- "3,1,Hello,1,1,1,1,1",
- "3,2,Hello world,3,2,1,2,1",
- "1,5,Hello world,11,4,2,5,1",
- "1,6,Hello world,17,5,3,6,1",
- "1,9,Hello world,26,6,4,9,1",
- "1,8,Hello world,34,7,4,9,1",
- "1,7,Hello world,41,8,5,9,1",
- "2,5,Hello world,8,3,2,5,1",
- "3,5,Hello world,8,3,2,5,1"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SqlITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SqlITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SqlITCase.scala
deleted file mode 100644
index 55633ff..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/SqlITCase.scala
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.sql
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.TableEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamTestData, StreamingWithStateTestBase}
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo
-import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit._
-
-class SqlITCase extends StreamingWithStateTestBase {
-
- /** test row stream registered table **/
- @Test
- def testRowRegister(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM MyTableRow WHERE c < 3"
-
- val data = List(
- Row.of("Hello", "Worlds", Int.box(1)),
- Row.of("Hello", "Hiden", Int.box(5)),
- Row.of("Hello again", "Worlds", Int.box(2)))
-
- implicit val tpe: TypeInformation[Row] = new RowTypeInfo(
- BasicTypeInfo.STRING_TYPE_INFO,
- BasicTypeInfo.STRING_TYPE_INFO,
- BasicTypeInfo.INT_TYPE_INFO) // tpe is automatically
-
- val ds = env.fromCollection(data)
-
- val t = ds.toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTableRow", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("Hello,Worlds,1","Hello again,Worlds,2")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test unbounded groupby (without window) **/
- @Test
- def testUnboundedGroupby(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT b, COUNT(a) FROM MyTable GROUP BY b"
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toRetractStream[Row]
- result.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = List("1,1", "2,2", "3,3", "4,4", "5,5", "6,6")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- /** test selection **/
- @Test
- def testSelectExpressionFromTable(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT a * 2, b - 1 FROM MyTable"
-
- val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("2,0", "4,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test filtering with registered table **/
- @Test
- def testSimpleFilter(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM MyTable WHERE a = 3"
-
- val t = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test filtering with registered datastream **/
- @Test
- def testDatastreamFilter(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM MyTable WHERE _1 = 3"
-
- val t = StreamTestData.getSmall3TupleDataStream(env)
- tEnv.registerDataStream("MyTable", t)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test union with registered tables **/
- @Test
- def testUnion(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM T1 " +
- "UNION ALL " +
- "SELECT * FROM T2"
-
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T1", t1)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T2", t2)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,1,Hi", "1,1,Hi",
- "2,2,Hello", "2,2,Hello",
- "3,2,Hello world", "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test union with filter **/
- @Test
- def testUnionWithFilter(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT * FROM T1 WHERE a = 3 " +
- "UNION ALL " +
- "SELECT * FROM T2 WHERE a = 2"
-
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T1", t1)
- val t2 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T2", t2)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- /** test union of a table and a datastream **/
- @Test
- def testUnionTableWithDataSet(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val sqlQuery = "SELECT c FROM T1 WHERE a = 3 " +
- "UNION ALL " +
- "SELECT c FROM T2 WHERE a = 2"
-
- val t1 = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).as('a, 'b, 'c)
- tEnv.registerTable("T1", t1)
- val t2 = StreamTestData.get3TupleDataStream(env)
- tEnv.registerDataStream("T2", t2, 'a, 'b, 'c)
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List("Hello", "Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnnestPrimitiveArrayFromTable(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val data = List(
- (1, Array(12, 45), Array(Array(12, 45))),
- (2, Array(41, 5), Array(Array(18), Array(87))),
- (3, Array(18, 42), Array(Array(1), Array(45)))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, b, s FROM T, UNNEST(T.b) AS A (s)"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,[12, 45],12",
- "1,[12, 45],45",
- "2,[41, 5],41",
- "2,[41, 5],5",
- "3,[18, 42],18",
- "3,[18, 42],42"
- )
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnnestArrayOfArrayFromTable(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val data = List(
- (1, Array(12, 45), Array(Array(12, 45))),
- (2, Array(41, 5), Array(Array(18), Array(87))),
- (3, Array(18, 42), Array(Array(1), Array(45)))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataStream("T", stream, 'a, 'b, 'c)
-
- val sqlQuery = "SELECT a, s FROM T, UNNEST(T.c) AS A (s)"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "1,[12, 45]",
- "2,[18]",
- "2,[87]",
- "3,[1]",
- "3,[45]")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testUnnestObjectArrayFromTableWithFilter(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val data = List(
- (1, Array((12, "45.6"), (12, "45.612"))),
- (2, Array((13, "41.6"), (14, "45.2136"))),
- (3, Array((18, "42.6")))
- )
- val stream = env.fromCollection(data)
- tEnv.registerDataStream("T", stream, 'a, 'b)
-
- val sqlQuery = "SELECT a, b, s, t FROM T, UNNEST(T.b) AS A (s, t) WHERE s > 13"
-
- val result = tEnv.sql(sqlQuery).toAppendStream[Row]
- result.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = List(
- "2,[(13,41.6), (14,45.2136)],14,45.2136",
- "3,[(18,42.6)],18,42.6")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala
index f95d0ab..cc9d786 100644
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/WindowAggregateTest.scala
@@ -18,8 +18,7 @@
package org.apache.flink.table.api.scala.stream.sql
import org.apache.flink.api.scala._
-import org.apache.flink.table.api.{TableException, ValidationException}
-import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.WeightedAvgWithMerge
import org.apache.flink.table.api.scala._
import org.apache.flink.table.plan.logical._
import org.apache.flink.table.utils.TableTestUtil._
@@ -31,17 +30,6 @@ class WindowAggregateTest extends TableTestBase {
streamUtil.addTable[(Int, String, Long)](
"MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
- /**
- * OVER clause is necessary for [[OverAgg0]] window function.
- */
- @Test(expected = classOf[ValidationException])
- def testOverAggregation(): Unit = {
- streamUtil.addFunction("overAgg", new OverAgg0)
-
- val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
- streamUtil.tEnv.sql(sqlQuery)
- }
-
@Test
def testGroupbyWithoutWindow() = {
val sql = "SELECT COUNT(a) FROM MyTable GROUP BY b"
@@ -66,7 +54,7 @@ class WindowAggregateTest extends TableTestBase {
@Test
def testTumbleFunction() = {
- streamUtil.tEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
val sql =
"SELECT " +
@@ -95,7 +83,7 @@ class WindowAggregateTest extends TableTestBase {
@Test
def testHoppingFunction() = {
- streamUtil.tEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
val sql =
"SELECT COUNT(*), weightedAvg(c, a) AS wAvg, " +
@@ -123,7 +111,7 @@ class WindowAggregateTest extends TableTestBase {
@Test
def testSessionFunction() = {
- streamUtil.tEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
val sql =
"SELECT " +
@@ -177,51 +165,4 @@ class WindowAggregateTest extends TableTestBase {
streamUtil.verifySql(sql, expected)
}
- @Test(expected = classOf[TableException])
- def testTumbleWindowNoOffset(): Unit = {
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM MyTable " +
- "GROUP BY TUMBLE(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testHopWindowNoOffset(): Unit = {
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM MyTable " +
- "GROUP BY HOP(proctime, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testSessionWindowNoOffset(): Unit = {
- val sqlQuery =
- "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
- "FROM MyTable " +
- "GROUP BY SESSION(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
-
- @Test(expected = classOf[TableException])
- def testVariableWindowSize() = {
- val sql = "SELECT COUNT(*) FROM MyTable GROUP BY TUMBLE(proctime, c * INTERVAL '1' MINUTE)"
- streamUtil.verifySql(sql, "n/a")
- }
-
- @Test(expected = classOf[ValidationException])
- def testWindowUdAggInvalidArgs(): Unit = {
- streamUtil.tEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
-
- val sqlQuery =
- "SELECT SUM(a) AS sumA, weightedAvg(a, b) AS wAvg " +
- "FROM MyTable " +
- "GROUP BY TUMBLE(proctime(), INTERVAL '2' HOUR, TIME '10:00:00')"
-
- streamUtil.verifySql(sqlQuery, "n/a")
- }
}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala
new file mode 100644
index 0000000..b1efc09
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/AggregationsValidationTest.scala
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.sql.validation
+
+import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.scala._
+import org.apache.flink.api.scala.typeutils.CaseClassTypeInfo
+import org.apache.flink.table.api.{Types, ValidationException}
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.OverAgg0
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil.{streamTableNode, term, unaryNode}
+import org.apache.flink.table.expressions.AggFunctionCall
+import org.apache.flink.table.functions.AggregateFunction
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.apache.flink.types.Row
+import org.junit.Assert.{assertEquals, assertTrue}
+import org.junit.{Ignore, Test}
+
+class AggregationsValidationTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c)
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testOverAggregation(): Unit = {
+ streamUtil.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
+
+ streamUtil.tableEnv.sql(sqlQuery)
+ }
+
+ @Test
+ def testDistinct(): Unit = {
+ val sql = "SELECT DISTINCT a, b, c FROM MyTable"
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupAggregate",
+ streamTableNode(0),
+ term("groupBy", "a, b, c"),
+ term("select", "a, b, c")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+ // TODO: this query should be optimized to only have a single DataStreamGroupAggregate
+ // TODO: reopen this until FLINK-7144 fixed
+ @Ignore
+ @Test
+ def testDistinctAfterAggregate(): Unit = {
+ val sql = "SELECT DISTINCT a FROM MyTable GROUP BY a, b, c"
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a")
+ ),
+ term("groupBy", "a"),
+ term("select", "a")
+ )
+ streamUtil.verifySql(sql, expected)
+ }
+
+
+ @Test
+ def testUserDefinedAggregateFunctionWithScalaAccumulator(): Unit = {
+ streamUtil.addFunction("udag", new MyAgg)
+ val call = streamUtil
+ .tEnv
+ .functionCatalog
+ .lookupFunction("udag", Seq())
+ .asInstanceOf[AggFunctionCall]
+
+ val typeInfo = call.accTypeInfo
+ assertTrue(typeInfo.isInstanceOf[CaseClassTypeInfo[_]])
+ assertEquals(2, typeInfo.getTotalFields)
+ val caseTypeInfo = typeInfo.asInstanceOf[CaseClassTypeInfo[_]]
+ assertEquals(Types.LONG, caseTypeInfo.getTypeAt(0))
+ assertEquals(Types.LONG, caseTypeInfo.getTypeAt(1))
+
+ streamUtil.addFunction("udag2", new MyAgg2)
+ val call2 = streamUtil
+ .tEnv
+ .functionCatalog
+ .lookupFunction("udag2", Seq())
+ .asInstanceOf[AggFunctionCall]
+
+ val typeInfo2 = call2.accTypeInfo
+ assertTrue(s"actual type: $typeInfo2", typeInfo2.isInstanceOf[RowTypeInfo])
+ assertEquals(2, typeInfo2.getTotalFields)
+ val rowTypeInfo = typeInfo2.asInstanceOf[RowTypeInfo]
+ assertEquals(Types.LONG, rowTypeInfo.getTypeAt(0))
+ assertEquals(Types.INT, rowTypeInfo.getTypeAt(1))
+ }
+}
+
+case class MyAccumulator(var sum: Long, var count: Long)
+
+class MyAgg extends AggregateFunction[Long, MyAccumulator] {
+
+ //Overloaded accumulate method
+ def accumulate(acc: MyAccumulator, value: Long): Unit = {
+ }
+
+ override def createAccumulator(): MyAccumulator = MyAccumulator(0, 0)
+
+ override def getValue(accumulator: MyAccumulator): Long = 1L
+}
+
+class MyAgg2 extends AggregateFunction[Long, Row] {
+
+ def accumulate(acc: Row, value: Long): Unit = {}
+
+ override def createAccumulator(): Row = new Row(2)
+
+ override def getValue(accumulator: Row): Long = 1L
+
+ def getAccumulatorType: TypeInformation[_] = new RowTypeInfo(Types.LONG, Types.INT)
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala
new file mode 100644
index 0000000..3cc13f4
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/OverWindowValidationTest.scala
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.apache.flink.types.Row
+import org.junit.Test
+
+class OverWindowValidationTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)]("T1", 'a, 'b, 'c, 'proctime.proctime)
+
+ /**
+ * All aggregates must be computed on the same window.
+ */
+ @Test(expected = classOf[TableException])
+ def testMultiWindow(): Unit = {
+
+ val sqlQuery = "SELECT " +
+ "c, " +
+ "count(a) OVER (PARTITION BY c ORDER BY proctime RANGE UNBOUNDED preceding), " +
+ "sum(a) OVER (PARTITION BY b ORDER BY proctime RANGE UNBOUNDED preceding) " +
+ "from T1"
+
+ streamUtil.tableEnv.sql(sqlQuery).toAppendStream[Row]
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala
new file mode 100644
index 0000000..0fd8740
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/sql/validation/WindowAggregateValidationTest.scala
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.sql.validation
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.java.utils.UserDefinedAggFunctions.{OverAgg0, WeightedAvgWithMerge}
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.{TableException, ValidationException}
+import org.apache.flink.table.utils.{StreamTableTestUtil, TableTestBase}
+import org.junit.Test
+
+class WindowAggregateValidationTest extends TableTestBase {
+ private val streamUtil: StreamTableTestUtil = streamTestUtil()
+ streamUtil.addTable[(Int, String, Long)](
+ "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
+
+ /**
+ * OVER clause is necessary for [[OverAgg0]] window function.
+ */
+ @Test(expected = classOf[ValidationException])
+ def testOverAggregation(): Unit = {
+ streamUtil.addFunction("overAgg", new OverAgg0)
+
+ val sqlQuery = "SELECT overAgg(c, a) FROM MyTable"
+ streamUtil.tableEnv.sql(sqlQuery)
+ }
+
+ @Test(expected = classOf[TableException])
+ def testTumbleWindowNoOffset(): Unit = {
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM MyTable " +
+ "GROUP BY TUMBLE(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testHopWindowNoOffset(): Unit = {
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM MyTable " +
+ "GROUP BY HOP(proctime, INTERVAL '1' HOUR, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testSessionWindowNoOffset(): Unit = {
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
+ "FROM MyTable " +
+ "GROUP BY SESSION(proctime, INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+
+ @Test(expected = classOf[TableException])
+ def testVariableWindowSize() = {
+ val sql = "SELECT COUNT(*) FROM MyTable GROUP BY TUMBLE(proctime, c * INTERVAL '1' MINUTE)"
+ streamUtil.verifySql(sql, "n/a")
+ }
+
+ @Test(expected = classOf[ValidationException])
+ def testWindowUdAggInvalidArgs(): Unit = {
+ streamUtil.tableEnv.registerFunction("weightedAvg", new WeightedAvgWithMerge)
+
+ val sqlQuery =
+ "SELECT SUM(a) AS sumA, weightedAvg(a, b) AS wAvg " +
+ "FROM MyTable " +
+ "GROUP BY TUMBLE(proctime(), INTERVAL '2' HOUR, TIME '10:00:00')"
+
+ streamUtil.verifySql(sqlQuery, "n/a")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/CalcITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/CalcITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/CalcITCase.scala
deleted file mode 100644
index adf4d44..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/CalcITCase.scala
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamTestData}
-import org.apache.flink.table.api.{TableEnvironment, TableException}
-import org.apache.flink.table.expressions.Literal
-import org.apache.flink.types.Row
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.collection.mutable
-
-class CalcITCase extends StreamingMultipleProgramsTestBase {
-
- @Test
- def testSimpleSelectAll(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1, '_2, '_3)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hi",
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSelectFirst(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv).select('_1)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("1", "2", "3")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSimpleSelectWithNaming(): Unit = {
-
- // verify ProjectMergeRule.
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv)
- .select('_1 as 'a, '_2 as 'b, '_1 as 'c)
- .select('a, 'b)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1", "2,2", "3,2", "4,3", "5,3", "6,3", "7,4",
- "8,4", "9,4", "10,4", "11,5", "12,5", "13,5", "14,5", "15,5",
- "16,6", "17,6", "18,6", "19,6", "20,6", "21,6")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSimpleSelectAllWithAs(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a, 'b, 'c)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hi",
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test(expected = classOf[TableException])
- def testAsWithToManyFields(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("no")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test(expected = classOf[TableException])
- def testAsWithAmbiguousFields(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'b)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("no")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
-
- @Test(expected = classOf[TableException])
- def testOnlyFieldRefInAs(): Unit = {
-
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b as 'c, 'd)
-
- val results = ds.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("no")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testSimpleFilter(): Unit = {
- /*
- * Test simple filter
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter('a === 3)
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList("3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testAllRejectingFilter(): Unit = {
- /*
- * Test all-rejecting filter
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(false) )
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- assertEquals(true, StreamITCase.testResults.isEmpty)
- }
-
- @Test
- def testAllPassingFilter(): Unit = {
- /*
- * Test all-passing filter
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.getSmall3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( Literal(true) )
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "1,1,Hi",
- "2,2,Hello",
- "3,2,Hello world")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testFilterOnIntegerTupleField(): Unit = {
- /*
- * Test filter on Integer tuple field.
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 === 0 )
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
-
- val expected = mutable.MutableList(
- "2,2,Hello", "4,3,Hello world, how are you?",
- "6,3,Luke Skywalker", "8,4,Comment#2", "10,4,Comment#4",
- "12,5,Comment#6", "14,5,Comment#8", "16,6,Comment#10",
- "18,6,Comment#12", "20,6,Comment#14")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-
- @Test
- def testNotEquals(): Unit = {
- /*
- * Test filter on Integer tuple field.
- */
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- val tEnv = TableEnvironment.getTableEnvironment(env)
-
- StreamITCase.testResults = mutable.MutableList()
- val ds = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
-
- val filterDs = ds.filter( 'a % 2 !== 0)
- val results = filterDs.toAppendStream[Row]
- results.addSink(new StreamITCase.StringSink[Row])
- env.execute()
- val expected = mutable.MutableList(
- "1,1,Hi", "3,2,Hello world",
- "5,3,I am fine.", "7,4,Comment#1", "9,4,Comment#3",
- "11,5,Comment#5", "13,5,Comment#7", "15,5,Comment#9",
- "17,6,Comment#11", "19,6,Comment#13", "21,6,Comment#15")
- assertEquals(expected.sorted, StreamITCase.testResults.sorted)
- }
-}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala
new file mode 100644
index 0000000..20a88fe
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExplainTest.scala
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.api.scala.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.streaming.util.StreamingMultipleProgramsTestBase
+import org.apache.flink.table.api.TableEnvironment
+import org.apache.flink.table.api.scala._
+import org.junit.Assert.assertEquals
+import org.junit._
+
+class ExplainTest
+ extends StreamingMultipleProgramsTestBase {
+
+ val testFilePath = this.getClass.getResource("/").getFile
+
+ @Test
+ def testFilter(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table = env.fromElements((1, "hello"))
+ .toTable(tEnv, 'a, 'b)
+ .filter("a % 2 = 0")
+
+ val result = replaceString(tEnv.explain(table))
+
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testFilterStream0.out").mkString
+ val expect = replaceString(source)
+ assertEquals(result, expect)
+ }
+
+ @Test
+ def testUnion(): Unit = {
+ val env = StreamExecutionEnvironment.getExecutionEnvironment
+ val tEnv = TableEnvironment.getTableEnvironment(env)
+
+ val table1 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table2 = env.fromElements((1, "hello")).toTable(tEnv, 'count, 'word)
+ val table = table1.unionAll(table2)
+
+ val result = replaceString(tEnv.explain(table))
+
+ val source = scala.io.Source.fromFile(testFilePath +
+ "../../src/test/scala/resources/testUnionStream0.out").mkString
+ val expect = replaceString(source)
+ assertEquals(result, expect)
+ }
+
+ def replaceString(s: String): String = {
+ /* Stage {id} is ignored, because id keeps incrementing in test class
+ * while StreamExecutionEnvironment is up
+ */
+ s.replaceAll("\\r\\n", "\n").replaceAll("Stage \\d+", "")
+ }
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala
new file mode 100644
index 0000000..fec25eb
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/ExpressionReductionTest.scala
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestBase
+import org.apache.flink.table.utils.TableTestUtil._
+import org.junit.Test
+
+class ExpressionReductionTest extends TableTestBase {
+
+ @Test
+ def testReduceCalcExpression(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ ),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceProjectExpression(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .select((3 + 4).toExpr + 6,
+ (11 === 1) ? ("a", "b"),
+ " STRING ".trim,
+ "test" + "string",
+ "1990-10-14 23:00:00.123".toTimestamp + 10.days + 1.second,
+ 1.isNull,
+ "TEST".like("%EST"),
+ 2.5.toExpr.floor(),
+ true.cast(Types.STRING) + "X")
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select",
+ "13 AS _c0",
+ "'b' AS _c1",
+ "'STRING' AS _c2",
+ "'teststring' AS _c3",
+ "1990-10-24 23:00:01.123 AS _c4",
+ "false AS _c5",
+ "true AS _c6",
+ "2E0 AS _c7",
+ "'trueX' AS _c8"
+ )
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+ @Test
+ def testReduceFilterExpression(): Unit = {
+ val util = streamTestUtil()
+ val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+
+ val result = table
+ .where('a > (1 + 7))
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "a", "b", "c"),
+ term("where", ">(a, 8)")
+ )
+
+ util.verifyTable(result, expected)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala
new file mode 100644
index 0000000..3bf9c33
--- /dev/null
+++ b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/FieldProjectionTest.scala
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.flink.table.api.scala.stream.table
+
+import org.apache.flink.api.scala._
+import org.apache.flink.table.api.scala._
+import org.apache.flink.table.expressions.{Upper, WindowReference}
+import org.apache.flink.table.plan.logical.TumblingGroupWindow
+import org.apache.flink.table.utils.TableTestUtil._
+import org.apache.flink.table.utils.{TableTestBase, _}
+import org.junit.Test
+
+/**
+ * Tests for all the situations when we can do fields projection. Like selecting few fields
+ * from a large field count source.
+ */
+class FieldProjectionTest extends TableTestBase {
+
+ val streamUtil: StreamTableTestUtil = streamTestUtil()
+
+ @Test
+ def testSelectFromWindow(): Unit = {
+ val sourceTable = streamUtil
+ .addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
+ val resultTable = sourceTable
+ .window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w)
+ .select(Upper('c).count, 'a.sum)
+
+ val expected =
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "c", "a", "rowtime", "UPPER(c) AS $f3")
+ ),
+ term("window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'rowtime,
+ 5.millis)),
+ term("select", "COUNT($f3) AS TMP_0", "SUM(a) AS TMP_1")
+ )
+
+ streamUtil.verifyTable(resultTable, expected)
+ }
+
+ @Test
+ def testSelectFromGroupedWindow(): Unit = {
+ val sourceTable = streamUtil
+ .addTable[(Int, Long, String, Double)]("MyTable", 'a, 'b, 'c, 'd, 'rowtime.rowtime)
+ val resultTable = sourceTable
+ .window(Tumble over 5.millis on 'rowtime as 'w)
+ .groupBy('w, 'b)
+ .select(Upper('c).count, 'a.sum, 'b)
+
+ val expected = unaryNode(
+ "DataStreamCalc",
+ unaryNode(
+ "DataStreamGroupWindowAggregate",
+ unaryNode(
+ "DataStreamCalc",
+ streamTableNode(0),
+ term("select", "c", "a", "b", "rowtime", "UPPER(c) AS $f4")
+ ),
+ term("groupBy", "b"),
+ term("window",
+ TumblingGroupWindow(
+ WindowReference("w"),
+ 'rowtime,
+ 5.millis)),
+ term("select", "b", "COUNT($f4) AS TMP_0", "SUM(a) AS TMP_1")
+ ),
+ term("select", "TMP_0", "TMP_1", "b")
+ )
+
+ streamUtil.verifyTable(resultTable, expected)
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/flink/blob/ecde7bc1/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsITCase.scala
----------------------------------------------------------------------
diff --git a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsITCase.scala b/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsITCase.scala
deleted file mode 100644
index 4a3524b..0000000
--- a/flink-libraries/flink-table/src/test/scala/org/apache/flink/table/api/scala/stream/table/GroupAggregationsITCase.scala
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.api.scala.stream.table
-
-import org.apache.flink.api.common.time.Time
-import org.apache.flink.api.scala._
-import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
-import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.scala.stream.utils.{StreamITCase, StreamTestData, StreamingWithStateTestBase}
-import org.apache.flink.table.api.{StreamQueryConfig, TableEnvironment}
-import org.apache.flink.table.api.scala.stream.utils.StreamITCase.RetractingSink
-import org.apache.flink.types.Row
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-import scala.collection.mutable
-
-/**
- * Tests of groupby (without window) aggregations
- */
-class GroupAggregationsITCase extends StreamingWithStateTestBase {
- private val queryConfig = new StreamQueryConfig()
- queryConfig.withIdleStateRetentionTime(Time.hours(1), Time.hours(2))
-
-
- @Test
- def testDistinct(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .select('b).distinct()
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = mutable.MutableList("1", "2", "3", "4", "5", "6")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testDistinctAfterAggregate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .groupBy('e).select('e, 'a.count).distinct()
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = mutable.MutableList("1,5", "2,7", "3,3")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testNonKeyedGroupAggregate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .select('a.sum, 'b.sum)
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink).setParallelism(1)
- env.execute()
-
- val expected = List("231,91")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testGroupAggregate(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('b, 'a.sum)
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new StreamITCase.RetractingSink)
- env.execute()
-
- val expected = List("1,1", "2,5", "3,15", "4,34", "5,65", "6,111")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testDoubleGroupAggregation(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get3TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c)
- .groupBy('b)
- .select('a.count as 'cnt, 'b)
- .groupBy('cnt)
- .select('cnt, 'b.count as 'freq)
-
- val results = t.toRetractStream[Row](queryConfig)
-
- results.addSink(new RetractingSink)
- env.execute()
- val expected = List("1,1", "2,1", "3,1", "4,1", "5,1", "6,1")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-
- @Test
- def testGroupAggregateWithExpression(): Unit = {
- val env = StreamExecutionEnvironment.getExecutionEnvironment
- env.setStateBackend(getStateBackend)
- val tEnv = TableEnvironment.getTableEnvironment(env)
- StreamITCase.clear
-
- val t = StreamTestData.get5TupleDataStream(env).toTable(tEnv, 'a, 'b, 'c, 'd, 'e)
- .groupBy('e, 'b % 3)
- .select('c.min, 'e, 'a.avg, 'd.count)
-
- val results = t.toRetractStream[Row](queryConfig)
- results.addSink(new RetractingSink)
- env.execute()
-
- val expected = mutable.MutableList(
- "0,1,1,1", "7,1,4,2", "2,1,3,2",
- "3,2,3,3", "1,2,3,3", "14,2,5,1",
- "12,3,5,1", "5,3,4,2")
- assertEquals(expected.sorted, StreamITCase.retractedResults.sorted)
- }
-}