blob: c50e9e31620b2de9df1ff08814f7196273ea3e45 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.client.solrj.io.sql;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.cloud.AbstractDistribZkTestBase;
import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.Aliases;
import org.apache.solr.common.cloud.ZkStateReader;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
/**
* All base tests will be done with CloudSolrStream. Under the covers CloudSolrStream uses SolrStream so
* SolrStream will get fully exercised through these tests.
**/
@Slow
@LuceneTestCase.SuppressCodecs({"Lucene3x", "Lucene40", "Lucene41", "Lucene42", "Lucene45"})
public class JdbcTest extends SolrCloudTestCase {
private static final String COLLECTIONORALIAS = "collection1";
private static final String id = "id";
private static String zkHost;
@BeforeClass
public static void setupCluster() throws Exception {
configureCluster(2)
.addConfig("conf", getFile("solrj").toPath().resolve("solr").resolve("configsets").resolve("streaming").resolve("conf"))
.configure();
String collection;
boolean useAlias = random().nextBoolean();
if (useAlias) {
collection = COLLECTIONORALIAS + "_collection";
} else {
collection = COLLECTIONORALIAS;
}
CollectionAdminRequest.createCollection(collection, "conf", 2, 1).process(cluster.getSolrClient());
cluster.waitForActiveCollection(collection, 2, 2);
AbstractDistribZkTestBase.waitForRecoveriesToFinish(collection, cluster.getSolrClient().getZkStateReader(),
false, true, DEFAULT_TIMEOUT);
if (useAlias) {
CollectionAdminRequest.createAlias(COLLECTIONORALIAS, collection).process(cluster.getSolrClient());
}
UpdateRequest update = new UpdateRequest()
.add(id, "0", "a_s", "hello0", "a_i", "0", "a_f", "1", "testnull_i", null)
.add(id, "2", "a_s", "hello0", "a_i", "2", "a_f", "2", "testnull_i", "2")
.add(id, "3", "a_s", "hello3", "a_i", "3", "a_f", "3", "testnull_i", null)
.add(id, "4", "a_s", "hello4", "a_i", "4", "a_f", "4", "testnull_i", "4")
.add(id, "1", "a_s", "hello0", "a_i", "1", "a_f", "5", "testnull_i", null)
.add(id, "5", "a_s", "hello3", "a_i", "10", "a_f", "6", "testnull_i", "6")
.add(id, "6", "a_s", "hello4", "a_i", "11", "a_f", "7", "testnull_i", null)
.add(id, "7", "a_s", "hello3", "a_i", "12", "a_f", "8", "testnull_i", "8")
.add(id, "8", "a_s", "hello3", "a_i", "13", "a_f", "9", "testnull_i", null)
.add(id, "9", "a_s", "hello0", "a_i", "14", "a_f", "10", "testnull_i", "10");
SolrInputDocument withMVs = new SolrInputDocument();
withMVs.setField(id, "10");
withMVs.setField("s_multi", Arrays.asList("abc", "lmn", "xyz"));
withMVs.setField("d_multi", Arrays.asList(1d, 2d, 3d));
update.add(withMVs);
withMVs = new SolrInputDocument();
withMVs.setField(id, "11");
withMVs.setField("s_multi", Arrays.asList("a", "b", "c"));
withMVs.setField("d_multi", Arrays.asList(3d, 4d, 5d));
update.add(withMVs);
update.commit(cluster.getSolrClient(), collection);
zkHost = cluster.getZkServer().getZkAddress();
}
@Test
public void doTest() throws Exception {
Properties props = new Properties();
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost + "?collection=" + COLLECTIONORALIAS, props)) {
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select id, a_i, a_s, a_f from " + COLLECTIONORALIAS + " WHERE a_i IS NOT NULL order by a_i desc limit 2")) {
assertTrue(rs.next());
assertEquals(14, rs.getLong("a_i"));
assertEquals(14, rs.getLong(2));
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(3));
assertEquals(10, rs.getDouble("a_f"), 0);
assertEquals(10, rs.getDouble(4), 0);
assertTrue(rs.next());
assertEquals(13, rs.getLong("a_i"));
assertEquals(13, rs.getLong(2));
assertEquals("hello3", rs.getString("a_s"));
assertEquals("hello3", rs.getString(3));
assertEquals(9, rs.getDouble("a_f"), 0);
assertEquals(9, rs.getDouble(4), 0);
assertFalse(rs.next());
}
//Test statement reuse
try (ResultSet rs = stmt.executeQuery("select id, a_i, a_s, a_f from " + COLLECTIONORALIAS + " WHERE a_i IS NOT NULL order by a_i asc limit 2")) {
assertTrue(rs.next());
assertEquals(0, rs.getLong("a_i"));
assertEquals(0, rs.getLong(2));
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(3));
assertEquals(1, rs.getDouble("a_f"), 0);
assertEquals(1, rs.getDouble(4), 0);
assertTrue(rs.next());
assertEquals(1, rs.getLong("a_i"));
assertEquals(1, rs.getLong(2));
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(3));
assertEquals(5, rs.getDouble("a_f"), 0);
assertEquals(5, rs.getDouble(4), 0);
assertFalse(rs.next());
}
}
//Test connection reuse
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select id, a_i, a_s, a_f from " + COLLECTIONORALIAS + " WHERE a_i IS NOT NULL order by a_i desc limit 2")) {
assertTrue(rs.next());
assertEquals(14, rs.getLong("a_i"));
assertEquals(14, rs.getLong(2));
assertTrue(rs.next());
assertEquals(13, rs.getLong("a_i"));
assertEquals(13, rs.getLong(2));
assertFalse(rs.next());
}
//Test statement reuse
stmt.setMaxRows(2);
try (ResultSet rs = stmt.executeQuery("select id, a_i, a_s, a_f from " + COLLECTIONORALIAS + " WHERE a_i IS NOT NULL order by a_i asc")) {
assertTrue(rs.next());
assertEquals(0, rs.getLong("a_i"));
assertEquals(0, rs.getLong(2));
assertTrue(rs.next());
assertEquals(1, rs.getLong("a_i"));
assertEquals(1, rs.getLong(2));
assertFalse(rs.next());
}
//Test simple loop. Since limit is set it will override the statement maxRows.
try (ResultSet rs = stmt.executeQuery("select id, a_i, a_s, a_f from " + COLLECTIONORALIAS + " WHERE a_i IS NOT NULL order by a_i asc LIMIT 100")) {
int count = 0;
while (rs.next()) {
++count;
}
assertEquals(10, count);
}
}
}
}
@Test
public void testFacetAggregation() throws Exception {
//Test facet aggregation
Properties props = new Properties();
props.put("aggregationMode", "facet");
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost + "?collection=" + COLLECTIONORALIAS, props)) {
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select a_s, sum(a_f) from " + COLLECTIONORALIAS + " group by a_s " +
"order by sum(a_f) desc")) {
assertTrue(rs.next());
assertEquals("hello3", rs.getString("a_s"));
assertEquals("hello3", rs.getString(1));
assertEquals(26, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(26, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(1));
assertEquals(18, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(18, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello4", rs.getString("a_s"));
assertEquals("hello4", rs.getString(1));
assertEquals(11, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(11, rs.getDouble(2), 0);
assertFalse(rs.next());
}
}
}
}
@Test
public void testMapReduceAggregation() throws Exception {
//Test map / reduce aggregation
Properties props = new Properties();
props.put("aggregationMode", "map_reduce");
props.put("numWorkers", "2");
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost + "?collection=" + COLLECTIONORALIAS, props)) {
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select a_s, sum(a_f) from " + COLLECTIONORALIAS + " WHERE a_s IS NOT NULL group by a_s " +
"order by sum(a_f) desc")) {
assertTrue(rs.next());
assertEquals("hello3", rs.getString("a_s"));
assertEquals("hello3", rs.getString(1));
assertEquals(26, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(26, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(1));
assertEquals(18, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(18, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello4", rs.getString("a_s"));
assertEquals("hello4", rs.getString(1));
assertEquals(11, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(11, rs.getDouble(2), 0);
assertFalse(rs.next());
}
}
}
}
@Test
public void testConnectionParams() throws Exception {
//Test params on the url
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost +
"?collection=" + COLLECTIONORALIAS + "&aggregationMode=map_reduce&numWorkers=2")) {
Properties p = ((ConnectionImpl) con).getProperties();
assert (p.getProperty("aggregationMode").equals("map_reduce"));
assert (p.getProperty("numWorkers").equals("2"));
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select a_s, sum(a_f) from " + COLLECTIONORALIAS + " WHERE a_s IS NOT NULL group by a_s " +
"order by sum(a_f) desc")) {
assertTrue(rs.next());
assertEquals("hello3", rs.getString("a_s"));
assertEquals("hello3", rs.getString(1));
assertEquals(26, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(26, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(1));
assertEquals(18, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(18, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello4", rs.getString("a_s"));
assertEquals("hello4", rs.getString(1));
assertEquals(11, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(11, rs.getDouble(2), 0);
assertFalse(rs.next());
}
}
}
}
@Test
public void testJDBCUrlParameters() throws Exception {
// Test JDBC paramters in URL
try (Connection con = DriverManager.getConnection(
"jdbc:solr://" + zkHost + "?collection=" + COLLECTIONORALIAS + "&username=&password=&testKey1=testValue&testKey2")) {
Properties p = ((ConnectionImpl) con).getProperties();
assertEquals("", p.getProperty("username"));
assertEquals("", p.getProperty("password"));
assertEquals("testValue", p.getProperty("testKey1"));
assertEquals("", p.getProperty("testKey2"));
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select a_s, sum(a_f) from " + COLLECTIONORALIAS + " group by a_s " +
"order by sum(a_f) desc")) {
assertTrue(rs.next());
assertEquals("hello3", rs.getString("a_s"));
assertEquals("hello3", rs.getString(1));
assertEquals(26, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(26, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(1));
assertEquals(18, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(18, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello4", rs.getString("a_s"));
assertEquals("hello4", rs.getString(1));
assertEquals(11, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(11, rs.getDouble(2), 0);
assertFalse(rs.next());
}
}
}
}
@Test
public void testJDBCPropertiesParameters() throws Exception {
// Test JDBC paramters in properties
Properties providedProperties = new Properties();
providedProperties.put("collection", COLLECTIONORALIAS);
providedProperties.put("username", "");
providedProperties.put("password", "");
providedProperties.put("testKey1", "testValue");
providedProperties.put("testKey2", "");
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost, providedProperties)) {
Properties p = ((ConnectionImpl) con).getProperties();
assert (p.getProperty("username").equals(""));
assert (p.getProperty("password").equals(""));
assert (p.getProperty("testKey1").equals("testValue"));
assert (p.getProperty("testKey2").equals(""));
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select a_s, sum(a_f) from " + COLLECTIONORALIAS + " group by a_s " +
"order by sum(a_f) desc")) {
assertTrue(rs.next());
assertEquals("hello3", rs.getString("a_s"));
assertEquals("hello3", rs.getString(1));
assertEquals(26, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(26, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello0", rs.getString("a_s"));
assertEquals("hello0", rs.getString(1));
assertEquals(18, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(18, rs.getDouble(2), 0);
assertTrue(rs.next());
assertEquals("hello4", rs.getString("a_s"));
assertEquals("hello4", rs.getString(1));
assertEquals(11, rs.getDouble("EXPR$1"), 0); //sum(a_f)
assertEquals(11, rs.getDouble(2), 0);
assertFalse(rs.next());
}
}
}
}
@Ignore("Fix error checking")
@Test
@SuppressWarnings({"try"})
public void testErrorPropagation() throws Exception {
//Test error propagation
Properties props = new Properties();
props.put("aggregationMode", "facet");
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost + "?collection=" + COLLECTIONORALIAS, props)) {
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select crap from " + COLLECTIONORALIAS + " group by a_s " +
"order by sum(a_f) desc")) {
} catch (Exception e) {
String errorMessage = e.getMessage();
assertTrue(errorMessage.contains("Group by queries must include at least one aggregate function"));
}
}
}
}
@Test
@SuppressWarnings({"try"})
public void testSQLExceptionThrownWhenQueryAndConnUseDiffCollections() throws Exception {
String badCollection = COLLECTIONORALIAS + "bad";
String connectionString = "jdbc:solr://" + zkHost + "?collection=" + badCollection;
String sql = "select id, a_i, a_s, a_f from " + badCollection + " order by a_i desc limit 2";
//Bad connection string: wrong collection name
try(Connection connection = DriverManager.getConnection(connectionString)) {
try (Statement statement = connection.createStatement()) {
try (ResultSet ignored = statement.executeQuery(sql)) {
fail("Expected query against wrong collection to throw a SQLException.");
}
}
} catch (SQLException ignore) {
// Expected exception due to miss matched collection
}
}
@Test
public void testOneEqualZeroMetadata() throws Exception {
// SOLR-8845 - Make sure that 1 = 1 (literal comparison literal) works
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost +
"?collection=" + COLLECTIONORALIAS)) {
try (Statement stmt = con.createStatement()) {
try (ResultSet rs = stmt.executeQuery("select a_s from " + COLLECTIONORALIAS + " where 1 = 0")) {
assertFalse(rs.next());
ResultSetMetaData resultSetMetaData = rs.getMetaData();
assertNotNull(resultSetMetaData);
assertEquals(1, resultSetMetaData.getColumnCount());
assertEquals("a_s", resultSetMetaData.getColumnName(1));
}
}
}
}
@Test
public void testDriverMetadata() throws Exception {
String collection = COLLECTIONORALIAS;
String connectionString1 = "jdbc:solr://" + zkHost + "?collection=" + collection +
"&username=&password=&testKey1=testValue&testKey2";
Properties properties1 = new Properties();
String sql = "select id, a_i, a_s, a_f as my_float_col, testnull_i from " + collection +
" order by a_i desc";
String connectionString2 = "jdbc:solr://" + zkHost + "?collection=" + collection +
"&aggregationMode=map_reduce&numWorkers=2&username=&password=&testKey1=testValue&testKey2";
Properties properties2 = new Properties();
String sql2 = sql + " limit 2";
//testJDBCMethods(collection, connectionString1, properties1, sql);
//testJDBCMethods(collection, connectionString2, properties2, sql);
testJDBCMethods(collection, connectionString1, properties1, sql2);
testJDBCMethods(collection, connectionString2, properties2, sql2);
}
private void testJDBCMethods(String collection, String connectionString, Properties properties, String sql) throws Exception {
try (Connection con = DriverManager.getConnection(connectionString, properties)) {
assertTrue(con.isValid(DEFAULT_CONNECTION_TIMEOUT));
assertTrue("connection should be valid when checked with timeout = 0 -> con.isValid(0)", con.isValid(0));
assertEquals(zkHost, con.getCatalog());
con.setCatalog(zkHost);
assertEquals(zkHost, con.getCatalog());
assertEquals(null, con.getSchema());
con.setSchema("myschema");
assertEquals(null, con.getSchema());
DatabaseMetaData databaseMetaData = con.getMetaData();
assertNotNull(databaseMetaData);
assertEquals(con, databaseMetaData.getConnection());
assertEquals(connectionString, databaseMetaData.getURL());
assertEquals(4, databaseMetaData.getJDBCMajorVersion());
assertEquals(0, databaseMetaData.getJDBCMinorVersion());
assertEquals("Apache Solr", databaseMetaData.getDatabaseProductName());
// The following tests require package information that is not available when running via Maven
// assertEquals(this.getClass().getPackage().getSpecificationVersion(), databaseMetaData.getDatabaseProductVersion());
// assertEquals(0, databaseMetaData.getDatabaseMajorVersion());
// assertEquals(0, databaseMetaData.getDatabaseMinorVersion());
// assertEquals(this.getClass().getPackage().getSpecificationTitle(), databaseMetaData.getDriverName());
// assertEquals(this.getClass().getPackage().getSpecificationVersion(), databaseMetaData.getDriverVersion());
// assertEquals(0, databaseMetaData.getDriverMajorVersion());
// assertEquals(0, databaseMetaData.getDriverMinorVersion());
List<String> tableSchemas = new ArrayList<>(Arrays.asList(zkHost, "metadata"));
try(ResultSet rs = databaseMetaData.getSchemas()) {
assertTrue(rs.next());
assertTrue(tableSchemas.contains(rs.getString("tableSchem")));
tableSchemas.remove(rs.getString("tableSchem"));
assertNull(rs.getString("tableCat"));
assertTrue(rs.next());
assertTrue(tableSchemas.contains(rs.getString("tableSchem")));
tableSchemas.remove(rs.getString("tableSchem"));
assertNull(rs.getString("tableCat"));
assertFalse(rs.next());
assertTrue(tableSchemas.isEmpty());
}
try(ResultSet rs = databaseMetaData.getCatalogs()) {
assertTrue(rs.next());
assertNull(rs.getString("tableCat"));
assertFalse(rs.next());
}
CloudSolrClient solrClient = cluster.getSolrClient();
solrClient.connect();
ZkStateReader zkStateReader = solrClient.getZkStateReader();
Set<String> collectionsSet = zkStateReader.getClusterState().getCollectionsMap().keySet();
SortedSet<String> tables = new TreeSet<>(collectionsSet);
Aliases aliases = zkStateReader.getAliases();
tables.addAll(aliases.getCollectionAliasListMap().keySet());
try(ResultSet rs = databaseMetaData.getTables(null, zkHost, "%", null)) {
for(String table : tables) {
assertTrue(rs.next());
assertNull(rs.getString("tableCat"));
assertEquals(zkHost, rs.getString("tableSchem"));
assertEquals(table, rs.getString("tableName"));
assertEquals("TABLE", rs.getString("tableType"));
assertNull(rs.getString("remarks"));
}
assertFalse(rs.next());
}
assertEquals(Connection.TRANSACTION_NONE, con.getTransactionIsolation());
try {
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
fail("should not have been able to set transaction isolation");
} catch (SQLException e) {
assertEquals(UnsupportedOperationException.class, e.getCause().getClass());
}
assertEquals(Connection.TRANSACTION_NONE, con.getTransactionIsolation());
assertTrue(con.isReadOnly());
con.setReadOnly(true);
assertTrue(con.isReadOnly());
assertNull(con.getWarnings());
con.clearWarnings();
assertNull(con.getWarnings());
try (Statement statement = con.createStatement()) {
checkStatement(con, statement);
try (ResultSet rs = statement.executeQuery(sql)) {
assertEquals(statement, rs.getStatement());
checkResultSetMetadata(rs);
checkResultSet(rs);
}
assertTrue(statement.execute(sql));
assertEquals(-1, statement.getUpdateCount());
try (ResultSet rs = statement.getResultSet()) {
assertEquals(statement, rs.getStatement());
checkResultSetMetadata(rs);
checkResultSet(rs);
}
assertFalse(statement.getMoreResults());
}
try (PreparedStatement statement = con.prepareStatement(sql)) {
checkStatement(con, statement);
try (ResultSet rs = statement.executeQuery()) {
assertEquals(statement, rs.getStatement());
checkResultSetMetadata(rs);
checkResultSet(rs);
}
assertTrue(statement.execute());
assertEquals(-1, statement.getUpdateCount());
try (ResultSet rs = statement.getResultSet()) {
assertEquals(statement, rs.getStatement());
checkResultSetMetadata(rs);
checkResultSet(rs);
}
assertFalse(statement.getMoreResults());
}
}
}
private void checkStatement(Connection con, Statement statement) throws Exception {
assertEquals(con, statement.getConnection());
assertNull(statement.getWarnings());
statement.clearWarnings();
assertNull(statement.getWarnings());
assertEquals(ResultSet.TYPE_FORWARD_ONLY, statement.getResultSetType());
assertEquals(ResultSet.CONCUR_READ_ONLY, statement.getResultSetConcurrency());
assertEquals(ResultSet.FETCH_FORWARD, statement.getFetchDirection());
statement.setFetchDirection(ResultSet.FETCH_FORWARD);
assertEquals(ResultSet.FETCH_FORWARD, statement.getFetchDirection());
assertEquals(0, statement.getFetchSize());
statement.setFetchSize(0);
assertEquals(0, statement.getFetchSize());
}
private void checkResultSetMetadata(ResultSet rs) throws Exception {
ResultSetMetaData resultSetMetaData = rs.getMetaData();
assertNotNull(resultSetMetaData);
assertEquals(5, resultSetMetaData.getColumnCount());
assertEquals("id", resultSetMetaData.getColumnName(1));
assertEquals("a_i", resultSetMetaData.getColumnName(2));
assertEquals("a_s", resultSetMetaData.getColumnName(3));
assertEquals("a_f", resultSetMetaData.getColumnName(4));
assertEquals("testnull_i", resultSetMetaData.getColumnName(5));
assertEquals("id", resultSetMetaData.getColumnLabel(1));
assertEquals("a_i", resultSetMetaData.getColumnLabel(2));
assertEquals("a_s", resultSetMetaData.getColumnLabel(3));
assertEquals("my_float_col", resultSetMetaData.getColumnLabel(4));
assertEquals("testnull_i", resultSetMetaData.getColumnLabel(5));
assertEquals("id".length(), resultSetMetaData.getColumnDisplaySize(1));
assertEquals("a_i".length(), resultSetMetaData.getColumnDisplaySize(2));
assertEquals("a_s".length(), resultSetMetaData.getColumnDisplaySize(3));
assertEquals("my_float_col".length(), resultSetMetaData.getColumnDisplaySize(4));
assertEquals("testnull_i".length(), resultSetMetaData.getColumnDisplaySize(5));
assertEquals("String", resultSetMetaData.getColumnTypeName(1));
assertEquals("Long", resultSetMetaData.getColumnTypeName(2));
assertEquals("String", resultSetMetaData.getColumnTypeName(3));
assertEquals("Double", resultSetMetaData.getColumnTypeName(4));
assertEquals("Long", resultSetMetaData.getColumnTypeName(5));
assertEquals(Types.VARCHAR, resultSetMetaData.getColumnType(1));
assertEquals(Types.DOUBLE, resultSetMetaData.getColumnType(2));
assertEquals(Types.VARCHAR, resultSetMetaData.getColumnType(3));
assertEquals(Types.DOUBLE, resultSetMetaData.getColumnType(4));
assertEquals(Types.DOUBLE, resultSetMetaData.getColumnType(5));
}
private void checkResultSet(ResultSet rs) throws Exception {
assertNull(rs.getWarnings());
rs.clearWarnings();
assertNull(rs.getWarnings());
assertEquals(ResultSet.TYPE_FORWARD_ONLY, rs.getType());
assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency());
assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
rs.setFetchDirection(ResultSet.FETCH_FORWARD);
assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
assertEquals(0, rs.getFetchSize());
rs.setFetchSize(10);
assertEquals(0, rs.getFetchSize());
assertTrue(rs.next());
assertEquals(14L, rs.getObject("a_i"));
assertFalse(rs.wasNull());
assertEquals(14L, rs.getObject(2));
assertFalse(rs.wasNull());
assertEquals(14L, rs.getLong("a_i"));
assertFalse(rs.wasNull());
assertEquals(14L, rs.getLong(2));
assertFalse(rs.wasNull());
assertEquals(14D, rs.getDouble("a_i"), 0);
assertFalse(rs.wasNull());
assertEquals(14D, rs.getDouble(2), 0);
assertFalse(rs.wasNull());
assertEquals(14f, rs.getFloat("a_i"), 0);
assertFalse(rs.wasNull());
assertEquals(14f, rs.getFloat(2), 0);
assertFalse(rs.wasNull());
assertEquals(14, rs.getShort("a_i"));
assertFalse(rs.wasNull());
assertEquals(14, rs.getShort(2));
assertFalse(rs.wasNull());
assertEquals(14, rs.getByte("a_i"));
assertFalse(rs.wasNull());
assertEquals(14, rs.getByte(2));
assertFalse(rs.wasNull());
assertEquals("hello0", rs.getObject("a_s"));
assertFalse(rs.wasNull());
assertEquals("hello0", rs.getObject(3));
assertFalse(rs.wasNull());
assertEquals("hello0", rs.getString("a_s"));
assertFalse(rs.wasNull());
assertEquals("hello0", rs.getString(3));
assertFalse(rs.wasNull());
assertEquals(10D, rs.getObject("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(10D, rs.getObject(4));
assertFalse(rs.wasNull());
assertEquals(10D, rs.getDouble("my_float_col"), 0);
assertFalse(rs.wasNull());
assertEquals(10D, rs.getDouble(4), 0);
assertFalse(rs.wasNull());
assertEquals(10F, rs.getFloat("my_float_col"), 0);
assertFalse(rs.wasNull());
assertEquals(10F, rs.getFloat(4), 0);
assertFalse(rs.wasNull());
assertEquals(10, rs.getInt("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(10, rs.getInt(4));
assertFalse(rs.wasNull());
assertEquals(10L, rs.getLong("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(10L, rs.getLong(4));
assertFalse(rs.wasNull());
assertEquals(10, rs.getShort("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(10, rs.getShort(4));
assertFalse(rs.wasNull());
assertEquals(10, rs.getByte("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(10, rs.getByte(4));
assertFalse(rs.wasNull());
assertEquals(10L, rs.getObject("testnull_i"));
assertFalse(rs.wasNull());
assertEquals(10L, rs.getObject(5));
assertFalse(rs.wasNull());
assertEquals("10", rs.getString("testnull_i"));
assertFalse(rs.wasNull());
assertEquals("10", rs.getString(5));
assertFalse(rs.wasNull());
assertEquals(10D, rs.getDouble("testnull_i"), 0);
assertFalse(rs.wasNull());
assertEquals(10D, rs.getDouble(5), 0);
assertFalse(rs.wasNull());
assertEquals(10F, rs.getFloat("testnull_i"), 0);
assertFalse(rs.wasNull());
assertEquals(10F, rs.getFloat(5), 0);
assertFalse(rs.wasNull());
assertEquals(10, rs.getInt("testnull_i"));
assertFalse(rs.wasNull());
assertEquals(10, rs.getInt(5));
assertFalse(rs.wasNull());
assertEquals(10L, rs.getLong("testnull_i"));
assertFalse(rs.wasNull());
assertEquals(10L, rs.getLong(5));
assertFalse(rs.wasNull());
assertEquals(10, rs.getShort("testnull_i"));
assertFalse(rs.wasNull());
assertEquals(10, rs.getShort(5));
assertFalse(rs.wasNull());
assertEquals(10, rs.getByte("testnull_i"));
assertFalse(rs.wasNull());
assertEquals(10, rs.getByte(5));
assertFalse(rs.wasNull());
assertTrue(rs.next());
assertEquals(13L, rs.getObject("a_i"));
assertFalse(rs.wasNull());
assertEquals(13L, rs.getObject(2));
assertFalse(rs.wasNull());
assertEquals(13L, rs.getLong("a_i"));
assertFalse(rs.wasNull());
assertEquals(13L, rs.getLong(2));
assertFalse(rs.wasNull());
assertEquals(13D, rs.getDouble("a_i"), 0);
assertFalse(rs.wasNull());
assertEquals(13D, rs.getDouble(2), 0);
assertFalse(rs.wasNull());
assertEquals(13f, rs.getFloat("a_i"), 0);
assertFalse(rs.wasNull());
assertEquals(13f, rs.getFloat(2), 0);
assertFalse(rs.wasNull());
assertEquals(13, rs.getShort("a_i"));
assertFalse(rs.wasNull());
assertEquals(13, rs.getShort(2));
assertFalse(rs.wasNull());
assertEquals(13, rs.getByte("a_i"));
assertFalse(rs.wasNull());
assertEquals(13, rs.getByte(2));
assertFalse(rs.wasNull());
assertEquals("hello3", rs.getObject("a_s"));
assertFalse(rs.wasNull());
assertEquals("hello3", rs.getObject(3));
assertFalse(rs.wasNull());
assertEquals("hello3", rs.getString("a_s"));
assertFalse(rs.wasNull());
assertEquals("hello3", rs.getString(3));
assertFalse(rs.wasNull());
assertEquals(9D, rs.getObject("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(9D, rs.getObject(4));
assertFalse(rs.wasNull());
assertEquals(9D, rs.getDouble("my_float_col"), 0);
assertFalse(rs.wasNull());
assertEquals(9D, rs.getDouble(4), 0);
assertFalse(rs.wasNull());
assertEquals(9F, rs.getFloat("my_float_col"), 0);
assertFalse(rs.wasNull());
assertEquals(9F, rs.getFloat(4), 0);
assertFalse(rs.wasNull());
assertEquals(9, rs.getInt("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(9, rs.getInt(4));
assertFalse(rs.wasNull());
assertEquals(9L, rs.getLong("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(9L, rs.getLong(4));
assertFalse(rs.wasNull());
assertEquals(9, rs.getShort("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(9, rs.getShort(4));
assertFalse(rs.wasNull());
assertEquals(9, rs.getByte("my_float_col"));
assertFalse(rs.wasNull());
assertEquals(9, rs.getByte(4));
assertFalse(rs.wasNull());
assertEquals(null, rs.getObject("testnull_i"));
assertTrue(rs.wasNull());
assertEquals(null, rs.getObject(5));
assertTrue(rs.wasNull());
assertEquals(null, rs.getString("testnull_i"));
assertTrue(rs.wasNull());
assertEquals(null, rs.getString(5));
assertTrue(rs.wasNull());
assertEquals(0D, rs.getDouble("testnull_i"), 0);
assertTrue(rs.wasNull());
assertEquals(0D, rs.getDouble(5), 0);
assertTrue(rs.wasNull());
assertEquals(0F, rs.getFloat("testnull_i"), 0);
assertTrue(rs.wasNull());
assertEquals(0F, rs.getFloat(5), 0);
assertTrue(rs.wasNull());
assertEquals(0, rs.getInt("testnull_i"));
assertTrue(rs.wasNull());
assertEquals(0, rs.getInt(5));
assertTrue(rs.wasNull());
assertEquals(0L, rs.getLong("testnull_i"));
assertTrue(rs.wasNull());
assertEquals(0L, rs.getLong(5));
assertTrue(rs.wasNull());
assertEquals(0, rs.getShort("testnull_i"));
assertTrue(rs.wasNull());
assertEquals(0, rs.getShort(5));
assertTrue(rs.wasNull());
assertEquals(0, rs.getByte("testnull_i"));
assertTrue(rs.wasNull());
assertEquals(0, rs.getByte(5));
assertTrue(rs.wasNull());
assertFalse(rs.next());
}
@Test
public void doTestMultiValued() throws Exception {
Properties props = new Properties();
try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost + "?collection=" + COLLECTIONORALIAS, props)) {
try (Statement stmt = con.createStatement()) {
// Multi-valued field projection
try (ResultSet rs = stmt.executeQuery("select id, s_multi, d_multi from " + COLLECTIONORALIAS + " WHERE s_multi IS NOT NULL order by id desc limit 2")) {
assertTrue(rs.next());
assertEquals(Arrays.asList("a", "b", "c"), rs.getObject("s_multi"));
assertEquals(Arrays.asList(3d, 4d, 5d), rs.getObject("d_multi"));
assertTrue(rs.next());
assertEquals(Arrays.asList("abc", "lmn", "xyz"), rs.getObject("s_multi"));
assertEquals(Arrays.asList(1d, 2d, 3d), rs.getObject("d_multi"));
assertFalse(rs.next());
}
// Filtering with multi-valued fields
try (ResultSet rs = stmt.executeQuery("select id, s_multi, d_multi from " + COLLECTIONORALIAS + " WHERE s_multi IN ('a', 'abc') AND d_multi >= 1 order by id desc limit 2")) {
assertTrue(rs.next());
assertEquals(Arrays.asList("a", "b", "c"), rs.getObject("s_multi"));
assertEquals(Arrays.asList(3d, 4d, 5d), rs.getObject("d_multi"));
assertTrue(rs.next());
assertEquals(Arrays.asList("abc", "lmn", "xyz"), rs.getObject("s_multi"));
assertEquals(Arrays.asList(1d, 2d, 3d), rs.getObject("d_multi"));
assertFalse(rs.next());
}
// group by multi-valued
try (ResultSet rs = stmt.executeQuery("select count(*) as the_count, d_multi from " + COLLECTIONORALIAS + " WHERE d_multi IS NOT NULL GROUP BY d_multi ORDER BY count(*) DESC")) {
assertTrue(rs.next());
assertEquals(2, rs.getLong("the_count"));
assertTrue(3d == rs.getDouble("d_multi"));
assertTrue(rs.next()); // 4 other values, all with count 1
assertTrue(rs.next());
assertTrue(rs.next());
assertTrue(rs.next());
assertFalse(rs.next());
}
}
}
}
}