/* * 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.jdbc; import com.facebook.presto.server.testing.TestingPrestoServer; import io.airlift.log.Logging; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.Statement; import java.sql.Types; import static com.facebook.presto.jdbc.TestPrestoDriver.closeQuietly; import static java.lang.String.format; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @Test(singleThreaded = true) public class TestJdbcResultSet { private TestingPrestoServer server; private Connection connection; private Statement statement; @BeforeClass public void setupServer() throws Exception { Logging.initialize(); server = new TestingPrestoServer(); } @AfterClass public void teardownServer() { closeQuietly(server); } @SuppressWarnings("JDBCResourceOpenedButNotSafelyClosed") @BeforeMethod public void setup() throws Exception { connection = createConnection(); statement = connection.createStatement(); } @AfterMethod public void teardown() { closeQuietly(statement); closeQuietly(connection); } @Test public void testDuplicateColumnLabels() throws Exception { try (ResultSet rs = statement.executeQuery("SELECT 123 x, 456 x")) { ResultSetMetaData metadata = rs.getMetaData(); assertEquals(metadata.getColumnCount(), 2); assertEquals(metadata.getColumnName(1), "x"); assertEquals(metadata.getColumnName(2), "x"); assertTrue(rs.next()); assertEquals(rs.getLong(1), 123L); assertEquals(rs.getLong(2), 456L); assertEquals(rs.getLong("x"), 123L); } } @SuppressWarnings("UnnecessaryBoxing") @Test public void testObjectTypes() throws Exception { String sql = "SELECT 123, 12300000000, REAL '123.45', 0.1, true, 'hello', 1.0 / 0.0, 0.0 / 0.0, ARRAY[1, 2], cast('foo' as char(5))"; try (ResultSet rs = statement.executeQuery(sql)) { ResultSetMetaData metadata = rs.getMetaData(); assertEquals(metadata.getColumnCount(), 10); assertEquals(metadata.getColumnType(1), Types.INTEGER); assertEquals(metadata.getColumnType(2), Types.BIGINT); assertEquals(metadata.getColumnType(3), Types.REAL); assertEquals(metadata.getColumnType(4), Types.DOUBLE); assertEquals(metadata.getColumnType(5), Types.BOOLEAN); assertEquals(metadata.getColumnType(6), Types.LONGNVARCHAR); assertEquals(metadata.getColumnType(7), Types.DOUBLE); assertEquals(metadata.getColumnType(8), Types.DOUBLE); assertEquals(metadata.getColumnType(9), Types.ARRAY); assertEquals(metadata.getColumnType(10), Types.CHAR); assertTrue(rs.next()); assertEquals(rs.getObject(1), 123); assertEquals(rs.getObject(2), 12300000000L); assertEquals(rs.getObject(3), 123.45f); assertEquals(rs.getObject(4), 0.1d); assertEquals(rs.getObject(5), true); assertEquals(rs.getObject(6), "hello"); assertEquals(rs.getObject(7), Double.POSITIVE_INFINITY); assertEquals(rs.getObject(8), Double.NaN); assertEquals(rs.getArray(9).getArray(), new int[] {1, 2}); assertEquals(rs.getObject(10), "foo "); } } @Test public void testStatsExtraction() throws Exception { try (PrestoResultSet rs = (PrestoResultSet) statement.executeQuery("SELECT 123 x, 456 x")) { assertNotNull(rs.getStats()); assertTrue(rs.next()); assertNotNull(rs.getStats()); assertFalse(rs.next()); assertNotNull(rs.getStats()); } } @Test public void testMaxRowsUnset() throws SQLException { assertMaxRowsLimit(0); assertMaxRowsResult(7); } @Test public void testMaxRowsUnlimited() throws SQLException { assertMaxRowsLimit(0); statement.setMaxRows(0); assertMaxRowsLimit(0); assertMaxRowsResult(7); } @Test public void testMaxRowsLimited() throws SQLException { assertMaxRowsLimit(0); statement.setMaxRows(4); assertMaxRowsLimit(4); assertMaxRowsResult(4); } @Test public void testMaxRowsLimitLargerThanResult() throws SQLException { assertMaxRowsLimit(0); statement.setMaxRows(10); assertMaxRowsLimit(10); assertMaxRowsResult(7); } @Test public void testLargeMaxRowsUnlimited() throws SQLException { assertMaxRowsLimit(0); statement.setLargeMaxRows(0); assertMaxRowsLimit(0); assertMaxRowsResult(7); } @Test public void testLargeMaxRowsLimited() throws SQLException { assertMaxRowsLimit(0); statement.setLargeMaxRows(4); assertMaxRowsLimit(4); assertMaxRowsResult(4); } @Test public void testLargeMaxRowsLimitLargerThanResult() throws SQLException { long limit = Integer.MAX_VALUE * 10L; statement.setLargeMaxRows(limit); assertEquals(statement.getLargeMaxRows(), limit); assertMaxRowsResult(7); } private void assertMaxRowsLimit(int expectedLimit) throws SQLException { assertEquals(statement.getMaxRows(), expectedLimit); assertEquals(statement.getLargeMaxRows(), expectedLimit); } private void assertMaxRowsResult(long expectedCount) throws SQLException { try (ResultSet rs = statement.executeQuery("SELECT * FROM (VALUES (1), (2), (3), (4), (5), (6), (7)) AS x (a)")) { assertEquals(countRows(rs), expectedCount); } } @Test(expectedExceptions = SQLException.class, expectedExceptionsMessageRegExp = "Max rows exceeds limit of 2147483647") public void testMaxRowsExceedsLimit() throws SQLException { statement.setLargeMaxRows(Integer.MAX_VALUE * 10L); statement.getMaxRows(); } @Test(expectedExceptions = SQLFeatureNotSupportedException.class, expectedExceptionsMessageRegExp = "SET/RESET SESSION .*") public void testSetSession() throws Exception { statement.execute("SET SESSION hash_partition_count = 16"); } @Test(expectedExceptions = SQLFeatureNotSupportedException.class, expectedExceptionsMessageRegExp = "SET/RESET SESSION .*") public void testResetSession() throws Exception { statement.execute("RESET SESSION hash_partition_count"); } private Connection createConnection() throws SQLException { String url = format("jdbc:presto://%s", server.getAddress()); return DriverManager.getConnection(url, "test", null); } private static long countRows(ResultSet rs) throws SQLException { long count = 0; while (rs.next()) { count++; } return count; } }