/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS 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
