/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.facebook.presto.plugin.mysql; import com.facebook.presto.spi.type.VarcharType; import com.facebook.presto.testing.MaterializedResult; import com.facebook.presto.tests.AbstractTestQueries; import com.facebook.presto.tests.datatype.CreateAndInsertDataSetup; import com.facebook.presto.tests.datatype.CreateAsSelectDataSetup; import com.facebook.presto.tests.datatype.DataSetup; import com.facebook.presto.tests.datatype.DataTypeTest; import com.facebook.presto.tests.sql.JdbcSqlExecutor; import com.facebook.presto.tests.sql.PrestoSqlExecutor; import io.airlift.testing.mysql.TestingMySqlServer; import io.airlift.tpch.TpchTable; import org.testng.annotations.AfterClass; import org.testng.annotations.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import static com.facebook.presto.plugin.mysql.MySqlQueryRunner.createMySqlQueryRunner; import static com.facebook.presto.spi.type.VarcharType.VARCHAR; import static com.facebook.presto.spi.type.VarcharType.createUnboundedVarcharType; import static com.facebook.presto.spi.type.VarcharType.createVarcharType; import static com.facebook.presto.testing.MaterializedResult.resultBuilder; import static com.facebook.presto.testing.assertions.Assert.assertEquals; import static com.facebook.presto.tests.datatype.DataType.charDataType; import static com.facebook.presto.tests.datatype.DataType.stringDataType; import static com.facebook.presto.tests.datatype.DataType.varcharDataType; import static com.google.common.base.Strings.repeat; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; @Test public class TestMySqlDistributedQueries extends AbstractTestQueries { private static final String CHARACTER_SET_UTF8 = "CHARACTER SET utf8"; private final TestingMySqlServer mysqlServer; public TestMySqlDistributedQueries() throws Exception { this(new TestingMySqlServer("testuser", "testpass", "tpch")); } public TestMySqlDistributedQueries(TestingMySqlServer mysqlServer) throws Exception { super(() -> createMySqlQueryRunner(mysqlServer, TpchTable.getTables())); this.mysqlServer = mysqlServer; } @AfterClass(alwaysRun = true) public final void destroy() { mysqlServer.close(); } @Test public void testDropTable() { assertUpdate("CREATE TABLE test_drop AS SELECT 123 x", 1); assertTrue(getQueryRunner().tableExists(getSession(), "test_drop")); assertUpdate("DROP TABLE test_drop"); assertFalse(getQueryRunner().tableExists(getSession(), "test_drop")); } @Test public void testViews() throws SQLException { execute("CREATE OR REPLACE VIEW tpch.test_view AS SELECT * FROM tpch.orders"); assertQuery("SELECT orderkey FROM test_view", "SELECT orderkey FROM orders"); execute("DROP VIEW IF EXISTS tpch.test_view"); } @Test public void testPrestoCreatedParameterizedVarchar() { DataTypeTest.create() .addRoundTrip(stringDataType("varchar(10)", createVarcharType(255)), "text_a") .addRoundTrip(stringDataType("varchar(255)", createVarcharType(255)), "text_b") .addRoundTrip(stringDataType("varchar(256)", createVarcharType(65535)), "text_c") .addRoundTrip(stringDataType("varchar(65535)", createVarcharType(65535)), "text_d") .addRoundTrip(stringDataType("varchar(65536)", createVarcharType(16777215)), "text_e") .addRoundTrip(stringDataType("varchar(16777215)", createVarcharType(16777215)), "text_f") .addRoundTrip(stringDataType("varchar(16777216)", createUnboundedVarcharType()), "text_g") .addRoundTrip(stringDataType("varchar(" + VarcharType.MAX_LENGTH + ")", createUnboundedVarcharType()), "text_h") .addRoundTrip(stringDataType("varchar", createUnboundedVarcharType()), "unbounded") .execute(getQueryRunner(), prestoCreateAsSelect("presto_test_parameterized_varchar")); } @Test public void testMySqlCreatedParameterizedVarchar() { DataTypeTest.create() .addRoundTrip(stringDataType("tinytext", createVarcharType(255)), "a") .addRoundTrip(stringDataType("text", createVarcharType(65535)), "b") .addRoundTrip(stringDataType("mediumtext", createVarcharType(16777215)), "c") .addRoundTrip(stringDataType("longtext", createUnboundedVarcharType()), "d") .addRoundTrip(varcharDataType(32), "e") .addRoundTrip(varcharDataType(20000), "f") .execute(getQueryRunner(), mysqlCreateAndInsert("tpch.mysql_test_parameterized_varchar")); } @Test public void testMySqlCreatedParameterizedVarcharUnicode() { String sampleUnicodeText = "\u653b\u6bbb\u6a5f\u52d5\u968a"; DataTypeTest.create() .addRoundTrip(stringDataType("tinytext " + CHARACTER_SET_UTF8, createVarcharType(255)), sampleUnicodeText) .addRoundTrip(stringDataType("text " + CHARACTER_SET_UTF8, createVarcharType(65535)), sampleUnicodeText) .addRoundTrip(stringDataType("mediumtext " + CHARACTER_SET_UTF8, createVarcharType(16777215)), sampleUnicodeText) .addRoundTrip(stringDataType("longtext " + CHARACTER_SET_UTF8, createUnboundedVarcharType()), sampleUnicodeText) .addRoundTrip(varcharDataType(sampleUnicodeText.length(), CHARACTER_SET_UTF8), sampleUnicodeText) .addRoundTrip(varcharDataType(32, CHARACTER_SET_UTF8), sampleUnicodeText) .addRoundTrip(varcharDataType(20000, CHARACTER_SET_UTF8), sampleUnicodeText) .execute(getQueryRunner(), mysqlCreateAndInsert("tpch.mysql_test_parameterized_varchar_unicode")); } @Test public void testPrestoCreatedParameterizedChar() { mysqlCharTypeTest().execute(getQueryRunner(), prestoCreateAsSelect("mysql_test_parameterized_char")); } @Test public void testMySqlCreatedParameterizedChar() { mysqlCharTypeTest().execute(getQueryRunner(), mysqlCreateAndInsert("tpch.mysql_test_parameterized_char")); } private DataTypeTest mysqlCharTypeTest() { return DataTypeTest.create() .addRoundTrip(charDataType("char", 1), "") .addRoundTrip(charDataType("char", 1), "a") .addRoundTrip(charDataType(1), "") .addRoundTrip(charDataType(1), "a") .addRoundTrip(charDataType(8), "abc") .addRoundTrip(charDataType(8), "12345678") .addRoundTrip(charDataType(255), repeat("a", 255)); } @Test public void testMySqlCreatedParameterizedCharUnicode() { DataTypeTest.create() .addRoundTrip(charDataType(1, CHARACTER_SET_UTF8), "\u653b") .addRoundTrip(charDataType(5, CHARACTER_SET_UTF8), "\u653b\u6bbb") .addRoundTrip(charDataType(5, CHARACTER_SET_UTF8), "\u653b\u6bbb\u6a5f\u52d5\u968a") .execute(getQueryRunner(), mysqlCreateAndInsert("tpch.mysql_test_parameterized_varchar")); } private DataSetup prestoCreateAsSelect(String tableNamePrefix) { return new CreateAsSelectDataSetup(new PrestoSqlExecutor(getQueryRunner()), tableNamePrefix); } private DataSetup mysqlCreateAndInsert(String tableNamePrefix) { JdbcSqlExecutor mysqlUnicodeExecutor = new JdbcSqlExecutor(mysqlServer.getJdbcUrl() + "&useUnicode=true&characterEncoding=utf8"); return new CreateAndInsertDataSetup(mysqlUnicodeExecutor, tableNamePrefix); } @Override public void testShowColumns() { MaterializedResult actual = computeActual("SHOW COLUMNS FROM orders"); MaterializedResult expectedParametrizedVarchar = resultBuilder(getSession(), VARCHAR, VARCHAR, VARCHAR, VARCHAR) .row("orderkey", "bigint", "", "") .row("custkey", "bigint", "", "") .row("orderstatus", "varchar(255)", "", "") .row("totalprice", "double", "", "") .row("orderdate", "date", "", "") .row("orderpriority", "varchar(255)", "", "") .row("clerk", "varchar(255)", "", "") .row("shippriority", "integer", "", "") .row("comment", "varchar(255)", "", "") .build(); assertEquals(actual, expectedParametrizedVarchar); } @Override public void testDescribeOutput() { // this connector uses a non-canonical type for varchar columns in tpch } @Override public void testDescribeOutputNamedAndUnnamed() { // this connector uses a non-canonical type for varchar columns in tpch } private void execute(String sql) throws SQLException { try (Connection connection = DriverManager.getConnection(mysqlServer.getJdbcUrl()); Statement statement = connection.createStatement()) { statement.execute(sql); } } }