content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to you under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.calcite.avatica;
  
  import org.apache.calcite.avatica.remote.TypedValue;
  
  import org.junit.After;
  import org.junit.Before;
  import org.junit.Test;
  
  import java.sql.Connection;
  import java.sql.DatabaseMetaData;
  import java.sql.ResultSet;
  import java.sql.ResultSetMetaData;
  import java.sql.SQLException;
  import java.sql.Types;
  import java.util.List;
  import java.util.Locale;
  
  import static org.junit.Assert.assertEquals;
  
  /**
   * Test that {@code ResultSet} returned by {@code DatabaseMetaData} methods
   * conform to JDBC specification.
   */
  public class MetaResultSetTest {
    /**
     * A fake test driver for test.
     */
    private static final class TestDriver extends UnregisteredDriver {
  
      @Override protected DriverVersion createDriverVersion() {
        return new DriverVersion("test", "test 0.0.0", "test", "test 0.0.0", false, 0, 0, 0, 0);
      }
  
      @Override protected String getConnectStringPrefix() {
        return "jdbc:test";
      }
  
      @Override public Meta createMeta(AvaticaConnection connection) {
        return new TestMetaImpl(connection);
      }
    }
  
    /**
     * Fake meta implementation for test driver.
     */
    public static final class TestMetaImpl extends MetaImpl {
      public TestMetaImpl(AvaticaConnection connection) {
        super(connection);
      }
  
      @Override public StatementHandle prepare(ConnectionHandle ch, String sql, long maxRowCount) {
        throw new UnsupportedOperationException();
      }
  
      @SuppressWarnings("deprecation")
      @Override public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
          long maxRowCount, PrepareCallback callback) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
          long maxRowCount, int maxRowsInFirstFrame, PrepareCallback callback)
          throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public ExecuteBatchResult prepareAndExecuteBatch(StatementHandle h,
          List<String> sqlCommands) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public ExecuteBatchResult executeBatch(StatementHandle h,
          List<List<TypedValue>> parameterValues) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public Frame fetch(StatementHandle h, long offset, int fetchMaxRowCount)
          throws NoSuchStatementException, MissingResultsException {
        throw new UnsupportedOperationException();
      }
  
      @SuppressWarnings("deprecation")
      @Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
          long maxRowCount) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
          int maxRowsInFirstFrame) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public void closeStatement(StatementHandle h) {
      }
  
      @Override public boolean syncResults(StatementHandle sh, QueryState state, long offset)
          throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public void commit(ConnectionHandle ch) {
        throw new UnsupportedOperationException();
      }
  
      @Override public void rollback(ConnectionHandle ch) {
        throw new UnsupportedOperationException();
      }
    }
  
    private Connection connection;
  
    @Before public void setUp() throws SQLException {
      connection = new TestDriver().connect("jdbc:test", null);
    }
  
    @After public void tearDown() throws SQLException {
      connection.close();
    }
  
    @Test public void testGetAttributes() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getAttributes(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(21, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TYPE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TYPE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "ATTR_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "ATTR_TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 7, "ATTR_SIZE", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 8, "DECIMAL_DIGITS", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 9, "NUM_PREC_RADIX", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 10, "NULLABLE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 11, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 12, "ATTR_DEF", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 13, "SQL_DATA_TYPE", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 14, "SQL_DATETIME_SUB", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 15, "CHAR_OCTET_LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 16, "ORDINAL_POSITION", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 17, "IS_NULLABLE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 18, "SCOPE_CATALOG", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 19, "SCOPE_SCHEMA", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 20, "SCOPE_TABLE", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 21, "SOURCE_DATA_TYPE", Types.SMALLINT, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetBestRowIdentifier() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getBestRowIdentifier(null, null, null,
          DatabaseMetaData.bestRowUnknown, false)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(8, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "SCOPE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 2, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 3, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "COLUMN_SIZE", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "BUFFER_LENGTH", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 7, "DECIMAL_DIGITS", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 8, "PSEUDO_COLUMN", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetCatalogs() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getCatalogs()) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(1, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetClientInfoProperties() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getClientInfoProperties()) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(4, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 2, "MAX_LEN", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 3, "DEFAULT_VALUE", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 4, "DESCRIPTION", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetColumnPrivileges() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getColumnPrivileges(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(8, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "GRANTOR", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "GRANTEE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 7, "PRIVILEGE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "IS_GRANTABLE", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetColumns() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getColumns(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(24, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 7, "COLUMN_SIZE", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 8, "BUFFER_LENGTH", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 9, "DECIMAL_DIGITS", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 10, "NUM_PREC_RADIX", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 11, "NULLABLE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 12, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 13, "COLUMN_DEF", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 14, "SQL_DATA_TYPE", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 15, "SQL_DATETIME_SUB", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 16, "CHAR_OCTET_LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 17, "ORDINAL_POSITION", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 18, "IS_NULLABLE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 19, "SCOPE_CATALOG", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 20, "SCOPE_SCHEMA", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 21, "SCOPE_TABLE", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 22, "SOURCE_DATA_TYPE", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 23, "IS_AUTOINCREMENT", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 24, "IS_GENERATEDCOLUMN", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetCrossReference() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getCrossReference(null, null, null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(14, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "PKTABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "PKTABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "PKTABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "PKCOLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "FKTABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "FKTABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "FKTABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "FKCOLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 9, "KEY_SEQ", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 10, "UPDATE_RULE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 11, "DELETE_RULE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 12, "FK_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 13, "PK_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 14, "DEFERABILITY", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetExportedKeys() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getExportedKeys(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(14, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "PKTABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "PKTABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "PKTABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "PKCOLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "FKTABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "FKTABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "FKTABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "FKCOLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 9, "KEY_SEQ", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 10, "UPDATE_RULE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 11, "DELETE_RULE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 12, "FK_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 13, "PK_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 14, "DEFERABILITY", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetFunctionColumns() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getFunctionColumns(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(17, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "FUNCTION_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "FUNCTION_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "FUNCTION_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "COLUMN_TYPE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 7, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "PRECISION", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 9, "LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 10, "SCALE", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 11, "RADIX", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 12, "NULLABLE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 13, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 14, "CHAR_OCTET_LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 15, "ORDINAL_POSITION", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 16, "IS_NULLABLE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 17, "SPECIFIC_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetFunctions() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getFunctions(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(6, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "FUNCTION_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "FUNCTION_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "FUNCTION_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 5, "FUNCTION_TYPE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "SPECIFIC_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetImportedKeys() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getImportedKeys(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(14, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "PKTABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "PKTABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "PKTABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "PKCOLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "FKTABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "FKTABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "FKTABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "FKCOLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 9, "KEY_SEQ", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 10, "UPDATE_RULE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 11, "DELETE_RULE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 12, "FK_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 13, "PK_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 14, "DEFERABILITY", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetIndexInfo() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getIndexInfo(null, null, null, false, false)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(13, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "NON_UNIQUE", Types.BOOLEAN, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "INDEX_QUALIFIER", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "INDEX_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "TYPE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "ORDINAL_POSITION", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 9, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 10, "ASC_OR_DESC", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 11, "CARDINALITY", Types.BIGINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 12, "PAGES", Types.BIGINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 13, "FILTER_CONDITION", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetPrimaryKeys() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getPrimaryKeys(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(6, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "KEY_SEQ", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "PK_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetProcedureColumns() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getProcedureColumns(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(20, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "PROCEDURE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "PROCEDURE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "PROCEDURE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "COLUMN_TYPE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 7, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "PRECISION", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 9, "LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 10, "SCALE", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 11, "RADIX", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 12, "NULLABLE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 13, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 14, "COLUMN_DEF", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 15, "SQL_DATA_TYPE", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 16, "SQL_DATETIME_SUB", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 17, "CHAR_OCTET_LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 18, "ORDINAL_POSITION", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 19, "IS_NULLABLE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 20, "SPECIFIC_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetProcedures() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getProcedures(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(9, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "PROCEDURE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "PROCEDURE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "PROCEDURE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 7, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 8, "PROCEDURE_TYPE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 9, "SPECIFIC_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetPseudoColumns() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getPseudoColumns(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(12, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "COLUMN_SIZE", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "DECIMAL_DIGITS", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 8, "NUM_PREC_RADIX", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 9, "COLUMN_USAGE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 10, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 11, "CHAR_OCTET_LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 12, "IS_NULLABLE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetSchemas() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getSchemas(null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(2, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 2, "TABLE_CATALOG", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetSuperTables() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getSuperTables(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(4, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "SUPERTABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetSuperTypes() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getSuperTypes(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(6, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TYPE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TYPE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "SUPERTYPE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 5, "SUPERTYPE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "SUPERTYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetTablePrivileges() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getTablePrivileges(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(7, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "GRANTOR", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 5, "GRANTEE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "PRIVILEGE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 7, "IS_GRANTABLE", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetTables() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getTables(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(10, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TABLE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TABLE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "TABLE_TYPE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "TYPE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "TYPE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 8, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 9, "SELF_REFERENCING_COL_NAME", Types.VARCHAR,
            DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 10, "REF_GENERATION", Types.VARCHAR, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetTableTypes() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getTableTypes()) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(1, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TABLE_TYPE", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
      }
    }
  
    @Test public void testGetTypeInfo() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getTypeInfo()) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(18, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 2, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 3, "PRECISION", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 4, "LITERAL_PREFIX", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 5, "LITERAL_SUFFIX", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "CREATE_PARAMS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "NULLABLE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 8, "CASE_SENSITIVE", Types.BOOLEAN, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 9, "SEARCHABLE", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 10, "UNSIGNED_ATTRIBUTE", Types.BOOLEAN, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 11, "FIXED_PREC_SCALE", Types.BOOLEAN, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 12, "AUTO_INCREMENT", Types.BOOLEAN, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 13, "LOCAL_TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 14, "MINIMUM_SCALE", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 15, "MAXIMUM_SCALE", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 16, "SQL_DATA_TYPE", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 17, "SQL_DATETIME_SUB", Types.INTEGER,
            DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 18, "NUM_PREC_RADIX", Types.INTEGER, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetUDTs() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getUDTs(null, null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(7, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "TYPE_CAT", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 2, "TYPE_SCHEM", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 3, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "CLASS_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 6, "REMARKS", Types.VARCHAR, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "BASE_TYPE", Types.SMALLINT, DatabaseMetaData.columnNullable);
      }
    }
  
    @Test public void testGetVersionColumns() throws SQLException {
      DatabaseMetaData metadata = getDatabaseMetadata();
      try (ResultSet rs = metadata.getVersionColumns(null, null, null)) {
        ResultSetMetaData rsMeta = rs.getMetaData();
  
        assertEquals(8, rsMeta.getColumnCount());
        assertColumn(rsMeta, 1, "SCOPE", Types.SMALLINT, DatabaseMetaData.columnNullableUnknown);
        assertColumn(rsMeta, 2, "COLUMN_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 3, "DATA_TYPE", Types.INTEGER, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 4, "TYPE_NAME", Types.VARCHAR, DatabaseMetaData.columnNoNulls);
        assertColumn(rsMeta, 5, "COLUMN_SIZE", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 6, "BUFFER_LENGTH", Types.INTEGER, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 7, "DECIMAL_DIGITS", Types.SMALLINT, DatabaseMetaData.columnNullable);
        assertColumn(rsMeta, 8, "PSEUDO_COLUMN", Types.SMALLINT, DatabaseMetaData.columnNoNulls);
      }
    }
  
    private static void assertColumn(ResultSetMetaData rsMeta, int column, String name, int type,
        int nullable) throws SQLException {
      assertEquals(
          String.format(Locale.ROOT,
              "Expected column %d to be named '%s', was '%s'.",
              column, name, rsMeta.getColumnName(column)),
          name,
          rsMeta.getColumnName(column));
  
      assertEquals(
          String.format(Locale.ROOT,
              "Expected column %d type to be '%d', was '%d'.",
              column, type, rsMeta.getColumnType(column)),
          type,
          rsMeta.getColumnType(column));
  
      assertEquals(
          String.format(Locale.ROOT,
              "Expected column %d nullability to be '%d', was '%d'.",
              column, nullable, rsMeta.isNullable(column)),
          nullable,
          rsMeta.isNullable(column));
    }
  
    private DatabaseMetaData getDatabaseMetadata() throws SQLException {
      return connection.getMetaData();
    }
  
  }
  
  // End MetaResultSetTest.java
  