// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2012-2014 Monty Program Ab
// Copyright (c) 2015-2021 MariaDB Corporation Ab

package org.mariadb.jdbc;

import java.sql.*;
import java.sql.Statement;
import java.text.ParseException;
import java.util.*;
import org.mariadb.jdbc.client.DataType;
import org.mariadb.jdbc.client.ServerVersion;
import org.mariadb.jdbc.client.result.CompleteResult;
import org.mariadb.jdbc.client.result.Result;
import org.mariadb.jdbc.util.VersionFactory;
import org.mariadb.jdbc.util.constants.ColumnFlags;
import org.mariadb.jdbc.util.constants.ServerStatus;

/** Mariadb Database metadata */
public class DatabaseMetaData implements java.sql.DatabaseMetaData {

  /** MariaDB driver name */
  public static final String DRIVER_NAME = "MariaDB Connector/J";

  private final org.mariadb.jdbc.Connection connection;
  private final Configuration conf;

  /**
   * Constructor.
   *
   * @param connection connection
   * @param conf configuration
   */
  public DatabaseMetaData(org.mariadb.jdbc.Connection connection, Configuration conf) {
    this.connection = connection;
    this.conf = conf;
  }

  private static String DataTypeClause(Configuration conf) {
    String upperCaseWithoutSize =
        " UCASE(IF( COLUMN_TYPE LIKE '%(%)%', CONCAT(SUBSTRING( COLUMN_TYPE,1, LOCATE('(',"
            + "COLUMN_TYPE) - 1 ), SUBSTRING(COLUMN_TYPE ,1+locate(')', COLUMN_TYPE))), "
            + "COLUMN_TYPE))";

    if (conf.tinyInt1isBit()) {
      upperCaseWithoutSize =
          " IF(COLUMN_TYPE like 'tinyint(1)%', '"
              + (conf.transformedBitIsBoolean() ? "BOOLEAN" : "BIT")
              + "', "
              + upperCaseWithoutSize
              + ")";
    }

    if (!conf.yearIsDateType()) {
      return " IF(COLUMN_TYPE IN ('year(2)', 'year(4)'), 'SMALLINT', " + upperCaseWithoutSize + ")";
    }

    return upperCaseWithoutSize;
  }

  // Extract identifier quoted string from input String.
  // Return new position, or -1 on error
  private static int skipWhiteSpace(char[] part, int startPos) {
    for (int i = startPos; i < part.length; i++) {
      if (!Character.isWhitespace(part[i])) {
        return i;
      }
    }
    return part.length;
  }

  private static int parseIdentifier(char[] part, int startPos, Identifier identifier)
      throws ParseException {
    int pos = skipWhiteSpace(part, startPos);
    if (part[pos] != '`') {
      throw new ParseException(new String(part), pos);
    }
    pos++;
    StringBuilder sb = new StringBuilder();
    int quotes = 0;
    for (; pos < part.length; pos++) {
      char ch = part[pos];
      if (ch == '`') {
        quotes++;
      } else {
        for (int j = 0; j < quotes / 2; j++) {
          sb.append('`');
        }
        if (quotes % 2 == 1) {
          if (ch == '.') {
            if (identifier.schema != null) {
              throw new ParseException(new String(part), pos);
            }
            identifier.schema = sb.toString();
            return parseIdentifier(part, pos + 1, identifier);
          }
          identifier.name = sb.toString();
          return pos;
        }
        quotes = 0;
        sb.append(ch);
      }
    }
    throw new ParseException(new String(part), startPos);
  }

  private static int skipKeyword(char[] part, int startPos, String keyword) throws ParseException {
    int pos = skipWhiteSpace(part, startPos);
    for (int i = 0; i < keyword.length(); i++, pos++) {
      if (part[pos] != keyword.charAt(i)) {
        throw new ParseException(new String(part), pos);
      }
    }
    return pos;
  }

  private static int getImportedKeyAction(String actionKey) {
    if (actionKey == null) {
      return java.sql.DatabaseMetaData.importedKeyRestrict;
    }
    switch (actionKey) {
      case "NO ACTION":
        return java.sql.DatabaseMetaData.importedKeyNoAction;

      case "CASCADE":
        return java.sql.DatabaseMetaData.importedKeyCascade;

      case "SET NULL":
        return java.sql.DatabaseMetaData.importedKeySetNull;

      case "SET DEFAULT":
        return java.sql.DatabaseMetaData.importedKeySetDefault;

      case "RESTRICT":
        return java.sql.DatabaseMetaData.importedKeyRestrict;

      default:
        throw new IllegalArgumentException("Illegal key action '" + actionKey + "' specified.");
    }
  }

  private static String quoteIdentifier(String string) {
    return "`" + string.replaceAll("`", "``") + "`";
  }

  /**
   * Escape String.
   *
   * @param value value to escape
   * @param noBackslashEscapes must backslash be escaped
   * @return escaped string.
   */
  public static String escapeString(String value, boolean noBackslashEscapes) {
    if (noBackslashEscapes) {
      return value.replace("'", "''");
    }
    return value
        .replace("\\", "\\\\")
        .replace("'", "\\'")
        .replace("\0", "\\0")
        .replace("\"", "\\\"");
  }

  private int parseIdentifierList(char[] part, int startPos, List<Identifier> list)
      throws ParseException {
    int pos = skipWhiteSpace(part, startPos);
    if (part[pos] != '(') {
      throw new ParseException(new String(part), pos);
    }
    pos++;
    for (; ; ) {
      pos = skipWhiteSpace(part, pos);
      char ch = part[pos];
      switch (ch) {
        case ')':
          return pos + 1;
        case '`':
          Identifier id = new Identifier();
          pos = parseIdentifier(part, pos, id);
          list.add(id);
          break;
        case ',':
          pos++;
          break;
        default:
          throw new ParseException(new String(part, startPos, part.length - startPos), startPos);
      }
    }
  }

  /**
   * Get imported keys.
   *
   * @param tableDef table definition
   * @param tableName table name
   * @param catalog catalog
   * @param connection connection
   * @return resultset resultset
   * @throws ParseException exception
   */
  private ResultSet getImportedKeys(
      String tableDef, String tableName, String catalog, org.mariadb.jdbc.Connection connection)
      throws Exception, SQLException {
    boolean importedKeysWithConstraintNames =
        Boolean.parseBoolean(
            conf.nonMappedOptions().getProperty("importedKeysWithConstraintNames", "true"));
    String[] columnNames = {
      "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
      "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
      "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
      "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
      "PK_NAME", "DEFERRABILITY"
    };
    DataType[] dataTypes = {
      DataType.VARCHAR, DataType.NULL, DataType.VARCHAR,
      DataType.VARCHAR, DataType.VARCHAR, DataType.NULL,
      DataType.VARCHAR, DataType.VARCHAR, DataType.SMALLINT,
      DataType.SMALLINT, DataType.SMALLINT, DataType.VARCHAR,
      DataType.VARCHAR, DataType.SMALLINT
    };

    String[] parts = tableDef.split("\n");

    List<String[]> data = new ArrayList<>();

    for (String part : parts) {
      part = part.trim();
      if (!part.toUpperCase(Locale.ROOT).startsWith("CONSTRAINT")
          && !part.toUpperCase(Locale.ROOT).contains("FOREIGN KEY")) {
        continue;
      }
      char[] partChar = part.toCharArray();

      Identifier constraintName = new Identifier();

      int pos = skipKeyword(partChar, 0, "CONSTRAINT");
      pos = parseIdentifier(partChar, pos, constraintName);
      pos = skipKeyword(partChar, pos, "FOREIGN KEY");
      List<Identifier> foreignKeyCols = new ArrayList<>();
      pos = parseIdentifierList(partChar, pos, foreignKeyCols);
      pos = skipKeyword(partChar, pos, "REFERENCES");
      Identifier pkTable = new Identifier();
      pos = parseIdentifier(partChar, pos, pkTable);
      List<Identifier> primaryKeyCols = new ArrayList<>();
      parseIdentifierList(partChar, pos, primaryKeyCols);

      int onUpdateReferenceAction = java.sql.DatabaseMetaData.importedKeyRestrict;
      int onDeleteReferenceAction = java.sql.DatabaseMetaData.importedKeyRestrict;

      for (String referenceAction :
          new String[] {"RESTRICT", "CASCADE", "SET NULL", "NO ACTION", "SET DEFAULT"}) {
        if (part.toUpperCase(Locale.ROOT).contains("ON UPDATE " + referenceAction)) {
          onUpdateReferenceAction = getImportedKeyAction(referenceAction);
        }
        if (part.toUpperCase(Locale.ROOT).contains("ON DELETE " + referenceAction)) {
          onDeleteReferenceAction = getImportedKeyAction(referenceAction);
        }
      }
      Map<String, Map<String[], String>> externalInfos = new HashMap<>();
      for (int i = 0; i < primaryKeyCols.size(); i++) {

        String[] row = new String[columnNames.length];
        row[0] = pkTable.schema; // PKTABLE_CAT
        if (row[0] == null) {
          row[0] = catalog;
        }
        row[1] = null; // PKTABLE_SCHEM
        row[2] = pkTable.name; // PKTABLE_NAME
        row[3] = primaryKeyCols.get(i).name; // PKCOLUMN_NAME
        row[4] = catalog; // FKTABLE_CAT
        row[5] = null; // FKTABLE_SCHEM
        row[6] = tableName; // FKTABLE_NAME
        row[7] = foreignKeyCols.get(i).name; // FKCOLUMN_NAME
        row[8] = Integer.toString(i + 1); // KEY_SEQ
        row[9] = Integer.toString(onUpdateReferenceAction); // UPDATE_RULE
        row[10] = Integer.toString(onDeleteReferenceAction); // DELETE_RULE
        row[11] = constraintName.name; // FK_NAME
        if (importedKeysWithConstraintNames) {
          String ext =
              (pkTable.schema == null ? "" : quoteIdentifier(pkTable.schema) + ".")
                  + quoteIdentifier(pkTable.name);
          if (!externalInfos.containsKey(ext)) {
            externalInfos.put(ext, getExtImportedKeys(ext, connection));
          }
          row[12] = null; // PK_NAME
          Map<String[], String> externalInfo = externalInfos.get(ext);
          if (externalInfo != null) {
            for (Map.Entry<String[], String> entry : externalInfo.entrySet()) {
              boolean foundAll = true;

              for (String keyPart : entry.getKey()) {
                boolean foundKey = false;
                for (Identifier keyCol : primaryKeyCols) {
                  if (keyCol.name.equals(keyPart)) {
                    foundKey = true;
                    break;
                  }
                }
                if (!foundKey) foundAll = false;
              }
              if (foundAll) {
                row[12] = entry.getValue();
              }
            }
          }
        } else {
          row[12] = null; // PK_NAME
        }
        row[13] = Integer.toString(DatabaseMetaData.importedKeyNotDeferrable); // DEFERRABILITY
        data.add(row);
      }
    }
    String[][] arr = data.toArray(new String[0][]);

    /* Sort array by PKTABLE_CAT, PKTABLE_NAME, and KEY_SEQ.*/
    Arrays.sort(
        arr,
        (row1, row2) -> {
          int result = row1[0].compareTo(row2[0]); // PKTABLE_CAT
          if (result == 0) {
            result = row1[2].compareTo(row2[2]); // PKTABLE_NAME
            if (result == 0) {
              result = row1[8].length() - row2[8].length(); // KEY_SEQ
              if (result == 0) {
                result = row1[8].compareTo(row2[8]);
              }
            }
          }
          return result;
        });
    return CompleteResult.createResultSet(
        columnNames, dataTypes, arr, connection.getContext(), ColumnFlags.PRIMARY_KEY);
  }

  private Map<String[], String> getExtImportedKeys(
      String tableName, org.mariadb.jdbc.Connection connection) throws SQLException {
    ResultSet rs = connection.createStatement().executeQuery("SHOW CREATE TABLE " + tableName);
    rs.next();
    String refTableDef = rs.getString(2);
    Map<String[], String> res = new HashMap<>();
    String[] parts = refTableDef.split("\n");
    for (int i = 1; i < parts.length - 1; i++) {
      String part = parts[i].trim();
      if (part.startsWith("`")) {
        // field
        continue;
      }
      if (part.startsWith("PRIMARY KEY") || part.startsWith("UNIQUE KEY")) {
        String name = "PRIMARY";
        if (part.indexOf("`") < part.indexOf("(")) {
          int offset = part.indexOf("`");
          name = part.substring(offset + 1, part.indexOf("`", offset + 1));
        }

        String subPart = part.substring(part.indexOf("(") + 1, part.lastIndexOf(")"));
        List<String> cols = new ArrayList<>();
        int pos = 0;
        while (pos < subPart.length()) {
          pos = subPart.indexOf("`", pos);
          int endpos = subPart.indexOf("`", pos + 1);
          cols.add(subPart.substring(pos + 1, endpos));
          pos = endpos + 1;
        }
        res.put(cols.toArray(new String[0]), name);
      }
    }
    return res;
  }

  /**
   * Retrieves a description of the primary key columns that are referenced by the given table's
   * foreign key columns (the primary keys imported by a table). They are ordered by PKTABLE_CAT,
   * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
   *
   * <p>Each primary key column description has the following columns:
   *
   * <OL>
   *   <LI><B>PKTABLE_CAT</B> String {@code =>} primary key table catalog being imported (may be
   *       <code>null</code>)
   *   <LI><B>PKTABLE_SCHEM</B> String {@code =>} primary key table schema being imported (may be
   *       <code>null</code>)
   *   <LI><B>PKTABLE_NAME</B> String {@code =>} primary key table name being imported
   *   <LI><B>PKCOLUMN_NAME</B> String {@code =>} primary key column name being imported
   *   <LI><B>FKTABLE_CAT</B> String {@code =>} foreign key table catalog (may be <code>null</code>)
   *   <LI><B>FKTABLE_SCHEM</B> String {@code =>} foreign key table schema (may be <code>null</code>
   *       )
   *   <LI><B>FKTABLE_NAME</B> String {@code =>} foreign key table name
   *   <LI><B>FKCOLUMN_NAME</B> String {@code =>} foreign key column name
   *   <LI><B>KEY_SEQ</B> short {@code =>} sequence number within a foreign key( a value of 1
   *       represents the first column of the foreign key, a value of 2 would represent the second
   *       column within the foreign key).
   *   <LI><B>UPDATE_RULE</B> short {@code =>} What happens to a foreign key when the primary key is
   *       updated:
   *       <UL>
   *         <LI>importedNoAction - do not allow update of primary key if it has been imported
   *         <LI>importedKeyCascade - change imported key to agree with primary key update
   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
   *             has been updated
   *         <LI>importedKeySetDefault - change imported key to default values if its primary key
   *             has been updated
   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
   *       </UL>
   *   <LI><B>DELETE_RULE</B> short {@code =>} What happens to the foreign key when primary is
   *       deleted.
   *       <UL>
   *         <LI>importedKeyNoAction - do not allow delete of primary key if it has been imported
   *         <LI>importedKeyCascade - delete rows that import a deleted key
   *         <LI>importedKeySetNull - change imported key to NULL if its primary key has been
   *             deleted
   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
   *         <LI>importedKeySetDefault - change imported key to default if its primary key has been
   *             deleted
   *       </UL>
   *   <LI><B>FK_NAME</B> String {@code =>} foreign key name (may be <code>null</code>)
   *   <LI><B>PK_NAME</B> String {@code =>} primary key name (may be <code>null</code>)
   *   <LI><B>DEFERRABILITY</B> short {@code =>} can the evaluation of foreign key constraints be
   *       deferred until commit
   *       <UL>
   *         <LI>importedKeyInitiallyDeferred - see SQL92 for definition
   *         <LI>importedKeyInitiallyImmediate - see SQL92 for definition
   *         <LI>importedKeyNotDeferrable - see SQL92 for definition
   *       </UL>
   * </OL>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schema a schema name; must match the schema name as it is stored in the database; ""
   *     retrieves those without a schema; <code>null</code> means that the schema name should not
   *     be used to narrow the search
   * @param table a table name; must match the table name as it is stored in the database
   * @return <code>ResultSet</code> - each row is a primary key column description
   * @throws SQLException if a database access error occurs
   * @see #getExportedKeys
   */
  public ResultSet getImportedKeys(String catalog, String schema, String table)
      throws SQLException {

    // We avoid using information schema queries by default, because this appears to be an expensive
    // query (CONJ-41).
    if (table == null) {
      throw new SQLException("'table' parameter in getImportedKeys cannot be null");
    }

    if (catalog == null || catalog.isEmpty()) {
      return getImportedKeysUsingInformationSchema(catalog, table);
    }

    try {
      return getImportedKeysUsingShowCreateTable(catalog, table);
    } catch (Exception e) {
      // Likely, parsing failed, try out I_S query.
      return getImportedKeysUsingInformationSchema(catalog, table);
    }
  }

  private String dataTypeClause(String fullTypeColumnName) {
    return " CASE data_type"
        + " WHEN 'bit' THEN "
        + Types.BIT
        + " WHEN 'tinyblob' THEN "
        + Types.VARBINARY
        + " WHEN 'mediumblob' THEN "
        + Types.LONGVARBINARY
        + " WHEN 'longblob' THEN "
        + Types.LONGVARBINARY
        + " WHEN 'blob' THEN "
        + Types.LONGVARBINARY
        + " WHEN 'tinytext' THEN "
        + Types.VARCHAR
        + " WHEN 'mediumtext' THEN "
        + Types.LONGVARCHAR
        + " WHEN 'longtext' THEN "
        + Types.LONGVARCHAR
        + " WHEN 'text' THEN "
        + Types.LONGVARCHAR
        + " WHEN 'date' THEN "
        + Types.DATE
        + " WHEN 'datetime' THEN "
        + Types.TIMESTAMP
        + " WHEN 'decimal' THEN "
        + Types.DECIMAL
        + " WHEN 'double' THEN "
        + Types.DOUBLE
        + " WHEN 'enum' THEN "
        + Types.VARCHAR
        + " WHEN 'float' THEN "
        + Types.REAL
        + " WHEN 'int' THEN IF( "
        + fullTypeColumnName
        + " like '%unsigned%', "
        + Types.INTEGER
        + ","
        + Types.INTEGER
        + ")"
        + " WHEN 'bigint' THEN "
        + Types.BIGINT
        + " WHEN 'mediumint' THEN "
        + Types.INTEGER
        + " WHEN 'null' THEN "
        + Types.NULL
        + " WHEN 'set' THEN "
        + Types.VARCHAR
        + " WHEN 'smallint' THEN IF( "
        + fullTypeColumnName
        + " like '%unsigned%', "
        + Types.SMALLINT
        + ","
        + Types.SMALLINT
        + ")"
        + " WHEN 'varchar' THEN "
        + Types.VARCHAR
        + " WHEN 'varbinary' THEN "
        + Types.VARBINARY
        + " WHEN 'char' THEN "
        + Types.CHAR
        + " WHEN 'binary' THEN "
        + Types.BINARY
        + " WHEN 'time' THEN "
        + Types.TIME
        + " WHEN 'timestamp' THEN "
        + Types.TIMESTAMP
        + " WHEN 'tinyint' THEN "
        + (conf.tinyInt1isBit()
            ? "IF("
                + fullTypeColumnName
                + " like 'tinyint(1)%',"
                + (conf.transformedBitIsBoolean() ? Types.BOOLEAN : Types.BIT)
                + ","
                + Types.TINYINT
                + ") "
            : Types.TINYINT)
        + " WHEN 'year' THEN "
        + (conf.yearIsDateType() ? Types.DATE : Types.SMALLINT)
        + " ELSE "
        + Types.OTHER
        + " END ";
  }

  private ResultSet executeQuery(String sql) throws SQLException {
    Statement stmt = connection.createStatement();
    Result rs = (Result) stmt.executeQuery(sql);
    rs.setStatement(null); // bypass Hibernate statement tracking (CONJ-49)
    rs.useAliasAsName();
    return rs;
  }

  private String escapeQuote(String value) {
    return value == null
        ? "null"
        : "'"
            + escapeString(
                value,
                (connection.getContext().getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) > 0)
            + "'";
  }

  /**
   * Generate part of the information schema query that restricts catalog names In the driver,
   * catalogs is the equivalent to MariaDB schemas.
   *
   * @param columnName - column name in the information schema table
   * @param catalog - catalog name. This driver does not (always) follow JDBC standard for following
   *     special values, due to ConnectorJ compatibility 1. empty string ("") - matches current
   *     catalog (i.e. database). JDBC standard says only tables without catalog should be returned
   *     - such tables do not exist in MariaDB. If there is no current catalog, then empty string
   *     matches any catalog. 2. null - if nullCatalogMeansCurrent=true (which is the default), then
   *     the handling is the same as for "" . i.e. return current catalog.JDBC-conforming way would
   *     be to match any catalog with null parameter. This can be switched with
   *     nullCatalogMeansCurrent=false in the connection URL.
   * @return part of SQL query ,that restricts search for the catalog.
   */
  private boolean catalogCond(
      boolean firstCondition, StringBuilder sb, String columnName, String catalog) {
    // null catalog => searching without any catalog restriction
    if (catalog == null) return firstCondition;

    // empty catalog => search restricting to current catalog
    if (catalog.isEmpty()) {
      sb.append(firstCondition ? " WHERE " : " AND ").append(columnName).append(" = database()");
      return false;
    }

    // search with specified catalog
    sb.append(firstCondition ? " WHERE " : " AND ")
        .append(columnName)
        .append("=")
        .append(escapeQuote(catalog));
    return false;
  }

  // Helper to generate  information schema queries with "like" or "equals" condition (typically  on
  // table name)
  private boolean patternCond(
      boolean firstCondition, StringBuilder sb, String columnName, String tableName) {
    if (tableName == null || "%".equals(tableName)) {
      return firstCondition;
    }
    sb.append(firstCondition ? " WHERE " : " AND ")
        .append(columnName)
        .append((tableName.indexOf('%') == -1 && tableName.indexOf('_') == -1) ? "=" : " LIKE ")
        .append("'")
        .append(
            escapeString(
                tableName,
                (connection.getContext().getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES)
                    != 0))
        .append("'");
    return false;
  }

  /**
   * Retrieves a description of the given table's primary key columns. They are ordered by
   * COLUMN_NAME.
   *
   * <p>Each primary key column description has the following columns:
   *
   * <OL>
   *   <li><B>TABLE_CAT</B> String {@code =>} table catalog
   *   <li><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
   *   <li><B>TABLE_NAME</B> String {@code =>} table name
   *   <li><B>COLUMN_NAME</B> String {@code =>} column name
   *   <li><B>KEY_SEQ</B> short {@code =>} sequence number within primary key( a value of 1
   *       represents the first column of the primary key, a value of 2 would represent the second
   *       column within the primary key).
   *   <li><B>PK_NAME</B> String {@code =>} primary key name
   * </OL>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schema a schema name; must match the schema name as it is stored in the database; ""
   *     retrieves those without a schema; <code>null</code> means that the schema name should not
   *     be used to narrow the search
   * @param table a table name; must match the table name as it is stored in the database
   * @return <code>ResultSet</code> - each row is a primary key column description
   * @throws SQLException if a database access error occurs
   */
  public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
    // MySQL 8 now use 'PRI' in place of 'pri'
    StringBuilder sb =
        new StringBuilder(
            "SELECT A.TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, A.TABLE_NAME, A.COLUMN_NAME,"
                + " B.SEQ_IN_INDEX KEY_SEQ, B.INDEX_NAME PK_NAME  FROM INFORMATION_SCHEMA.COLUMNS"
                + " A, INFORMATION_SCHEMA.STATISTICS B WHERE A.COLUMN_KEY in ('PRI','pri') AND"
                + " B.INDEX_NAME='PRIMARY'");

    catalogCond(false, sb, "A.TABLE_SCHEMA", catalog);
    catalogCond(false, sb, "B.TABLE_SCHEMA", catalog);
    patternCond(false, sb, "A.TABLE_NAME", table);
    patternCond(false, sb, "B.TABLE_NAME", table);
    sb.append(
        " AND A.TABLE_SCHEMA = B.TABLE_SCHEMA AND A.TABLE_NAME = B.TABLE_NAME AND A.COLUMN_NAME ="
            + " B.COLUMN_NAME ORDER BY A.COLUMN_NAME");

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of the tables available in the given catalog. Only table descriptions
   * matching the catalog, schema, table name and type criteria are returned. They are ordered by
   * <code>TABLE_TYPE</code>, <code>TABLE_CAT</code>, <code>TABLE_SCHEM</code> and <code>TABLE_NAME
   * </code>. Each table description has the following columns:
   *
   * <OL>
   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
   *   <LI><B>TABLE_TYPE</B> String {@code =>} table type. Typical types are "TABLE", "VIEW",
   *       "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
   *   <LI><B>REMARKS</B> String {@code =>} explanatory comment on the table
   *   <LI><B>TYPE_CAT</B> String {@code =>} the types catalog (may be <code>null</code>)
   *   <LI><B>TYPE_SCHEM</B> String {@code =>} the types schema (may be <code>null</code>)
   *   <LI><B>TYPE_NAME</B> String {@code =>} type name (may be <code>null</code>)
   *   <LI><B>SELF_REFERENCING_COL_NAME</B> String {@code =>} name of the designated "identifier"
   *       column of a typed table (may be <code>null</code>)
   *   <LI><B>REF_GENERATION</B> String {@code =>} specifies how values in SELF_REFERENCING_COL_NAME
   *       are created. Values are "SYSTEM", "USER", "DERIVED". (may be <code>null</code>)
   * </OL>
   *
   * <p><B>Note:</B> Some databases may not return information for all tables.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
   *     database
   * @param types a list of table types, which must be from the list of table types returned from
   *     {@link #getTableTypes},to include; <code>null</code> returns all types
   * @return <code>ResultSet</code> - each row is a table description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   */
  public ResultSet getTables(
      String catalog, String schemaPattern, String tableNamePattern, String[] types)
      throws SQLException {

    StringBuilder sb =
        new StringBuilder(
            "SELECT TABLE_SCHEMA TABLE_CAT, NULL  TABLE_SCHEM,  TABLE_NAME, IF(TABLE_TYPE='BASE"
                + " TABLE' or TABLE_TYPE='SYSTEM VERSIONED', 'TABLE', TABLE_TYPE) as TABLE_TYPE,"
                + " TABLE_COMMENT REMARKS, NULL TYPE_CAT, NULL TYPE_SCHEM, NULL TYPE_NAME, NULL"
                + " SELF_REFERENCING_COL_NAME,  NULL REF_GENERATION FROM"
                + " INFORMATION_SCHEMA.TABLES");
    boolean firstCondition = true;
    firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "TABLE_NAME", tableNamePattern);

    if (types != null && types.length > 0) {
      boolean mustAddType = false;

      StringBuilder sqlType =
          new StringBuilder(((firstCondition) ? " WHERE " : " AND ") + " TABLE_TYPE IN (");
      for (String s : types) {
        if (mustAddType) sqlType.append(",");
        mustAddType = true;
        if (s == null) {
          mustAddType = false;
          continue;
        }
        String type = "TABLE".equals(s) ? "'BASE TABLE','SYSTEM VERSIONED'" : escapeQuote(s);
        sqlType.append(type);
      }
      sqlType.append(")");
      if (mustAddType) sb.append(sqlType);
    }

    sb.append(" ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME");

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of table columns available in the specified catalog.
   *
   * <p>Only column descriptions matching the catalog, schema, table and column name criteria are
   * returned. They are ordered by <code>TABLE_CAT</code>,<code>TABLE_SCHEM</code>, <code>TABLE_NAME
   * </code>, and <code>ORDINAL_POSITION</code>.
   *
   * <p>Each column description has the following columns:
   *
   * <OL>
   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
   *   <LI><B>TYPE_NAME</B> String {@code =>} Data source dependent type name, for a UDT the type
   *       name is fully qualified
   *   <LI><B>COLUMN_SIZE</B> int {@code =>} column size.
   *   <LI><B>BUFFER_LENGTH</B> is not used.
   *   <LI><B>DECIMAL_DIGITS</B> int {@code =>} the number of fractional digits. Null is returned
   *       for data types where DECIMAL_DIGITS is not applicable.
   *   <LI><B>NUM_PREC_RADIX</B> int {@code =>} Radix (typically either 10 or 2)
   *   <LI><B>NULLABLE</B> int {@code =>} is NULL allowed.
   *       <UL>
   *         <LI>columnNoNulls - might not allow <code>NULL</code> values
   *         <LI>columnNullable - definitely allows <code>NULL</code> values
   *         <LI>columnNullableUnknown - nullability unknown
   *       </UL>
   *   <LI><B>REMARKS</B> String {@code =>} comment describing column (may be <code>null</code>)
   *   <LI><B>COLUMN_DEF</B> String {@code =>} default value for the column, which should be
   *       interpreted as a string when the value is enclosed in single quotes (may be <code>null
   *       </code>)
   *   <LI><B>SQL_DATA_TYPE</B> int {@code =>} unused
   *   <LI><B>SQL_DATETIME_SUB</B> int {@code =>} unused
   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} for char types the maximum number of bytes in the
   *       column
   *   <LI><B>ORDINAL_POSITION</B> int {@code =>} index of column in table (starting at 1)
   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
   *       a column.
   *       <UL>
   *         <LI>YES --- if the column can include NULLs
   *         <LI>NO --- if the column cannot include NULLs
   *         <LI>empty string --- if the nullability for the column is unknown
   *       </UL>
   *   <LI><B>SCOPE_CATALOG</B> String {@code =>} catalog of table that is the scope of a reference
   *       attribute (<code>null</code> if DATA_TYPE isn't REF)
   *   <LI><B>SCOPE_SCHEMA</B> String {@code =>} schema of table that is the scope of a reference
   *       attribute (<code>null</code> if the DATA_TYPE isn't REF)
   *   <LI><B>SCOPE_TABLE</B> String {@code =>} table name that this the scope of a reference
   *       attribute (<code>null</code> if the DATA_TYPE isn't REF)
   *   <LI><B>SOURCE_DATA_TYPE</B> short {@code =>} source type of a distinct type or user-generated
   *       Ref type, SQL type from java.sql.Types (<code>null</code> if DATA_TYPE isn't DISTINCT or
   *       user-generated REF)
   *   <LI><B>IS_AUTOINCREMENT</B> String {@code =>} Indicates whether this column is auto
   *       incremented
   *       <UL>
   *         <LI>YES --- if the column is auto incremented
   *         <LI>NO --- if the column is not auto incremented
   *         <LI>empty string --- if it cannot be determined whether the column is auto incremented
   *       </UL>
   *   <LI><B>IS_GENERATEDCOLUMN</B> String {@code =>} Indicates whether this is a generated column
   *       <UL>
   *         <LI>YES --- if this a generated column
   *         <LI>NO --- if this not a generated column
   *         <LI>empty string --- if it cannot be determined whether this is a generated column
   *       </UL>
   * </OL>
   *
   * <p>The COLUMN_SIZE column specifies the column size for the given column. For numeric data,
   * this is the maximum precision. For character data, this is the length in characters. For
   * datetime datatypes, this is the length in characters of the String representation (assuming the
   * maximum allowed precision of the fractional seconds component). For binary data, this is the
   * length in bytes. For the ROWID datatype, this is the length in bytes. Null is returned for data
   * types where the column size is not applicable.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
   *     database
   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
   *     the database
   * @return <code>ResultSet</code> - each row is a column description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   */
  public ResultSet getColumns(
      String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
      throws SQLException {

    ServerVersion version = connection.getContext().getVersion();
    boolean supportsFractionalSeconds =
        version.isMariaDBServer()
            /* "In MariaDB 5.3 and later, the TIME, DATETIME, and TIMESTAMP types, along with the temporal
            functions, CAST and dynamic columns, now support microseconds."
            https://web.archive.org/web/20130928042640/https://mariadb.com/kb/en/microseconds-in-mariadb/
            */
            ? version.versionGreaterOrEqual(5, 3, 0)
            // See https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-4.html
            : version.versionGreaterOrEqual(5, 6, 4);
    StringBuilder sb = new StringBuilder();
    sb.append(
        "SELECT TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, TABLE_NAME, COLUMN_NAME,"
            + dataTypeClause("COLUMN_TYPE")
            + " DATA_TYPE,"
            + DataTypeClause(conf)
            + " TYPE_NAME, "
            + " CASE DATA_TYPE"
            + "  WHEN 'date' THEN 10");
    if (supportsFractionalSeconds) {
      sb.append(
          "  WHEN 'time' THEN "
              + "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
              + "  WHEN 'datetime' THEN "
              + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
              + "  WHEN 'timestamp' THEN "
              + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))");
    } else {
      // Older versions do not include the DATETIME_PRECISION column in INFORMATION_SCHEMA.COLUMNS.
      sb.append(" WHEN 'time' THEN 10 WHEN 'datetime' THEN 19 WHEN 'timestamp' THEN 19");
    }
    sb.append(
        (conf.yearIsDateType() ? "" : " WHEN 'year' THEN 5")
            + "  ELSE "
            + "  IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
            + Integer.MAX_VALUE
            + "), NUMERIC_PRECISION) "
            + " END"
            + " COLUMN_SIZE, 65535 BUFFER_LENGTH, "
            + " CONVERT (CASE DATA_TYPE"
            + " WHEN 'year' THEN "
            + (conf.yearIsDateType() ? "NUMERIC_SCALE" : "0")
            + " WHEN 'tinyint' THEN "
            + (conf.tinyInt1isBit() ? "0" : "NUMERIC_SCALE")
            + " ELSE NUMERIC_SCALE END, UNSIGNED INTEGER) DECIMAL_DIGITS,"
            + " 10 NUM_PREC_RADIX, IF(IS_NULLABLE = 'yes',1,0) NULLABLE,COLUMN_COMMENT REMARKS,"
            + " COLUMN_DEFAULT COLUMN_DEF, 0 SQL_DATA_TYPE, 0 SQL_DATETIME_SUB,  "
            + " LEAST(CHARACTER_OCTET_LENGTH,"
            + Integer.MAX_VALUE
            + ") CHAR_OCTET_LENGTH, ORDINAL_POSITION, IS_NULLABLE, NULL SCOPE_CATALOG, NULL"
            + " SCOPE_SCHEMA, NULL SCOPE_TABLE, NULL SOURCE_DATA_TYPE, IF(EXTRA ="
            + " 'auto_increment','YES','NO') IS_AUTOINCREMENT,  IF(EXTRA in ('VIRTUAL',"
            + " 'PERSISTENT', 'VIRTUAL GENERATED', 'STORED GENERATED') ,'YES','NO')"
            + " IS_GENERATEDCOLUMN  FROM INFORMATION_SCHEMA.COLUMNS");
    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "TABLE_NAME", tableNamePattern);
    firstCondition = patternCond(firstCondition, sb, "COLUMN_NAME", columnNamePattern);
    sb.append(" ORDER BY TABLE_CAT, TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION");
    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of the foreign key columns that reference the given table's primary key
   * columns (the foreign keys exported by a table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
   * FKTABLE_NAME, and KEY_SEQ.
   *
   * <p>Each foreign key column description has the following columns:
   *
   * <OL>
   *   <LI><B>PKTABLE_CAT</B> String {@code =>} primary key table catalog (may be <code>null</code>)
   *   <LI><B>PKTABLE_SCHEM</B> String {@code =>} primary key table schema (may be <code>null</code>
   *       )
   *   <LI><B>PKTABLE_NAME</B> String {@code =>} primary key table name
   *   <LI><B>PKCOLUMN_NAME</B> String {@code =>} primary key column name
   *   <LI><B>FKTABLE_CAT</B> String {@code =>} foreign key table catalog (may be <code>null</code>)
   *       being exported (may be <code>null</code>)
   *   <LI><B>FKTABLE_SCHEM</B> String {@code =>} foreign key table schema (may be <code>null</code>
   *       ) being exported (may be <code>null</code>)
   *   <LI><B>FKTABLE_NAME</B> String {@code =>} foreign key table name being exported
   *   <LI><B>FKCOLUMN_NAME</B> String {@code =>} foreign key column name being exported
   *   <LI><B>KEY_SEQ</B> short {@code =>} sequence number within foreign key( a value of 1
   *       represents the first column of the foreign key, a value of 2 would represent the second
   *       column within the foreign key).
   *   <LI><B>UPDATE_RULE</B> short {@code =>} What happens to foreign key when primary is updated:
   *       <UL>
   *         <LI>importedNoAction - do not allow update of primary key if it has been imported
   *         <LI>importedKeyCascade - change imported key to agree with primary key update
   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
   *             has been updated
   *         <LI>importedKeySetDefault - change imported key to default values if its primary key
   *             has been updated
   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
   *       </UL>
   *   <LI><B>DELETE_RULE</B> short {@code =>} What happens to the foreign key when primary is
   *       deleted.
   *       <UL>
   *         <LI>importedKeyNoAction - do not allow delete of primary key if it has been imported
   *         <LI>importedKeyCascade - delete rows that import a deleted key
   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
   *             has been deleted
   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
   *         <LI>importedKeySetDefault - change imported key to default if its primary key has been
   *             deleted
   *       </UL>
   *   <LI><B>FK_NAME</B> String {@code =>} foreign key name (may be <code>null</code>)
   *   <LI><B>PK_NAME</B> String {@code =>} primary key name (may be <code>null</code>)
   *   <LI><B>DEFERRABILITY</B> short {@code =>} can the evaluation of foreign key constraints be
   *       deferred until commit
   *       <UL>
   *         <LI>importedKeyInitiallyDeferred - see SQL92 for definition
   *         <LI>importedKeyInitiallyImmediate - see SQL92 for definition
   *         <LI>importedKeyNotDeferrable - see SQL92 for definition
   *       </UL>
   * </OL>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in this database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schema a schema name; must match the schema name as it is stored in the database; ""
   *     retrieves those without a schema; <code>null</code> means that the schema name should not
   *     be used to narrow the search
   * @param table a table name; must match the table name as it is stored in this database
   * @return a <code>ResultSet</code> object in which each row is a foreign key column description
   * @throws SQLException if a database access error occurs
   * @see #getImportedKeys
   */
  public ResultSet getExportedKeys(String catalog, String schema, String table)
      throws SQLException {
    StringBuilder sb =
        new StringBuilder(
            "SELECT KCU.REFERENCED_TABLE_SCHEMA PKTABLE_CAT, NULL PKTABLE_SCHEM, "
                + " KCU.REFERENCED_TABLE_NAME PKTABLE_NAME, KCU.REFERENCED_COLUMN_NAME"
                + " PKCOLUMN_NAME, KCU.TABLE_SCHEMA FKTABLE_CAT, NULL FKTABLE_SCHEM, "
                + " KCU.TABLE_NAME FKTABLE_NAME, KCU.COLUMN_NAME FKCOLUMN_NAME,"
                + " KCU.POSITION_IN_UNIQUE_CONSTRAINT KEY_SEQ, CASE update_rule    WHEN 'RESTRICT'"
                + " THEN 1   WHEN 'NO ACTION' THEN 3   WHEN 'CASCADE' THEN 0   WHEN 'SET NULL' THEN"
                + " 2   WHEN 'SET DEFAULT' THEN 4 END UPDATE_RULE, CASE DELETE_RULE  WHEN"
                + " 'RESTRICT' THEN 1  WHEN 'NO ACTION' THEN 3  WHEN 'CASCADE' THEN 0  WHEN 'SET"
                + " NULL' THEN 2  WHEN 'SET DEFAULT' THEN 4 END DELETE_RULE, RC.CONSTRAINT_NAME"
                + " FK_NAME, RC.UNIQUE_CONSTRAINT_NAME PK_NAME,"
                + importedKeyNotDeferrable
                + " DEFERRABILITY"
                + " FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU"
                + " INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC"
                + " ON KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA"
                + " AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME");
    boolean firstCondition = true;
    firstCondition = catalogCond(firstCondition, sb, "KCU.REFERENCED_TABLE_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "KCU.REFERENCED_TABLE_NAME", table);
    sb.append(" ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, KEY_SEQ");

    return executeQuery(sb.toString());
  }

  /**
   * GetImportedKeysUsingInformationSchema.
   *
   * @param catalog catalog
   * @param table table
   * @return resultset
   * @throws SQLException exception
   */
  public ResultSet getImportedKeysUsingInformationSchema(final String catalog, String table)
      throws SQLException {
    if (table == null) {
      throw new SQLException("'table' parameter in getImportedKeys cannot be null");
    }
    StringBuilder sb =
        new StringBuilder(
            "SELECT KCU.REFERENCED_TABLE_SCHEMA PKTABLE_CAT, NULL PKTABLE_SCHEM, "
                + " KCU.REFERENCED_TABLE_NAME PKTABLE_NAME, KCU.REFERENCED_COLUMN_NAME"
                + " PKCOLUMN_NAME, KCU.TABLE_SCHEMA FKTABLE_CAT, NULL FKTABLE_SCHEM, "
                + " KCU.TABLE_NAME FKTABLE_NAME, KCU.COLUMN_NAME FKCOLUMN_NAME,"
                + " KCU.POSITION_IN_UNIQUE_CONSTRAINT KEY_SEQ, CASE update_rule    WHEN 'RESTRICT'"
                + " THEN 1   WHEN 'NO ACTION' THEN 3   WHEN 'CASCADE' THEN 0   WHEN 'SET NULL' THEN"
                + " 2   WHEN 'SET DEFAULT' THEN 4 END UPDATE_RULE, CASE DELETE_RULE  WHEN"
                + " 'RESTRICT' THEN 1  WHEN 'NO ACTION' THEN 3  WHEN 'CASCADE' THEN 0  WHEN 'SET"
                + " NULL' THEN 2  WHEN 'SET DEFAULT' THEN 4 END DELETE_RULE, RC.CONSTRAINT_NAME"
                + " FK_NAME, RC.UNIQUE_CONSTRAINT_NAME PK_NAME,"
                + importedKeyNotDeferrable
                + " DEFERRABILITY"
                + " FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU"
                + " INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC"
                + " ON KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA"
                + " AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME ");

    boolean firstCondition = catalogCond(true, sb, "KCU.TABLE_SCHEMA", catalog);
    sb.append(firstCondition ? " WHERE " : " AND ")
        .append("KCU.TABLE_NAME = ")
        .append(escapeQuote(table));

    sb.append(" ORDER BY PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, KEY_SEQ");

    return executeQuery(sb.toString());
  }

  /**
   * GetImportedKeysUsingShowCreateTable.
   *
   * @param catalog catalog
   * @param table table
   * @return resultset
   * @throws Exception exception
   */
  public ResultSet getImportedKeysUsingShowCreateTable(final String catalog, String table)
      throws Exception {
    ResultSet rs =
        connection
            .createStatement()
            .executeQuery(
                "SHOW CREATE TABLE " + quoteIdentifier(catalog) + "." + quoteIdentifier(table));
    rs.next();
    String tableDef = rs.getString(2);
    return getImportedKeys(tableDef, table, catalog, connection);
  }

  /**
   * Retrieves a description of a table's optimal set of columns that uniquely identifies a row.
   * They are ordered by SCOPE.
   *
   * <p>Each column description has the following columns:
   *
   * <OL>
   *   <LI><B>SCOPE</B> short {@code =>} actual scope of result
   *       <UL>
   *         <LI>bestRowTemporary - very temporary, while using row
   *         <LI>bestRowTransaction - valid for remainder of current transaction
   *         <LI>bestRowSession - valid for remainder of current session
   *       </UL>
   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL data type from java.sql.Types
   *   <LI><B>TYPE_NAME</B> String {@code =>} Data source dependent type name, for a UDT the type
   *       name is fully qualified
   *   <LI><B>COLUMN_SIZE</B> int {@code =>} precision
   *   <LI><B>BUFFER_LENGTH</B> int {@code =>} not used
   *   <LI><B>DECIMAL_DIGITS</B> short {@code =>} scale - Null is returned for data types where
   *       DECIMAL_DIGITS is not applicable.
   *   <LI><B>PSEUDO_COLUMN</B> short {@code =>} is this a pseudo column like an Oracle ROWID
   *       <UL>
   *         <LI>bestRowUnknown - may or may not be pseudo column
   *         <LI>bestRowNotPseudo - is NOT a pseudo column
   *         <LI>bestRowPseudo - is a pseudo column
   *       </UL>
   * </OL>
   *
   * <p>The COLUMN_SIZE column represents the specified column size for the given column. For
   * numeric data, this is the maximum precision. For character data, this is the length in
   * characters. For datetime datatypes, this is the length in characters of the String
   * representation (assuming the maximum allowed precision of the fractional seconds component).
   * For binary data, this is the length in bytes. For the ROWID datatype, this is the length in
   * bytes. Null is returned for data types where the column size is not applicable.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schema a schema name; must match the schema name as it is stored in the database; ""
   *     retrieves those without a schema; <code>null</code> means that the schema name should not
   *     be used to narrow the search
   * @param table a table name; must match the table name as it is stored in the database
   * @param scope the scope of interest; use same values as SCOPE
   * @param nullable include columns that are nullable.
   * @return <code>ResultSet</code> - each row is a column description
   * @throws SQLException if a database access error occurs
   */
  public ResultSet getBestRowIdentifier(
      String catalog, String schema, String table, int scope, final boolean nullable)
      throws SQLException {

    if (table == null) {
      throw new SQLException("'table' parameter cannot be null in getBestRowIdentifier()");
    }
    boolean hasIsGeneratedCol =
        (connection.getContext().getVersion().isMariaDBServer()
            && connection.getContext().getVersion().versionGreaterOrEqual(10, 2, 0));

    StringBuilder sbInner =
        new StringBuilder("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_KEY = 'PRI'");
    catalogCond(false, sbInner, "TABLE_SCHEMA", catalog);
    sbInner.append(" AND TABLE_NAME = ").append(escapeQuote(table));

    StringBuilder sb =
        new StringBuilder(
            "SELECT "
                + bestRowSession
                + " SCOPE, COLUMN_NAME,"
                + dataTypeClause("COLUMN_TYPE")
                + " DATA_TYPE, DATA_TYPE TYPE_NAME, IF(NUMERIC_PRECISION IS NULL,"
                + " CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION) COLUMN_SIZE, 0 BUFFER_LENGTH,"
                + " NUMERIC_SCALE DECIMAL_DIGITS,"
                + (hasIsGeneratedCol
                    ? ("IF(IS_GENERATED='NEVER'," + bestRowNotPseudo + "," + bestRowPseudo + ")")
                    : bestRowNotPseudo)
                + " PSEUDO_COLUMN"
                + " FROM INFORMATION_SCHEMA.COLUMNS"
                + " WHERE (COLUMN_KEY  = 'PRI'"
                + " OR (COLUMN_KEY = 'UNI' AND NOT EXISTS ("
                + sbInner
                + " )))");
    catalogCond(false, sb, "TABLE_SCHEMA", catalog);
    sb.append(" AND TABLE_NAME = ").append(escapeQuote(table));
    if (!nullable) sb.append(" AND IS_NULLABLE = 'NO'");

    return executeQuery(sb.toString());
  }

  public boolean generatedKeyAlwaysReturned() {
    return true;
  }

  /**
   * Retrieves a description of the pseudo or hidden columns available in a given table within the
   * specified catalog and schema. Pseudo or hidden columns may not always be stored within a table
   * and are not visible in a ResultSet unless they are specified in the query's outermost SELECT
   * list. Pseudo or hidden columns may not necessarily be able to be modified. If there are no
   * pseudo or hidden columns, an empty ResultSet is returned.
   *
   * <p>Only column descriptions matching the catalog, schema, table and column name criteria are
   * returned. They are ordered by <code>TABLE_CAT</code>,<code>TABLE_SCHEM</code>, <code>TABLE_NAME
   * </code> and <code>COLUMN_NAME</code>.
   *
   * <p>Each column description has the following columns:
   *
   * <OL>
   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
   *   <LI><B>COLUMN_SIZE</B> int {@code =>} column size.
   *   <LI><B>DECIMAL_DIGITS</B> int {@code =>} the number of fractional digits. Null is returned
   *       for data types where DECIMAL_DIGITS is not applicable.
   *   <LI><B>NUM_PREC_RADIX</B> int {@code =>} Radix (typically either 10 or 2)
   *   <LI><B>COLUMN_USAGE</B> String {@code =>} The allowed usage for the column. The value
   *       returned will correspond to the enum name returned by PseudoColumnUsage.name()
   *   <LI><B>REMARKS</B> String {@code =>} comment describing column (may be <code>null</code>)
   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} for char types the maximum number of bytes in the
   *       column
   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
   *       a column.
   *       <UL>
   *         <LI>YES --- if the column can include NULLs
   *         <LI>NO --- if the column cannot include NULLs
   *         <LI>empty string --- if the nullability for the column is unknown
   *       </UL>
   * </OL>
   *
   * <p>The COLUMN_SIZE column specifies the column size for the given column. For numeric data,
   * this is the maximum precision. For character data, this is the length in characters. For
   * datetime datatypes, this is the length in characters of the String representation (assuming the
   * maximum allowed precision of the fractional seconds component). For binary data, this is the
   * length in bytes. For the ROWID datatype, this is the length in bytes. Null is returned for data
   * types where the column size is not applicable.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
   *     database
   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
   *     the database
   * @return <code>ResultSet</code> - each row is a column description
   * @throws SQLException if a database access error occurs
   * @see PseudoColumnUsage
   * @since 1.7
   */
  public ResultSet getPseudoColumns(
      String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
      throws SQLException {
    return connection
        .createStatement()
        .executeQuery(
            "SELECT ' ' TABLE_CAT, ' ' TABLE_SCHEM, ' ' TABLE_NAME, ' ' COLUMN_NAME, 0 DATA_TYPE, 0"
                + " COLUMN_SIZE, 0 DECIMAL_DIGITS, 10 NUM_PREC_RADIX, ' ' COLUMN_USAGE,  ' '"
                + " REMARKS, 0 CHAR_OCTET_LENGTH, 'YES' IS_NULLABLE FROM DUAL WHERE 1=0");
  }

  public boolean allProceduresAreCallable() {
    return true;
  }

  public boolean allTablesAreSelectable() {
    return true;
  }

  @Override
  public String getURL() {
    return conf.initialUrl();
  }

  public String getUserName() {
    return conf.user();
  }

  public boolean isReadOnly() throws SQLException {
    java.sql.Statement st = connection.createStatement();
    ResultSet rs = st.executeQuery("SELECT @@READ_ONLY");
    rs.next();
    return rs.getInt(1) == 1;
  }

  public boolean nullsAreSortedHigh() {
    return false;
  }

  public boolean nullsAreSortedLow() {
    return true;
  }

  public boolean nullsAreSortedAtStart() {
    return false;
  }

  public boolean nullsAreSortedAtEnd() {
    return true;
  }

  /**
   * Return Server type. MySQL or MariaDB. MySQL can be forced for compatibility with option
   * "useMysqlMetadata"
   *
   * @return server type
   */
  public String getDatabaseProductName() {
    if (!conf.useMysqlMetadata() && connection.getContext().getVersion().isMariaDBServer()) {
      return "MariaDB";
    }
    return "MySQL";
  }

  public String getDatabaseProductVersion() {
    return connection.getContext().getVersion().getVersion();
  }

  public String getDriverName() {
    return DRIVER_NAME;
  }

  public String getDriverVersion() {
    return VersionFactory.getInstance().getVersion();
  }

  public int getDriverMajorVersion() {
    return VersionFactory.getInstance().getMajorVersion();
  }

  public int getDriverMinorVersion() {
    return VersionFactory.getInstance().getMinorVersion();
  }

  public boolean usesLocalFiles() {
    return false;
  }

  public boolean usesLocalFilePerTable() {
    return false;
  }

  public boolean supportsMixedCaseIdentifiers() throws SQLException {
    return (connection.getLowercaseTableNames() == 0);
  }

  public boolean storesUpperCaseIdentifiers() {
    return false;
  }

  public boolean storesLowerCaseIdentifiers() throws SQLException {
    return (connection.getLowercaseTableNames() == 1);
  }

  public boolean storesMixedCaseIdentifiers() throws SQLException {
    return (connection.getLowercaseTableNames() == 2);
  }

  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
    return supportsMixedCaseIdentifiers();
  }

  public boolean storesUpperCaseQuotedIdentifiers() {
    return storesUpperCaseIdentifiers();
  }

  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
    return storesLowerCaseIdentifiers();
  }

  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
    return storesMixedCaseIdentifiers();
  }

  public String getIdentifierQuoteString() {
    return "`";
  }

  /**
   * Retrieves a comma-separated list of all of this database's SQL keywords that are NOT also
   * SQL:2003 keywords.
   *
   * @return the list of this database's keywords that are not also SQL:2003 keywords
   */
  @Override
  public String getSQLKeywords() {
    return "ACCESSIBLE,ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,CALL,CHANGE,CONDITION,DATABASE,DATABASES,"
               + "DAY_HOUR,DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,DETERMINISTIC,DISTINCTROW,DIV,DUAL,EACH,"
               + "ELSEIF,ENCLOSED,ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,GENERAL,HIGH_PRIORITY,"
               + "HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,IF,IGNORE,IGNORE_SERVER_IDS,INDEX,INFILE,INOUT,INT1,INT2,"
               + "INT3,INT4,INT8,ITERATE,KEY,KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,LOCALTIMESTAMP,LOCK,"
               + "LONG,LONGBLOB,LONGTEXT,LOOP,LOW_PRIORITY,MASTER_HEARTBEAT_PERIOD,MASTER_SSL_VERIFY_SERVER_CERT,"
               + "MAXVALUE,MEDIUMBLOB,MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,MINUTE_SECOND,MOD,MODIFIES,"
               + "NO_WRITE_TO_BINLOG,OPTIMIZE,OPTIONALLY,OUT,OUTFILE,PURGE,RANGE,READ_WRITE,READS,REGEXP,RELEASE,"
               + "RENAME,REPEAT,REPLACE,REQUIRE,RESIGNAL,RESTRICT,RETURN,RLIKE,SCHEMAS,SECOND_MICROSECOND,SENSITIVE,"
               + "SEPARATOR,SHOW,SIGNAL,SLOW,SPATIAL,SPECIFIC,SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQL_SMALL_RESULT,"
               + "SQLEXCEPTION,SSL,STARTING,STRAIGHT_JOIN,TERMINATED,TINYBLOB,TINYINT,TINYTEXT,TRIGGER,UNDO,UNLOCK,"
               + "UNSIGNED,USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,VARCHARACTER,WHILE,XOR,YEAR_MONTH,ZEROFILL";
  }

  /**
   * List of numeric functions.
   *
   * @return List of numeric functions.
   */
  @Override
  public String getNumericFunctions() {
    return "DIV,ABS,ACOS,ASIN,ATAN,ATAN2,CEIL,CEILING,CONV,COS,COT,CRC32,DEGREES,EXP,FLOOR,GREATEST,LEAST,LN,LOG,"
               + "LOG10,LOG2,MOD,OCT,PI,POW,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQRT,TAN,TRUNCATE";
  }

  /**
   * List of string functions.
   *
   * @return List of string functions.
   */
  @Override
  public String getStringFunctions() {
    return "ASCII,BIN,BIT_LENGTH,CAST,CHARACTER_LENGTH,CHAR_LENGTH,CONCAT,CONCAT_WS,CONVERT,ELT,EXPORT_SET,"
               + "EXTRACTVALUE,FIELD,FIND_IN_SET,FORMAT,FROM_BASE64,HEX,INSTR,LCASE,LEFT,LENGTH,LIKE,LOAD_FILE,LOCATE,LOWER,LPAD,LTRIM,MAKE_SET,MATCH"
               + " AGAINST,MID,NOT LIKE,NOT"
               + " REGEXP,OCTET_LENGTH,ORD,POSITION,QUOTE,REPEAT,REPLACE,REVERSE,RIGHT,RPAD,RTRIM,SOUNDEX,SOUNDS"
               + " LIKE,SPACE,STRCMP,SUBSTR,SUBSTRING,"
               + "SUBSTRING_INDEX,TO_BASE64,TRIM,UCASE,UNHEX,UPDATEXML,UPPER,WEIGHT_STRING";
  }

  /**
   * List of system functions.
   *
   * @return List of system functions.
   */
  @Override
  public String getSystemFunctions() {
    return "DATABASE,USER,SYSTEM_USER,SESSION_USER,LAST_INSERT_ID,VERSION";
  }

  /**
   * List of time and date functions.
   *
   * @return List of time and date functions.
   */
  @Override
  public String getTimeDateFunctions() {
    return "ADDDATE,ADDTIME,CONVERT_TZ,CURDATE,CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURTIME,DATEDIFF,"
               + "DATE_ADD,DATE_FORMAT,DATE_SUB,DAY,DAYNAME,DAYOFMONTH,DAYOFWEEK,DAYOFYEAR,EXTRACT,FROM_DAYS,"
               + "FROM_UNIXTIME,GET_FORMAT,HOUR,LAST_DAY,LOCALTIME,LOCALTIMESTAMP,MAKEDATE,MAKETIME,MICROSECOND,"
               + "MINUTE,MONTH,MONTHNAME,NOW,PERIOD_ADD,PERIOD_DIFF,QUARTER,SECOND,SEC_TO_TIME,STR_TO_DATE,SUBDATE,"
               + "SUBTIME,SYSDATE,TIMEDIFF,TIMESTAMPADD,TIMESTAMPDIFF,TIME_FORMAT,TIME_TO_SEC,TO_DAYS,TO_SECONDS,"
               + "UNIX_TIMESTAMP,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,WEEK,WEEKDAY,WEEKOFYEAR,YEAR,YEARWEEK";
  }

  public String getSearchStringEscape() {
    return "\\";
  }

  public String getExtraNameCharacters() {
    return "#@";
  }

  public boolean supportsAlterTableWithAddColumn() {
    return true;
  }

  public boolean supportsAlterTableWithDropColumn() {
    return true;
  }

  public boolean supportsColumnAliasing() {
    return true;
  }

  public boolean nullPlusNonNullIsNull() {
    return true;
  }

  public boolean supportsConvert() {
    return true;
  }

  /**
   * Retrieves whether this database supports the JDBC scalar function CONVERT for conversions
   * between the JDBC types fromType and toType. The JDBC types are the generic SQL data types
   * defined in java.sql.Types.
   *
   * @param fromType the type to convert from; one of the type codes from the class java.sql.Types
   * @param toType the type to convert to; one of the type codes from the class java.sql.Types
   * @return true if so; false otherwise
   */
  public boolean supportsConvert(int fromType, int toType) {
    switch (fromType) {
      case Types.TINYINT:
      case Types.SMALLINT:
      case Types.INTEGER:
      case Types.BIGINT:
      case Types.REAL:
      case Types.FLOAT:
      case Types.DECIMAL:
      case Types.NUMERIC:
      case Types.DOUBLE:
      case Types.BIT:
      case Types.BOOLEAN:
        switch (toType) {
          case Types.TINYINT:
          case Types.SMALLINT:
          case Types.INTEGER:
          case Types.BIGINT:
          case Types.REAL:
          case Types.FLOAT:
          case Types.DECIMAL:
          case Types.NUMERIC:
          case Types.DOUBLE:
          case Types.BIT:
          case Types.BOOLEAN:
          case Types.CHAR:
          case Types.VARCHAR:
          case Types.LONGVARCHAR:
          case Types.BINARY:
          case Types.VARBINARY:
          case Types.LONGVARBINARY:
            return true;
          default:
            return false;
        }

      case Types.BLOB:
        switch (toType) {
          case Types.BINARY:
          case Types.VARBINARY:
          case Types.LONGVARBINARY:
          case Types.CHAR:
          case Types.VARCHAR:
          case Types.LONGVARCHAR:
          case Types.TINYINT:
          case Types.SMALLINT:
          case Types.INTEGER:
          case Types.BIGINT:
          case Types.REAL:
          case Types.FLOAT:
          case Types.DECIMAL:
          case Types.NUMERIC:
          case Types.DOUBLE:
          case Types.BIT:
          case Types.BOOLEAN:
            return true;
          default:
            return false;
        }

      case Types.CHAR:
      case Types.CLOB:
      case Types.VARCHAR:
      case Types.LONGVARCHAR:
      case Types.BINARY:
      case Types.VARBINARY:
      case Types.LONGVARBINARY:
        switch (toType) {
          case Types.BIT:
          case Types.TINYINT:
          case Types.SMALLINT:
          case Types.INTEGER:
          case Types.BIGINT:
          case Types.FLOAT:
          case Types.REAL:
          case Types.DOUBLE:
          case Types.NUMERIC:
          case Types.DECIMAL:
          case Types.CHAR:
          case Types.VARCHAR:
          case Types.LONGVARCHAR:
          case Types.BINARY:
          case Types.VARBINARY:
          case Types.LONGVARBINARY:
          case Types.DATE:
          case Types.TIME:
          case Types.TIMESTAMP:
          case Types.BLOB:
          case Types.CLOB:
          case Types.BOOLEAN:
          case Types.NCHAR:
          case Types.LONGNVARCHAR:
          case Types.NCLOB:
            return true;
          default:
            return false;
        }

      case Types.DATE:
        switch (toType) {
          case Types.DATE:
          case Types.CHAR:
          case Types.VARCHAR:
          case Types.LONGVARCHAR:
          case Types.BINARY:
          case Types.VARBINARY:
          case Types.LONGVARBINARY:
            return true;

          default:
            return false;
        }

      case Types.TIME:
        switch (toType) {
          case Types.TIME:
          case Types.CHAR:
          case Types.VARCHAR:
          case Types.LONGVARCHAR:
          case Types.BINARY:
          case Types.VARBINARY:
          case Types.LONGVARBINARY:
            return true;
          default:
            return false;
        }

      case Types.TIMESTAMP:
        switch (toType) {
          case Types.TIMESTAMP:
          case Types.CHAR:
          case Types.VARCHAR:
          case Types.LONGVARCHAR:
          case Types.BINARY:
          case Types.VARBINARY:
          case Types.LONGVARBINARY:
          case Types.TIME:
          case Types.DATE:
            return true;
          default:
            return false;
        }
      default:
        return false;
    }
  }

  public boolean supportsTableCorrelationNames() {
    return true;
  }

  public boolean supportsDifferentTableCorrelationNames() {
    return true;
  }

  public boolean supportsExpressionsInOrderBy() {
    return true;
  }

  public boolean supportsOrderByUnrelated() {
    return true;
  }

  public boolean supportsGroupBy() {
    return true;
  }

  public boolean supportsGroupByUnrelated() {
    return true;
  }

  public boolean supportsGroupByBeyondSelect() {
    return true;
  }

  public boolean supportsLikeEscapeClause() {
    return true;
  }

  public boolean supportsMultipleResultSets() {
    return true;
  }

  public boolean supportsMultipleTransactions() {
    return true;
  }

  public boolean supportsNonNullableColumns() {
    return true;
  }

  @Override
  public boolean supportsMinimumSQLGrammar() {
    return true;
  }

  @Override
  public boolean supportsCoreSQLGrammar() {
    return true;
  }

  @Override
  public boolean supportsExtendedSQLGrammar() {
    return true;
  }

  @Override
  public boolean supportsANSI92EntryLevelSQL() {
    return true;
  }

  @Override
  public boolean supportsANSI92IntermediateSQL() {
    return true;
  }

  @Override
  public boolean supportsANSI92FullSQL() {
    return true;
  }

  public boolean supportsIntegrityEnhancementFacility() {
    return true;
  }

  public boolean supportsOuterJoins() {
    return true;
  }

  public boolean supportsFullOuterJoins() {
    return true;
  }

  public boolean supportsLimitedOuterJoins() {
    return true;
  }

  public String getSchemaTerm() {
    return "schema";
  }

  public String getProcedureTerm() {
    return "procedure";
  }

  public String getCatalogTerm() {
    return "database";
  }

  public boolean isCatalogAtStart() {
    return true;
  }

  public String getCatalogSeparator() {
    return ".";
  }

  public boolean supportsSchemasInDataManipulation() {
    return false;
  }

  public boolean supportsSchemasInProcedureCalls() {
    return false;
  }

  public boolean supportsSchemasInTableDefinitions() {
    return false;
  }

  public boolean supportsSchemasInIndexDefinitions() {
    return false;
  }

  public boolean supportsSchemasInPrivilegeDefinitions() {
    return false;
  }

  public boolean supportsCatalogsInDataManipulation() {
    return true;
  }

  public boolean supportsCatalogsInProcedureCalls() {
    return true;
  }

  public boolean supportsCatalogsInTableDefinitions() {
    return true;
  }

  public boolean supportsCatalogsInIndexDefinitions() {
    return true;
  }

  public boolean supportsCatalogsInPrivilegeDefinitions() {
    return true;
  }

  public boolean supportsPositionedDelete() {
    return false;
  }

  public boolean supportsPositionedUpdate() {
    return false;
  }

  public boolean supportsSelectForUpdate() {
    return true;
  }

  public boolean supportsStoredProcedures() {
    return true;
  }

  public boolean supportsSubqueriesInComparisons() {
    return true;
  }

  public boolean supportsSubqueriesInExists() {
    return true;
  }

  public boolean supportsSubqueriesInIns() {
    return true;
  }

  public boolean supportsSubqueriesInQuantifieds() {
    return true;
  }

  public boolean supportsCorrelatedSubqueries() {
    return true;
  }

  public boolean supportsUnion() {
    return true;
  }

  public boolean supportsUnionAll() {
    return true;
  }

  public boolean supportsOpenCursorsAcrossCommit() {
    return true;
  }

  public boolean supportsOpenCursorsAcrossRollback() {
    return true;
  }

  public boolean supportsOpenStatementsAcrossCommit() {
    return true;
  }

  public boolean supportsOpenStatementsAcrossRollback() {
    return true;
  }

  public int getMaxBinaryLiteralLength() {
    return Integer.MAX_VALUE;
  }

  public int getMaxCharLiteralLength() {
    return Integer.MAX_VALUE;
  }

  public int getMaxColumnNameLength() {
    return 64;
  }

  public int getMaxColumnsInGroupBy() {
    return 64;
  }

  public int getMaxColumnsInIndex() {
    return 16;
  }

  public int getMaxColumnsInOrderBy() {
    return 64;
  }

  public int getMaxColumnsInSelect() {
    return Short.MAX_VALUE;
  }

  public int getMaxColumnsInTable() {
    return 0;
  }

  public int getMaxConnections() {
    return 0;
  }

  public int getMaxCursorNameLength() {
    return 0;
  }

  public int getMaxIndexLength() {
    return 256;
  }

  public int getMaxSchemaNameLength() {
    return 0;
  }

  public int getMaxProcedureNameLength() {
    return 64;
  }

  public int getMaxCatalogNameLength() {
    return 0;
  }

  public int getMaxRowSize() {
    return 0;
  }

  public boolean doesMaxRowSizeIncludeBlobs() {
    return false;
  }

  public int getMaxStatementLength() {
    return 0;
  }

  public int getMaxStatements() {
    return 0;
  }

  public int getMaxTableNameLength() {
    return 64;
  }

  public int getMaxTablesInSelect() {
    return 256;
  }

  public int getMaxUserNameLength() {
    return 0;
  }

  public int getDefaultTransactionIsolation() {
    return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
  }

  /**
   * Retrieves whether this database supports transactions. If not, invoking the method <code>commit
   * </code> is a noop, and the isolation level is <code>TRANSACTION_NONE</code>.
   *
   * @return <code>true</code> if transactions are supported; <code>false</code> otherwise
   */
  public boolean supportsTransactions() {
    return true;
  }

  /* Helper to generate  information schema with "equality" condition (typically on catalog name)
   */

  /**
   * Retrieves whether this database supports the given transaction isolation level.
   *
   * @param level one of the transaction isolation levels defined in <code>java.sql.Connection
   *     </code>
   * @return <code>true</code> if so; <code>false</code> otherwise
   * @see java.sql.Connection
   */
  public boolean supportsTransactionIsolationLevel(int level) {
    switch (level) {
      case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
      case java.sql.Connection.TRANSACTION_READ_COMMITTED:
      case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
      case java.sql.Connection.TRANSACTION_SERIALIZABLE:
        return true;
      default:
        return false;
    }
  }

  public boolean supportsDataDefinitionAndDataManipulationTransactions() {
    return true;
  }

  public boolean supportsDataManipulationTransactionsOnly() {
    return false;
  }

  public boolean dataDefinitionCausesTransactionCommit() {
    return true;
  }

  public boolean dataDefinitionIgnoredInTransactions() {
    return false;
  }

  /**
   * Retrieves a description of the stored procedures available in the given catalog. Only procedure
   * descriptions matching the schema and procedure name criteria are returned. They are ordered by
   * <code>PROCEDURE_CAT</code>, <code>PROCEDURE_SCHEM</code>, <code>PROCEDURE_NAME</code> and
   * <code>SPECIFIC_ NAME</code>.
   *
   * <p>Each procedure description has the following columns:
   *
   * <OL>
   *   <LI><B>PROCEDURE_CAT</B> String {@code =>} procedure catalog (may be <code>null</code>)
   *   <LI><B>PROCEDURE_SCHEM</B> String {@code =>} procedure schema (may be <code>null</code>)
   *   <LI><B>PROCEDURE_NAME</B> String {@code =>} procedure name
   *   <LI>reserved for future use
   *   <LI>reserved for future use
   *   <LI>reserved for future use
   *   <LI><B>REMARKS</B> String {@code =>} explanatory comment on the procedure
   *   <LI><B>PROCEDURE_TYPE</B> short {@code =>} kind of procedure:
   *       <UL>
   *         <LI>procedureResultUnknown - Cannot determine if a return value will be returned
   *         <LI>procedureNoResult - Does not return a return value
   *         <LI>procedureReturnsResult - Returns a return value
   *       </UL>
   *   <LI><B>SPECIFIC_NAME</B> String {@code =>} The name which uniquely identifies this procedure
   *       within its schema.
   * </OL>
   *
   * <p>A user may not have permissions to execute any of the procedures that are returned by <code>
   * getProcedures</code>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param procedureNamePattern a procedure name pattern; must match the procedure name as it is
   *     stored in the database
   * @return <code>ResultSet</code> - each row is a procedure description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   */
  public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
      throws SQLException {

    StringBuilder sb =
        new StringBuilder(
            "SELECT ROUTINE_SCHEMA PROCEDURE_CAT,"
                + "NULL PROCEDURE_SCHEM, "
                + "ROUTINE_NAME PROCEDURE_NAME,"
                + " NULL RESERVED1,"
                + " NULL RESERVED2,"
                + " NULL RESERVED3,"
                + " ROUTINE_COMMENT REMARKS,"
                + " CASE ROUTINE_TYPE "
                + "  WHEN 'FUNCTION' THEN "
                + procedureReturnsResult
                + "  WHEN 'PROCEDURE' THEN "
                + procedureNoResult
                + "  ELSE "
                + procedureResultUnknown
                + " END PROCEDURE_TYPE,"
                + " SPECIFIC_NAME "
                + " FROM INFORMATION_SCHEMA.ROUTINES ");

    boolean firstCondition = catalogCond(true, sb, "ROUTINE_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "ROUTINE_NAME", procedureNamePattern);

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of the given catalog's stored procedure parameter and result columns.
   *
   * <p>Only descriptions matching the schema, procedure and parameter name criteria are returned.
   * They are ordered by PROCEDURE_CAT, PROCEDURE_SCHEM, PROCEDURE_NAME and SPECIFIC_NAME. Within
   * this, the return value, if any, is first. Next are the parameter descriptions in call order.
   * The column descriptions follow in column number order.
   *
   * <p>Each row in the <code>ResultSet</code> is a parameter description or column description with
   * the following fields:
   *
   * <OL>
   *   <LI><B>PROCEDURE_CAT</B> String {@code =>} procedure catalog (may be <code>null</code>)
   *   <LI><B>PROCEDURE_SCHEM</B> String {@code =>} procedure schema (may be <code>null</code>)
   *   <LI><B>PROCEDURE_NAME</B> String {@code =>} procedure name
   *   <LI><B>COLUMN_NAME</B> String {@code =>} column/parameter name
   *   <LI><B>COLUMN_TYPE</B> Short {@code =>} kind of column/parameter:
   *       <UL>
   *         <LI>procedureColumnUnknown - nobody knows
   *         <LI>procedureColumnIn - IN parameter
   *         <LI>procedureColumnInOut - INOUT parameter
   *         <LI>procedureColumnOut - OUT parameter
   *         <LI>procedureColumnReturn - procedure return value
   *         <LI>procedureColumnResult - result column in <code>ResultSet</code>
   *       </UL>
   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
   *   <LI><B>TYPE_NAME</B> String {@code =>} SQL type name, for a UDT type the type name is fully
   *       qualified
   *   <LI><B>PRECISION</B> int {@code =>} precision
   *   <LI><B>LENGTH</B> int {@code =>} length in bytes of data
   *   <LI><B>SCALE</B> short {@code =>} scale - null is returned for data types where SCALE is not
   *       applicable.
   *   <LI><B>RADIX</B> short {@code =>} radix
   *   <LI><B>NULLABLE</B> short {@code =>} can it contain NULL.
   *       <UL>
   *         <LI>procedureNoNulls - does not allow NULL values
   *         <LI>procedureNullable - allows NULL values
   *         <LI>procedureNullableUnknown - nullability unknown
   *       </UL>
   *   <LI><B>REMARKS</B> String {@code =>} comment describing parameter/column
   *   <LI><B>COLUMN_DEF</B> String {@code =>} default value for the column, which should be
   *       interpreted as a string when the value is enclosed in single quotes (may be <code>null
   *       </code>)
   *       <UL>
   *         <LI>The string NULL (not enclosed in quotes) - if NULL was specified as the default
   *             value
   *         <LI>TRUNCATE (not enclosed in quotes) - if the specified default value cannot be
   *             represented without truncation
   *         <LI>NULL - if a default value was not specified
   *       </UL>
   *   <LI><B>SQL_DATA_TYPE</B> int {@code =>} reserved for future use
   *   <LI><B>SQL_DATETIME_SUB</B> int {@code =>} reserved for future use
   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} the maximum length of binary and character based
   *       columns. For any other datatype the returned value is a NULL
   *   <LI><B>ORDINAL_POSITION</B> int {@code =>} the ordinal position, starting from 1, for the
   *       input and output parameters for a procedure. A value of 0 is returned if this row
   *       describes the procedure's return value. For result set columns, it is the ordinal
   *       position of the column in the result set starting from 1. If there are multiple result
   *       sets, the column ordinal positions are implementation defined.
   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
   *       a column.
   *       <UL>
   *         <LI>YES --- if the column can include NULLs
   *         <LI>NO --- if the column cannot include NULLs
   *         <LI>empty string --- if the nullability for the column is unknown
   *       </UL>
   *   <LI><B>SPECIFIC_NAME</B> String {@code =>} the name which uniquely identifies this procedure
   *       within its schema.
   * </OL>
   *
   * <p><B>Note:</B> Some databases may not return the column descriptions for a procedure.
   *
   * <p>The PRECISION column represents the specified column size for the given column. For numeric
   * data, this is the maximum precision. For character data, this is the length in characters. For
   * datetime datatypes, this is the length in characters of the String representation (assuming the
   * maximum allowed precision of the fractional seconds component). For binary data, this is the
   * length in bytes. For the ROWID datatype, this is the length in bytes. Null is returned for data
   * types where the column size is not applicable.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param procedureNamePattern a procedure name pattern; must match the procedure name as it is
   *     stored in the database
   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
   *     the database
   * @return <code>ResultSet</code> - each row describes a stored procedure parameter or column
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   */
  public ResultSet getProcedureColumns(
      String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern)
      throws SQLException {
    /*
     *  Get info from information_schema.parameters
     */
    StringBuilder sb =
        new StringBuilder(
            "SELECT SPECIFIC_SCHEMA PROCEDURE_CAT, NULL PROCEDURE_SCHEM, SPECIFIC_NAME"
                + " PROCEDURE_NAME, PARAMETER_NAME COLUMN_NAME,  CASE PARAMETER_MODE   WHEN 'IN'"
                + " THEN "
                + procedureColumnIn
                + "  WHEN 'OUT' THEN "
                + procedureColumnOut
                + "  WHEN 'INOUT' THEN "
                + procedureColumnInOut
                + "  ELSE IF(PARAMETER_MODE IS NULL,"
                + procedureColumnReturn
                + ","
                + procedureColumnUnknown
                + ")"
                + " END COLUMN_TYPE,"
                + dataTypeClause("DTD_IDENTIFIER")
                + " DATA_TYPE,"
                + "DATA_TYPE TYPE_NAME,"
                + " CASE DATA_TYPE"
                + "  WHEN 'time' THEN "
                + "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
                + "  WHEN 'date' THEN 10"
                + "  WHEN 'datetime' THEN "
                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
                + "  WHEN 'timestamp' THEN "
                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
                + "  ELSE "
                + "  IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
                + Integer.MAX_VALUE
                + "), NUMERIC_PRECISION) "
                + " END `PRECISION`,"
                + " CASE DATA_TYPE"
                + "  WHEN 'time' THEN "
                + "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
                + "  WHEN 'date' THEN 10"
                + "  WHEN 'datetime' THEN "
                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
                + "  WHEN 'timestamp' THEN "
                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
                + "  ELSE "
                + "  IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
                + Integer.MAX_VALUE
                + "), NUMERIC_PRECISION) "
                + " END `LENGTH`,"
                + " CASE DATA_TYPE"
                + "  WHEN 'time' THEN CAST(DATETIME_PRECISION as signed integer)"
                + "  WHEN 'datetime' THEN CAST(DATETIME_PRECISION as signed integer)"
                + "  WHEN 'timestamp' THEN CAST(DATETIME_PRECISION as signed integer)"
                + "  ELSE NUMERIC_SCALE "
                + " END `SCALE`,"
                + "10 RADIX,"
                + procedureNullableUnknown
                + " NULLABLE,NULL REMARKS,NULL COLUMN_DEF,0 SQL_DATA_TYPE,0"
                + " SQL_DATETIME_SUB,CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH ,ORDINAL_POSITION, ''"
                + " IS_NULLABLE, SPECIFIC_NAME  FROM INFORMATION_SCHEMA.PARAMETERS");

    boolean firstCondition = catalogCond(true, sb, "SPECIFIC_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "SPECIFIC_NAME", procedureNamePattern);
    firstCondition = patternCond(firstCondition, sb, "PARAMETER_NAME", columnNamePattern);
    sb.append(" ORDER BY SPECIFIC_SCHEMA, SPECIFIC_NAME, ORDINAL_POSITION");

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of the given catalog's system or user function parameters and return
   * type.
   *
   * <p>Only descriptions matching the schema, function and parameter name criteria are returned.
   * They are ordered by <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>, <code>FUNCTION_NAME
   * </code> and <code>SPECIFIC_ NAME</code>. Within this, the return value, if any, is first. Next
   * are the parameter descriptions in call order. The column descriptions follow in column number
   * order.
   *
   * <p>Each row in the <code>ResultSet</code> is a parameter description, column description or
   * return type description with the following fields:
   *
   * <OL>
   *   <LI><B>FUNCTION_CAT</B> String {@code =>} function catalog (may be <code>null</code>)
   *   <LI><B>FUNCTION_SCHEM</B> String {@code =>} function schema (may be <code>null</code>)
   *   <LI><B>FUNCTION_NAME</B> String {@code =>} function name. This is the name used to invoke the
   *       function
   *   <LI><B>COLUMN_NAME</B> String {@code =>} column/parameter name
   *   <LI><B>COLUMN_TYPE</B> Short {@code =>} kind of column/parameter:
   *       <UL>
   *         <LI>functionColumnUnknown - nobody knows
   *         <LI>functionColumnIn - IN parameter
   *         <LI>functionColumnInOut - INOUT parameter
   *         <LI>functionColumnOut - OUT parameter
   *         <LI>functionColumnReturn - function return value
   *         <LI>functionColumnResult - Indicates that the parameter or column is a column in the
   *             <code>ResultSet</code>
   *       </UL>
   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
   *   <LI><B>TYPE_NAME</B> String {@code =>} SQL type name, for a UDT type the type name is fully
   *       qualified
   *   <LI><B>PRECISION</B> int {@code =>} precision
   *   <LI><B>LENGTH</B> int {@code =>} length in bytes of data
   *   <LI><B>SCALE</B> short {@code =>} scale - null is returned for data types where SCALE is not
   *       applicable.
   *   <LI><B>RADIX</B> short {@code =>} radix
   *   <LI><B>NULLABLE</B> short {@code =>} can it contain NULL.
   *       <UL>
   *         <LI>functionNoNulls - does not allow NULL values
   *         <LI>functionNullable - allows NULL values
   *         <LI>functionNullableUnknown - nullability unknown
   *       </UL>
   *   <LI><B>REMARKS</B> String {@code =>} comment describing column/parameter
   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} the maximum length of binary and character based
   *       parameters or columns. For any other datatype the returned value is a NULL
   *   <LI><B>ORDINAL_POSITION</B> int {@code =>} the ordinal position, starting from 1, for the
   *       input and output parameters. A value of 0 is returned if this row describes the
   *       function's return value. For result set columns, it is the ordinal position of the column
   *       in the result set starting from 1.
   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
   *       a parameter or column.
   *       <UL>
   *         <LI>YES --- if the parameter or column can include NULLs
   *         <LI>NO --- if the parameter or column cannot include NULLs
   *         <LI>empty string --- if the nullability for the parameter or column is unknown
   *       </UL>
   *   <LI><B>SPECIFIC_NAME</B> String {@code =>} the name which uniquely identifies this function
   *       within its schema. This is a user specified, or DBMS generated, name that may be
   *       different then the <code>FUNCTION_NAME</code> for example with overload functions
   * </OL>
   *
   * <p>The PRECISION column represents the specified column size for the given parameter or column.
   * For numeric data, this is the maximum precision. For character data, this is the length in
   * characters. For datetime datatypes, this is the length in characters of the String
   * representation (assuming the maximum allowed precision of the fractional seconds component).
   * For binary data, this is the length in bytes. For the ROWID datatype, this is the length in
   * bytes. Null is returned for data types where the column size is not applicable.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param functionNamePattern a procedure name pattern; must match the function name as it is
   *     stored in the database
   * @param columnNamePattern a parameter name pattern; must match the parameter or column name as
   *     it is stored in the database
   * @return <code>ResultSet</code> - each row describes a user function parameter, column or return
   *     type
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   * @since 1.6
   */
  public ResultSet getFunctionColumns(
      String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern)
      throws SQLException {

    StringBuilder sb =
        new StringBuilder(
            "SELECT SPECIFIC_SCHEMA `FUNCTION_CAT`, NULL `FUNCTION_SCHEM`, SPECIFIC_NAME"
                + " FUNCTION_NAME, PARAMETER_NAME COLUMN_NAME,  CASE PARAMETER_MODE   WHEN 'IN'"
                + " THEN "
                + functionColumnIn
                + "  WHEN 'OUT' THEN "
                + functionColumnOut
                + "  WHEN 'INOUT' THEN "
                + functionColumnInOut
                + "  ELSE "
                + functionReturn
                + " END COLUMN_TYPE,"
                + dataTypeClause("DTD_IDENTIFIER")
                + " DATA_TYPE,DATA_TYPE TYPE_NAME,NUMERIC_PRECISION"
                + " `PRECISION`,CHARACTER_MAXIMUM_LENGTH LENGTH,NUMERIC_SCALE SCALE,10 RADIX,"
                + procedureNullableUnknown
                + " NULLABLE,NULL REMARKS,CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH"
                + " ,ORDINAL_POSITION, '' IS_NULLABLE, SPECIFIC_NAME  FROM"
                + " INFORMATION_SCHEMA.PARAMETERS");

    boolean firstCondition = catalogCond(true, sb, "SPECIFIC_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "SPECIFIC_NAME", functionNamePattern);
    firstCondition = patternCond(firstCondition, sb, "PARAMETER_NAME", columnNamePattern);
    sb.append(firstCondition ? " WHERE " : " AND ")
        .append(" ROUTINE_TYPE='FUNCTION' ORDER BY FUNCTION_CAT, SPECIFIC_NAME, ORDINAL_POSITION");

    return executeQuery(sb.toString());
  }

  public ResultSet getSchemas() throws SQLException {
    return executeQuery("SELECT '' TABLE_SCHEM, '' TABLE_catalog  FROM DUAL WHERE 1=0");
  }

  public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
    return executeQuery("SELECT  ' ' table_schem, ' ' table_catalog FROM DUAL WHERE 1=0");
  }

  public ResultSet getCatalogs() throws SQLException {
    return executeQuery("SELECT SCHEMA_NAME TABLE_CAT FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY 1");
  }

  public ResultSet getTableTypes() throws SQLException {
    return executeQuery(
        "SELECT 'TABLE' TABLE_TYPE UNION SELECT 'SYSTEM VIEW' TABLE_TYPE UNION SELECT 'VIEW'"
            + " TABLE_TYPE");
  }

  /**
   * Retrieves a description of the access rights for a table's columns.
   *
   * <p>Only privileges matching the column name criteria are returned. They are ordered by
   * COLUMN_NAME and PRIVILEGE.
   *
   * <p>Each privilege description has the following columns:
   *
   * <OL>
   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
   *   <LI><B>GRANTOR</B> String {@code =>} grantor of access (may be <code>null</code>)
   *   <LI><B>GRANTEE</B> String {@code =>} grantee of access
   *   <LI><B>PRIVILEGE</B> String {@code =>} name of access (SELECT, INSERT, UPDATE, REFRENCES,
   *       ...)
   *   <LI><B>IS_GRANTABLE</B> String {@code =>} "YES" if grantee is permitted to grant to others;
   *       "NO" if not; <code>null</code> if unknown
   * </OL>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schema a schema name; must match the schema name as it is stored in the database; ""
   *     retrieves those without a schema; <code>null</code> means that the schema name should not
   *     be used to narrow the search
   * @param table a table name; must match the table name as it is stored in the database
   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
   *     the database
   * @return <code>ResultSet</code> - each row is a column privilege description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   */
  public ResultSet getColumnPrivileges(
      String catalog, String schema, String table, String columnNamePattern) throws SQLException {

    if (table == null) {
      throw new SQLException("'table' parameter must not be null");
    }
    StringBuilder sb =
        new StringBuilder(
            "SELECT TABLE_SCHEMA TABLE_CAT, "
                + "NULL TABLE_SCHEM, "
                + "TABLE_NAME, "
                + "COLUMN_NAME, "
                + "NULL AS GRANTOR, "
                + "GRANTEE, "
                + "PRIVILEGE_TYPE AS PRIVILEGE, "
                + "IS_GRANTABLE "
                + "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES");
    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
    sb.append(firstCondition ? " WHERE " : " AND ")
        .append(" TABLE_NAME = ")
        .append(escapeQuote(table));
    patternCond(false, sb, "COLUMN_NAME", columnNamePattern);
    sb.append(" ORDER BY COLUMN_NAME, PRIVILEGE_TYPE");

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of the access rights for each table available in a catalog. Note that a
   * table privilege applies to one or more columns in the table. It would be wrong to assume that
   * this privilege applies to all columns (this may be true for some systems but is not true for
   * all.)
   *
   * <p>Only privileges matching the schema and table name criteria are returned. They are ordered
   * by <code>TABLE_CAT</code>, <code>TABLE_SCHEM</code>, <code>TABLE_NAME</code>, and <code>
   * PRIVILEGE</code>.
   *
   * <p>Each privilege description has the following columns:
   *
   * <OL>
   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
   *   <LI><B>GRANTOR</B> String {@code =>} grantor of access (may be <code>null</code>)
   *   <LI><B>GRANTEE</B> String {@code =>} grantee of access
   *   <LI><B>PRIVILEGE</B> String {@code =>} name of access (SELECT, INSERT, UPDATE, REFRENCES,
   *       ...)
   *   <LI><B>IS_GRANTABLE</B> String {@code =>} "YES" if grantee is permitted to grant to others;
   *       "NO" if not; <code>null</code> if unknown
   * </OL>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
   *     database
   * @return <code>ResultSet</code> - each row is a table privilege description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   */
  public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
      throws SQLException {
    StringBuilder sb =
        new StringBuilder(
            "SELECT TABLE_SCHEMA TABLE_CAT, "
                + "NULL TABLE_SCHEM, "
                + "TABLE_NAME, "
                + "NULL GRANTOR,"
                + "GRANTEE, "
                + "PRIVILEGE_TYPE PRIVILEGE, "
                + "IS_GRANTABLE "
                + "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES");
    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "TABLE_NAME", tableNamePattern);
    sb.append(" ORDER BY TABLE_SCHEMA, TABLE_NAME,  PRIVILEGE_TYPE ");

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of a table's columns that are automatically updated when any value in a
   * row is updated. They are unordered.
   *
   * <p>Each column description has the following columns:
   *
   * <OL>
   *   <LI><B>SCOPE</B> short {@code =>} is not used
   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL data type from <code>java.sql.Types</code>
   *   <LI><B>TYPE_NAME</B> String {@code =>} Data source-dependent type name
   *   <LI><B>COLUMN_SIZE</B> int {@code =>} precision
   *   <LI><B>BUFFER_LENGTH</B> int {@code =>} length of column value in bytes
   *   <LI><B>DECIMAL_DIGITS</B> short {@code =>} scale - Null is returned for data types where
   *       DECIMAL_DIGITS is not applicable.
   *   <LI><B>PSEUDO_COLUMN</B> short {@code =>} whether this is pseudo column like an Oracle ROWID
   *       <UL>
   *         <LI>versionColumnUnknown - may or may not be pseudo column
   *         <LI>versionColumnNotPseudo - is NOT a pseudo column
   *         <LI>versionColumnPseudo - is a pseudo column
   *       </UL>
   * </OL>
   *
   * <p>The COLUMN_SIZE column represents the specified column size for the given column. For
   * numeric data, this is the maximum precision. For character data, this is the length in
   * characters. For datetime datatypes, this is the length in characters of the String
   * representation (assuming the maximum allowed precision of the fractional seconds component).
   * For binary data, this is the length in bytes. For the ROWID datatype, this is the length in
   * bytes. Null is returned for data types where the column size is not applicable.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog;<code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schema a schema name; must match the schema name as it is stored in the database; ""
   *     retrieves those without a schema; <code>null</code> means that the schema name should not
   *     be used to narrow the search
   * @param table a table name; must match the table name as it is stored in the database
   * @return a <code>ResultSet</code> object in which each row is a column description
   * @throws SQLException if a database access error occurs
   */
  public ResultSet getVersionColumns(String catalog, String schema, String table)
      throws SQLException {
    String sql =
        "SELECT 0 SCOPE, ' ' COLUMN_NAME, 0 DATA_TYPE,"
            + " ' ' TYPE_NAME, 0 COLUMN_SIZE, 0 BUFFER_LENGTH,"
            + " 0 DECIMAL_DIGITS, 0 PSEUDO_COLUMN "
            + " FROM DUAL WHERE 1 = 0";
    return executeQuery(sql);
  }

  /**
   * Retrieves a description of the foreign key columns in the given foreign key table that
   * reference the primary key or the columns representing a unique constraint of the parent table
   * (could be the same or a different table). The number of columns returned from the parent table
   * must match the number of columns that make up the foreign key. They are ordered by FKTABLE_CAT,
   * FKTABLE_SCHEM, FKTABLE_NAME, and KEY_SEQ.
   *
   * <p>Each foreign key column description has the following columns:
   *
   * <OL>
   *   <LI><B>PKTABLE_CAT</B> String {@code =>} parent key table catalog (may be <code>null</code>)
   *   <LI><B>PKTABLE_SCHEM</B> String {@code =>} parent key table schema (may be <code>null</code>)
   *   <LI><B>PKTABLE_NAME</B> String {@code =>} parent key table name
   *   <LI><B>PKCOLUMN_NAME</B> String {@code =>} parent key column name
   *   <LI><B>FKTABLE_CAT</B> String {@code =>} foreign key table catalog (may be <code>null</code>)
   *       being exported (may be <code>null</code>)
   *   <LI><B>FKTABLE_SCHEM</B> String {@code =>} foreign key table schema (may be <code>null</code>
   *       ) being exported (may be <code>null</code>)
   *   <LI><B>FKTABLE_NAME</B> String {@code =>} foreign key table name being exported
   *   <LI><B>FKCOLUMN_NAME</B> String {@code =>} foreign key column name being exported
   *   <LI><B>KEY_SEQ</B> short {@code =>} sequence number within foreign key( a value of 1
   *       represents the first column of the foreign key, a value of 2 would represent the second
   *       column within the foreign key).
   *   <LI><B>UPDATE_RULE</B> short {@code =>} What happens to foreign key when parent key is
   *       updated:
   *       <UL>
   *         <LI>importedNoAction - do not allow update of parent key if it has been imported
   *         <LI>importedKeyCascade - change imported key to agree with parent key update
   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its parent key has
   *             been updated
   *         <LI>importedKeySetDefault - change imported key to default values if its parent key has
   *             been updated
   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
   *       </UL>
   *   <LI><B>DELETE_RULE</B> short {@code =>} What happens to the foreign key when parent key is
   *       deleted.
   *       <UL>
   *         <LI>importedKeyNoAction - do not allow delete of parent key if it has been imported
   *         <LI>importedKeyCascade - delete rows that import a deleted key
   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
   *             has been deleted
   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
   *         <LI>importedKeySetDefault - change imported key to default if its parent key has been
   *             deleted
   *       </UL>
   *   <LI><B>FK_NAME</B> String {@code =>} foreign key name (may be <code>null</code>)
   *   <LI><B>PK_NAME</B> String {@code =>} parent key name (may be <code>null</code>)
   *   <LI><B>DEFERRABILITY</B> short {@code =>} can the evaluation of foreign key constraints be
   *       deferred until commit
   *       <UL>
   *         <LI>importedKeyInitiallyDeferred - see SQL92 for definition
   *         <LI>importedKeyInitiallyImmediate - see SQL92 for definition
   *         <LI>importedKeyNotDeferrable - see SQL92 for definition
   *       </UL>
   * </OL>
   *
   * @param parentCatalog a catalog name; must match the catalog name as it is stored in the
   *     database; "" retrieves those without a catalog; <code>null</code> means drop catalog name
   *     from the selection criteria
   * @param parentSchema a schema name; must match the schema name as it is stored in the database;
   *     "" retrieves those without a schema; <code>null</code> means drop schema name from the
   *     selection criteria
   * @param parentTable the name of the table that exports the key; pattern, or null (means any
   *     table) value
   * @param foreignCatalog a catalog name; must match the catalog name as it is stored in the
   *     database; "" retrieves those without a catalog; <code>null</code> means drop catalog name
   *     from the selection criteria
   * @param foreignSchema a schema name; must match the schema name as it is stored in the database;
   *     "" retrieves those without a schema; <code>null</code> means drop schema name from the
   *     selection criteria
   * @param foreignTable the name of the table that imports the key; pattern, or null (means any
   *     table) value is stored in the database
   * @return <code>ResultSet</code> - each row is a foreign key column description
   * @throws SQLException if a database access error occurs
   * @see #getImportedKeys
   */
  public ResultSet getCrossReference(
      String parentCatalog,
      String parentSchema,
      String parentTable,
      String foreignCatalog,
      String foreignSchema,
      String foreignTable)
      throws SQLException {

    StringBuilder sb =
        new StringBuilder(
            "SELECT KCU.REFERENCED_TABLE_SCHEMA PKTABLE_CAT, NULL PKTABLE_SCHEM, "
                + " KCU.REFERENCED_TABLE_NAME PKTABLE_NAME, KCU.REFERENCED_COLUMN_NAME"
                + " PKCOLUMN_NAME, KCU.TABLE_SCHEMA FKTABLE_CAT, NULL FKTABLE_SCHEM, "
                + " KCU.TABLE_NAME FKTABLE_NAME, KCU.COLUMN_NAME FKCOLUMN_NAME,"
                + " KCU.POSITION_IN_UNIQUE_CONSTRAINT KEY_SEQ, CASE update_rule    WHEN 'RESTRICT'"
                + " THEN 1   WHEN 'NO ACTION' THEN 3   WHEN 'CASCADE' THEN 0   WHEN 'SET NULL' THEN"
                + " 2   WHEN 'SET DEFAULT' THEN 4 END UPDATE_RULE, CASE DELETE_RULE  WHEN"
                + " 'RESTRICT' THEN 1  WHEN 'NO ACTION' THEN 3  WHEN 'CASCADE' THEN 0  WHEN 'SET"
                + " NULL' THEN 2  WHEN 'SET DEFAULT' THEN 4 END DELETE_RULE, RC.CONSTRAINT_NAME"
                + " FK_NAME, RC.UNIQUE_CONSTRAINT_NAME PK_NAME,"
                + importedKeyNotDeferrable
                + " DEFERRABILITY "
                + "FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU"
                + " INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC"
                + " ON KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA"
                + " AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME ");

    boolean firstCondition = catalogCond(true, sb, "KCU.REFERENCED_TABLE_SCHEMA", parentCatalog);
    firstCondition = catalogCond(firstCondition, sb, "KCU.TABLE_SCHEMA", foreignCatalog);
    firstCondition = patternCond(firstCondition, sb, "KCU.REFERENCED_TABLE_NAME", parentTable);
    firstCondition = patternCond(firstCondition, sb, "KCU.TABLE_NAME", foreignTable);
    sb.append("ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, KEY_SEQ");

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves a description of all the data types supported by this database. They are ordered by
   * DATA_TYPE and then by how closely the data type maps to the corresponding JDBC SQL type.
   *
   * <p>If the database supports SQL distinct types, then getTypeInfo() will return a single row
   * with a TYPE_NAME of DISTINCT and a DATA_TYPE of Types.DISTINCT. If the database supports SQL
   * structured types, then getTypeInfo() will return a single row with a TYPE_NAME of STRUCT and a
   * DATA_TYPE of Types.STRUCT.
   *
   * <p>If SQL distinct or structured types are supported, then information on the individual types
   * may be obtained from the getUDTs() method.
   *
   * <p>Each type description has the following columns:
   *
   * <OL>
   *   <LI><B>TYPE_NAME</B> String {@code =>} Type name
   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL data type from java.sql.Types
   *   <LI><B>PRECISION</B> int {@code =>} maximum precision
   *   <LI><B>LITERAL_PREFIX</B> String {@code =>} prefix used to quote a literal (may be <code>null
   *       </code>)
   *   <LI><B>LITERAL_SUFFIX</B> String {@code =>} suffix used to quote a literal (may be <code>null
   *       </code>)
   *   <LI><B>CREATE_PARAMS</B> String {@code =>} parameters used in creating the type (may be
   *       <code>null</code>)
   *   <LI><B>NULLABLE</B> short {@code =>} can you use NULL for this type.
   *       <UL>
   *         <LI>typeNoNulls - does not allow NULL values
   *         <LI>typeNullable - allows NULL values
   *         <LI>typeNullableUnknown - nullability unknown
   *       </UL>
   *   <LI><B>CASE_SENSITIVE</B> boolean{@code =>} is it case sensitive.
   *   <LI><B>SEARCHABLE</B> short {@code =>} can you use "WHERE" based on this type:
   *       <UL>
   *         <LI>typePredNone - No support
   *         <LI>typePredChar - Only supported with WHERE .. LIKE
   *         <LI>typePredBasic - Supported except for WHERE .. LIKE
   *         <LI>typeSearchable - Supported for all WHERE ..
   *       </UL>
   *   <LI><B>UNSIGNED_ATTRIBUTE</B> boolean {@code =>} is it unsigned.
   *   <LI><B>FIXED_PREC_SCALE</B> boolean {@code =>} can it be a money value.
   *   <LI><B>AUTO_INCREMENT</B> boolean {@code =>} can it be used for an auto-increment value.
   *   <LI><B>LOCAL_TYPE_NAME</B> String {@code =>} localized version of type name (may be <code>
   *       null</code>)
   *   <LI><B>MINIMUM_SCALE</B> short {@code =>} minimum scale supported
   *   <LI><B>MAXIMUM_SCALE</B> short {@code =>} maximum scale supported
   *   <LI><B>SQL_DATA_TYPE</B> int {@code =>} unused
   *   <LI><B>SQL_DATETIME_SUB</B> int {@code =>} unused
   *   <LI><B>NUM_PREC_RADIX</B> int {@code =>} usually 2 or 10
   * </OL>
   *
   * <p>The PRECISION column represents the maximum column size that the server supports for the
   * given datatype. For numeric data, this is the maximum precision. For character data, this is
   * the length in characters. For datetime datatypes, this is the length in characters of the
   * String representation (assuming the maximum allowed precision of the fractional seconds
   * component). For binary data, this is the length in bytes. For the ROWID datatype, this is the
   * length in bytes. Null is returned for data types where the column size is not applicable.
   *
   * @return a <code>ResultSet</code> object in which each row is an SQL type description
   */
  public ResultSet getTypeInfo() {
    String[] columnNames = {
      "TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", "LITERAL_SUFFIX",
      "CREATE_PARAMS", "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE",
      "FIXED_PREC_SCALE", "AUTO_INCREMENT", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE",
      "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX"
    };
    DataType[] dataTypes = {
      DataType.VARCHAR,
      DataType.INTEGER,
      DataType.INTEGER,
      DataType.VARCHAR,
      DataType.VARCHAR,
      DataType.VARCHAR,
      DataType.INTEGER,
      DataType.BIT,
      DataType.SMALLINT,
      DataType.BIT,
      DataType.BIT,
      DataType.BIT,
      DataType.VARCHAR,
      DataType.SMALLINT,
      DataType.SMALLINT,
      DataType.INTEGER,
      DataType.INTEGER,
      DataType.INTEGER
    };

    String[][] data = {
      {"BIT", "-7", "1", "", "", "", "1", "1", "3", "0", "0", "0", "BIT", "0", "0", "0", "0", "10"},
      {
        "BOOL", "-7", "1", "", "", "", "1", "1", "3", "0", "0", "0", "BOOL", "0", "0", "0", "0",
        "10"
      },
      {
        "TINYINT",
        "-6",
        "3",
        "",
        "",
        "[(M)] [UNSIGNED] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "TINYINT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "TINYINT UNSIGNED",
        "-6",
        "3",
        "",
        "",
        "[(M)] [UNSIGNED] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "TINYINT UNSIGNED",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "BIGINT",
        "-5",
        "19",
        "",
        "",
        "[(M)] [UNSIGNED] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "BIGINT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "BIGINT UNSIGNED",
        "-5",
        "20",
        "",
        "",
        "[(M)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "BIGINT UNSIGNED",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "LONG VARBINARY",
        "-4",
        "16777215",
        "'",
        "'",
        "",
        "1",
        "1",
        "3",
        "0",
        "0",
        "0",
        "LONG VARBINARY",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "MEDIUMBLOB",
        "-4",
        "16777215",
        "'",
        "'",
        "",
        "1",
        "1",
        "3",
        "0",
        "0",
        "0",
        "MEDIUMBLOB",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "LONGBLOB",
        "-4",
        "2147483647",
        "'",
        "'",
        "",
        "1",
        "1",
        "3",
        "0",
        "0",
        "0",
        "LONGBLOB",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "BLOB", "-4", "65535", "'", "'", "", "1", "1", "3", "0", "0", "0", "BLOB", "0", "0", "0",
        "0", "10"
      },
      {
        "TINYBLOB",
        "-4",
        "255",
        "'",
        "'",
        "",
        "1",
        "1",
        "3",
        "0",
        "0",
        "0",
        "TINYBLOB",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "VARBINARY",
        "-3",
        "255",
        "'",
        "'",
        "(M)",
        "1",
        "1",
        "3",
        "0",
        "0",
        "0",
        "VARBINARY",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "BINARY", "-2", "255", "'", "'", "(M)", "1", "1", "3", "0", "0", "0", "BINARY", "0", "0",
        "0", "0", "10"
      },
      {
        "LONG VARCHAR",
        "-1",
        "16777215",
        "'",
        "'",
        "",
        "1",
        "0",
        "3",
        "0",
        "0",
        "0",
        "LONG VARCHAR",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "MEDIUMTEXT",
        "-1",
        "16777215",
        "'",
        "'",
        "",
        "1",
        "0",
        "3",
        "0",
        "0",
        "0",
        "MEDIUMTEXT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "LONGTEXT",
        "-1",
        "2147483647",
        "'",
        "'",
        "",
        "1",
        "0",
        "3",
        "0",
        "0",
        "0",
        "LONGTEXT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "TEXT", "-1", "65535", "'", "'", "", "1", "0", "3", "0", "0", "0", "TEXT", "0", "0", "0",
        "0", "10"
      },
      {
        "TINYTEXT",
        "-1",
        "255",
        "'",
        "'",
        "",
        "1",
        "0",
        "3",
        "0",
        "0",
        "0",
        "TINYTEXT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "CHAR", "1", "255", "'", "'", "(M)", "1", "0", "3", "0", "0", "0", "CHAR", "0", "0", "0",
        "0", "10"
      },
      {
        "NUMERIC",
        "2",
        "65",
        "",
        "",
        "[(M,D])] [ZEROFILL]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "1",
        "NUMERIC",
        "-308",
        "308",
        "0",
        "0",
        "10"
      },
      {
        "DECIMAL",
        "3",
        "65",
        "",
        "",
        "[(M,D])] [ZEROFILL]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "1",
        "DECIMAL",
        "-308",
        "308",
        "0",
        "0",
        "10"
      },
      {
        "INTEGER",
        "4",
        "10",
        "",
        "",
        "[(M)] [UNSIGNED] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "INTEGER",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "INTEGER UNSIGNED",
        "4",
        "10",
        "",
        "",
        "[(M)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "INTEGER UNSIGNED",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "INT",
        "4",
        "10",
        "",
        "",
        "[(M)] [UNSIGNED] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "INT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "INT UNSIGNED",
        "4",
        "10",
        "",
        "",
        "[(M)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "INT UNSIGNED",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "MEDIUMINT",
        "4",
        "7",
        "",
        "",
        "[(M)] [UNSIGNED] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "MEDIUMINT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "MEDIUMINT UNSIGNED",
        "4",
        "8",
        "",
        "",
        "[(M)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "MEDIUMINT UNSIGNED",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "SMALLINT",
        "5",
        "5",
        "",
        "",
        "[(M)] [UNSIGNED] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "SMALLINT",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "SMALLINT UNSIGNED",
        "5",
        "5",
        "",
        "",
        "[(M)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "1",
        "0",
        "1",
        "SMALLINT UNSIGNED",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "FLOAT",
        "7",
        "10",
        "",
        "",
        "[(M|D)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "1",
        "FLOAT",
        "-38",
        "38",
        "0",
        "0",
        "10"
      },
      {
        "DOUBLE",
        "8",
        "17",
        "",
        "",
        "[(M|D)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "1",
        "DOUBLE",
        "-308",
        "308",
        "0",
        "0",
        "10"
      },
      {
        "DOUBLE PRECISION",
        "8",
        "17",
        "",
        "",
        "[(M,D)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "1",
        "DOUBLE PRECISION",
        "-308",
        "308",
        "0",
        "0",
        "10"
      },
      {
        "REAL",
        "8",
        "17",
        "",
        "",
        "[(M,D)] [ZEROFILL]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "1",
        "REAL",
        "-308",
        "308",
        "0",
        "0",
        "10"
      },
      {
        "VARCHAR", "12", "255", "'", "'", "(M)", "1", "0", "3", "0", "0", "0", "VARCHAR", "0", "0",
        "0", "0", "10"
      },
      {
        "ENUM", "12", "65535", "'", "'", "", "1", "0", "3", "0", "0", "0", "ENUM", "0", "0", "0",
        "0", "10"
      },
      {
        "SET", "12", "64", "'", "'", "", "1", "0", "3", "0", "0", "0", "SET", "0", "0", "0", "0",
        "10"
      },
      {
        "DATE", "91", "10", "'", "'", "", "1", "0", "3", "0", "0", "0", "DATE", "0", "0", "0", "0",
        "10"
      },
      {
        "TIME", "92", "18", "'", "'", "[(M)]", "1", "0", "3", "0", "0", "0", "TIME", "0", "0", "0",
        "0", "10"
      },
      {
        "DATETIME",
        "93",
        "27",
        "'",
        "'",
        "[(M)]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "0",
        "DATETIME",
        "0",
        "0",
        "0",
        "0",
        "10"
      },
      {
        "TIMESTAMP",
        "93",
        "27",
        "'",
        "'",
        "[(M)]",
        "1",
        "0",
        "3",
        "0",
        "0",
        "0",
        "TIMESTAMP",
        "0",
        "0",
        "0",
        "0",
        "10"
      }
    };

    return CompleteResult.createResultSet(columnNames, dataTypes, data, connection.getContext(), 0);
  }

  /**
   * Retrieves a description of the given table's indices and statistics. They are ordered by
   * NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
   *
   * <p>Each index column description has the following columns:
   *
   * <ol>
   *   <li><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
   *   <li><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
   *   <li><B>TABLE_NAME</B> String {@code =>} table name
   *   <li><B>NON_UNIQUE</B> boolean {@code =>} Can index values be non-unique. false when TYPE is
   *       tableIndexStatistic
   *   <li><B>INDEX_QUALIFIER</B> String {@code =>} index catalog (may be <code>null</code>); <code>
   *       null</code> when TYPE is tableIndexStatistic
   *   <li><B>INDEX_NAME</B> String {@code =>} index name; <code>null</code> when TYPE is
   *       tableIndexStatistic
   *   <li><B>TYPE</B> short {@code =>} index type:
   *       <ul>
   *         <li>tableIndexStatistic - this identifies table statistics that are returned in
   *             conjuction with a table's index descriptions
   *         <li>tableIndexClustered - this is a clustered index
   *         <li>tableIndexHashed - this is a hashed index
   *         <li>tableIndexOther - this is some other style of index
   *       </ul>
   *   <li><B>ORDINAL_POSITION</B> short {@code =>} column sequence number within index; zero when
   *       TYPE is tableIndexStatistic
   *   <li><B>COLUMN_NAME</B> String {@code =>} column name; <code>null</code> when TYPE is
   *       tableIndexStatistic
   *   <li><B>ASC_OR_DESC</B> String {@code =>} column sort sequence, "A" {@code =>} ascending, "D"
   *       {@code =>} descending, may be <code>null</code> if sort sequence is not supported; <code>
   *       null</code> when TYPE is tableIndexStatistic
   *   <li><B>CARDINALITY</B> long {@code =>} When TYPE is tableIndexStatistic, then this is the
   *       number of rows in the table; otherwise, it is the number of unique values in the index.
   *   <li><B>PAGES</B> long {@code =>} When TYPE is tableIndexStatisic then this is the number of
   *       pages used for the table, otherwise it is the number of pages used for the current index.
   *   <li><B>FILTER_CONDITION</B> String {@code =>} Filter condition, if any. (may be <code>null
   *       </code>)
   * </ol>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in this database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schema a schema name; must match the schema name as it is stored in this database; ""
   *     retrieves those without a schema; <code>null</code> means that the schema name should not
   *     be used to narrow the search
   * @param table a table name; must match the table name as it is stored in this database
   * @param unique when true, return only indices for unique values; when false, return indices
   *     regardless of whether unique or not
   * @param approximate when true, result is allowed to reflect approximate or out of data values;
   *     when false, results are requested to be accurate
   * @return <code>ResultSet</code> - each row is an index column description
   * @throws SQLException if a database access error occurs
   */
  public ResultSet getIndexInfo(
      String catalog, String schema, String table, boolean unique, boolean approximate)
      throws SQLException {
    if (table == null) {
      throw new SQLException("'table' parameter must not be null");
    }
    StringBuilder sb =
        new StringBuilder(
            "SELECT TABLE_SCHEMA TABLE_CAT, "
                + "NULL TABLE_SCHEM, "
                + "TABLE_NAME, "
                + "NON_UNIQUE, "
                + "TABLE_SCHEMA INDEX_QUALIFIER, "
                + "INDEX_NAME, "
                + tableIndexOther
                + " TYPE, "
                + "SEQ_IN_INDEX ORDINAL_POSITION, "
                + "COLUMN_NAME, "
                + "COLLATION ASC_OR_DESC, "
                + "CARDINALITY, "
                + "NULL PAGES, "
                + "NULL FILTER_CONDITION"
                + " FROM INFORMATION_SCHEMA.STATISTICS");

    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
    sb.append(firstCondition ? " WHERE " : " AND ")
        .append("TABLE_NAME = ")
        .append(escapeQuote(table));
    if (unique) sb.append(" AND NON_UNIQUE = 0");
    sb.append(" ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION");

    return executeQuery(sb.toString());
  }

  /**
   * Retrieves whether this database supports the given result set type. ResultSet.TYPE_FORWARD_ONLY
   * and ResultSet.TYPE_SCROLL_INSENSITIVE are supported.
   *
   * @param type one of the following <code>ResultSet</code> constants:
   *     <ul>
   *       <li><code>ResultSet.TYPE_FORWARD_ONLY</code>
   *       <li><code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
   *       <li><code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
   *     </ul>
   *
   * @return true if supported
   */
  public boolean supportsResultSetType(int type) {
    return (type == ResultSet.TYPE_SCROLL_INSENSITIVE || type == ResultSet.TYPE_FORWARD_ONLY);
  }

  /**
   * Retrieves whether this database supports the given concurrency type in combination with the
   * given result set type. All are supported, but combination that use
   * ResultSet.TYPE_SCROLL_INSENSITIVE.
   *
   * @param type one of the following <code>ResultSet</code> constants:
   *     <ul>
   *       <li><code>ResultSet.TYPE_FORWARD_ONLY</code>
   *       <li><code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
   *       <li><code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
   *     </ul>
   *
   * @param concurrency one of the following <code>ResultSet</code> constants:
   *     <ul>
   *       <li><code>ResultSet.CONCUR_READ_ONLY</code>
   *       <li><code>ResultSet.CONCUR_UPDATABLE</code>
   *     </ul>
   *
   * @return true if supported
   */
  public boolean supportsResultSetConcurrency(int type, int concurrency) {
    // Support all concurrency (ResultSet.CONCUR_READ_ONLY and ResultSet.CONCUR_UPDATABLE)
    // so just return scroll type
    return type == ResultSet.TYPE_SCROLL_INSENSITIVE || type == ResultSet.TYPE_FORWARD_ONLY;
  }

  public boolean ownUpdatesAreVisible(int type) {
    return supportsResultSetType(type);
  }

  public boolean ownDeletesAreVisible(int type) {
    return supportsResultSetType(type);
  }

  public boolean ownInsertsAreVisible(int type) {
    return supportsResultSetType(type);
  }

  public boolean othersUpdatesAreVisible(int type) {
    return false;
  }

  public boolean othersDeletesAreVisible(int type) {
    return false;
  }

  public boolean othersInsertsAreVisible(int type) {
    return false;
  }

  public boolean updatesAreDetected(int type) {
    return false;
  }

  public boolean deletesAreDetected(int type) {
    return false;
  }

  public boolean insertsAreDetected(int type) {
    return false;
  }

  public boolean supportsBatchUpdates() {
    return true;
  }

  /**
   * Retrieves a description of the user-defined types (UDTs) defined in a particular schema.
   * Schema-specific UDTs may have type <code>JAVA_OBJECT</code>, <code>STRUCT</code>, or <code>
   * DISTINCT</code>.
   *
   * <p>Only types matching the catalog, schema, type name and type criteria are returned. They are
   * ordered by <code>DATA_TYPE</code>, <code>TYPE_CAT</code>, <code>TYPE_SCHEM</code> and <code>
   * TYPE_NAME</code>. The type name parameter may be a fully-qualified name. In this case, the
   * catalog and schemaPattern parameters are ignored.
   *
   * <p>Each type description has the following columns:
   *
   * <ol>
   *   <li><B>TYPE_CAT</B> String {@code =>} the type's catalog (may be <code>null</code>)
   *   <li><B>TYPE_SCHEM</B> String {@code =>} type's schema (may be <code>null</code>)
   *   <li><B>TYPE_NAME</B> String {@code =>} type name
   *   <li><B>CLASS_NAME</B> String {@code =>} Java class name
   *   <li><B>DATA_TYPE</B> int {@code =>} type value defined in java.sql.Types. One of JAVA_OBJECT,
   *       STRUCT, or DISTINCT
   *   <li><B>REMARKS</B> String {@code =>} explanatory comment on the type
   *   <li><B>BASE_TYPE</B> short {@code =>} type code of the source type of a DISTINCT type or the
   *       type that implements the user-generated reference type of the SELF_REFERENCING_COLUMN of
   *       a structured type as defined in java.sql.Types (<code>null</code> if DATA_TYPE is not
   *       DISTINCT or not STRUCT with REFERENCE_GENERATION = USER_DEFINED)
   * </ol>
   *
   * <p><B>Note:</B> If the driver does not support UDTs, an empty result set is returned.
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema pattern name; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param typeNamePattern a type name pattern; must match the type name as it is stored in the
   *     database; may be a fully qualified name
   * @param types a list of user-defined types (JAVA_OBJECT, STRUCT, or DISTINCT) to include; <code>
   *     null</code> returns all types
   * @return <code>ResultSet</code> object in which each row describes a UDT
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   * @since 1.2
   */
  @Override
  public ResultSet getUDTs(
      String catalog, String schemaPattern, String typeNamePattern, int[] types)
      throws SQLException {
    String sql =
        "SELECT ' ' TYPE_CAT, NULL TYPE_SCHEM, ' ' TYPE_NAME, ' ' CLASS_NAME, 0 DATA_TYPE, ' '"
            + " REMARKS, 0 BASE_TYPE FROM DUAL WHERE 1=0";

    return executeQuery(sql);
  }

  public org.mariadb.jdbc.Connection getConnection() {
    return connection;
  }

  public boolean supportsSavepoints() {
    return true;
  }

  public boolean supportsNamedParameters() {
    return false;
  }

  public boolean supportsMultipleOpenResults() {
    return false;
  }

  public boolean supportsGetGeneratedKeys() {
    return true;
  }

  /**
   * Retrieves a description of the user-defined type (UDT) hierarchies defined in a particular
   * schema in this database. Only the immediate super type/ subtype relationship is modeled. Only
   * supertype information for UDTs matching the catalog, schema, and type name is returned. The
   * type name parameter may be a fully-qualified name. When the UDT name supplied is a
   * fully-qualified name, the catalog and schemaPattern parameters are ignored. If a UDT does not
   * have a direct super type, it is not listed here. A row of the <code>ResultSet</code> object
   * returned by this method describes the designated UDT and a direct supertype. A row has the
   * following columns:
   *
   * <OL>
   *   <li><B>TYPE_CAT</B> String {@code =>} the UDT's catalog (may be <code>null</code>)
   *   <li><B>TYPE_SCHEM</B> String {@code =>} UDT's schema (may be <code>null</code>)
   *   <li><B>TYPE_NAME</B> String {@code =>} type name of the UDT
   *   <li><B>SUPERTYPE_CAT</B> String {@code =>} the direct super type's catalog (may be <code>null
   *       </code>)
   *   <li><B>SUPERTYPE_SCHEM</B> String {@code =>} the direct super type's schema (may be <code>
   *       null</code>)
   *   <li><B>SUPERTYPE_NAME</B> String {@code =>} the direct super type's name
   * </OL>
   *
   * <p><B>Note:</B> If the driver does not support type hierarchies, an empty result set is
   * returned.
   *
   * @param catalog a catalog name; "" retrieves those without a catalog; <code>null</code> means
   *     drop catalog name from the selection criteria
   * @param schemaPattern a schema name pattern; "" retrieves those without a schema
   * @param typeNamePattern a UDT name pattern; may be a fully-qualified name
   * @return a <code>ResultSet</code> object in which a row gives information about the designated
   *     UDT
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   * @since 1.4
   */
  public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern)
      throws SQLException {
    String sql =
        "SELECT  ' ' TYPE_CAT, NULL TYPE_SCHEM, ' ' TYPE_NAME, ' ' SUPERTYPE_CAT, ' '"
            + " SUPERTYPE_SCHEM, ' '  SUPERTYPE_NAME FROM DUAL WHERE 1=0";

    return executeQuery(sql);
  }

  /**
   * Retrieves a description of the table hierarchies defined in a particular schema in this
   * database.
   *
   * <p>Only supertable information for tables matching the catalog, schema and table name are
   * returned. The table name parameter may be a fully-qualified name, in which case, the catalog
   * and schemaPattern parameters are ignored. If a table does not have a super table, it is not
   * listed here. Supertables have to be defined in the same catalog and schema as the sub tables.
   * Therefore, the type description does not need to include this information for the supertable.
   *
   * <p>Each type description has the following columns:
   *
   * <OL>
   *   <li><B>TABLE_CAT</B> String {@code =>} the type's catalog (may be <code>null</code>)
   *   <li><B>TABLE_SCHEM</B> String {@code =>} type's schema (may be <code>null</code>)
   *   <li><B>TABLE_NAME</B> String {@code =>} type name
   *   <li><B>SUPERTABLE_NAME</B> String {@code =>} the direct super type's name
   * </OL>
   *
   * <p><B>Note:</B> If the driver does not support type hierarchies, an empty result set is
   * returned.
   *
   * @param catalog a catalog name; "" retrieves those without a catalog; <code>null</code> means
   *     drop catalog name from the selection criteria
   * @param schemaPattern a schema name pattern; "" retrieves those without a schema
   * @param tableNamePattern a table name pattern; may be a fully-qualified name
   * @return a <code>ResultSet</code> object in which each row is a type description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   * @since 1.4
   */
  public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern)
      throws SQLException {
    String sql =
        "SELECT  ' ' TABLE_CAT, ' ' TABLE_SCHEM, ' ' TABLE_NAME, ' ' SUPERTABLE_NAME FROM DUAL"
            + " WHERE 1=0";
    return executeQuery(sql);
  }

  /**
   * Retrieves a description of the given attribute of the given type for a user-defined type (UDT)
   * that is available in the given schema and catalog. Descriptions are returned only for
   * attributes of UDTs matching the catalog, schema, type, and attribute name criteria. They are
   * ordered by <code>TYPE_CAT</code>, <code>TYPE_SCHEM</code>, <code>TYPE_NAME</code> and <code>
   * ORDINAL_POSITION</code>. This description does not contain inherited attributes. The <code>
   * ResultSet</code> object that is returned has the following columns:
   *
   * <OL>
   *   <li><B>TYPE_CAT</B> String {@code =>} type catalog (may be <code>null</code>)
   *   <li><B>TYPE_SCHEM</B> String {@code =>} type schema (may be <code>null</code>)
   *   <li><B>TYPE_NAME</B> String {@code =>} type name
   *   <li><B>ATTR_NAME</B> String {@code =>} attribute name
   *   <li><B>DATA_TYPE</B> int {@code =>} attribute type SQL type from java.sql.Types
   *   <li><B>ATTR_TYPE_NAME</B> String {@code =>} Data source dependent type name. For a UDT, the
   *       type name is fully qualified. For a REF, the type name is fully qualified and represents
   *       the target type of the reference type.
   *   <li><B>ATTR_SIZE</B> int {@code =>} column size. For char or date types this is the maximum
   *       number of characters; for numeric or decimal types this is precision.
   *   <li><B>DECIMAL_DIGITS</B> int {@code =>} the number of fractional digits. Null is returned
   *       for data types where DECIMAL_DIGITS is not applicable.
   *   <li><B>NUM_PREC_RADIX</B> int {@code =>} Radix (typically either 10 or 2)
   *   <li><B>NULLABLE</B> int {@code =>} whether NULL is allowed
   *       <UL>
   *         <li>attributeNoNulls - might not allow NULL values
   *         <li>attributeNullable - definitely allows NULL values
   *         <li>attributeNullableUnknown - nullability unknown
   *       </UL>
   *   <li><B>REMARKS</B> String {@code =>} comment describing column (may be <code>null</code>)
   *   <li><B>ATTR_DEF</B> String {@code =>} default value (may be<code>null</code>)
   *   <li><B>SQL_DATA_TYPE</B> int {@code =>} unused
   *   <li><B>SQL_DATETIME_SUB</B> int {@code =>} unused
   *   <li><B>CHAR_OCTET_LENGTH</B> int {@code =>} for char types the maximum number of bytes in the
   *       column
   *   <li><B>ORDINAL_POSITION</B> int {@code =>} index of the attribute in the UDT (starting at 1)
   *   <li><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
   *       a attribute.
   *       <UL>
   *         <li>YES --- if the attribute can include NULLs
   *         <li>NO --- if the attribute cannot include NULLs
   *         <li>empty string --- if the nullability for the attribute is unknown
   *       </UL>
   *   <li><B>SCOPE_CATALOG</B> String {@code =>} catalog of table that is the scope of a reference
   *       attribute (<code>null</code> if DATA_TYPE isn't REF)
   *   <li><B>SCOPE_SCHEMA</B> String {@code =>} schema of table that is the scope of a reference
   *       attribute (<code>null</code> if DATA_TYPE isn't REF)
   *   <li><B>SCOPE_TABLE</B> String {@code =>} table name that is the scope of a reference
   *       attribute (<code>null</code> if the DATA_TYPE isn't REF)
   *   <li><B>SOURCE_DATA_TYPE</B> short {@code =>} source type of a distinct type or user-generated
   *       Ref type,SQL type from java.sql.Types (<code>null</code> if DATA_TYPE isn't DISTINCT or
   *       user-generated REF)
   * </OL>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param typeNamePattern a type name pattern; must match the type name as it is stored in the
   *     database
   * @param attributeNamePattern an attribute name pattern; must match the attribute name as it is
   *     declared in the database
   * @return a <code>ResultSet</code> object in which each row is an attribute description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   * @since 1.4
   */
  public ResultSet getAttributes(
      String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern)
      throws SQLException {

    String sql =
        "SELECT ' ' TYPE_CAT, ' ' TYPE_SCHEM, ' ' TYPE_NAME, ' ' ATTR_NAME, 0 DATA_TYPE, ' '"
            + " ATTR_TYPE_NAME, 0 ATTR_SIZE, 0 DECIMAL_DIGITS, 0 NUM_PREC_RADIX, 0 NULLABLE, ' '"
            + " REMARKS, ' ' ATTR_DEF,  0 SQL_DATA_TYPE, 0 SQL_DATETIME_SUB, 0 CHAR_OCTET_LENGTH, 0"
            + " ORDINAL_POSITION, ' ' IS_NULLABLE, ' ' SCOPE_CATALOG, ' ' SCOPE_SCHEMA, ' '"
            + " SCOPE_TABLE, 0 SOURCE_DATA_TYPE FROM DUAL  WHERE 1=0";

    return executeQuery(sql);
  }

  public boolean supportsResultSetHoldability(int holdability) {
    return holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT;
  }

  public int getResultSetHoldability() {
    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
  }

  public int getDatabaseMajorVersion() {
    return connection.getContext().getVersion().getMajorVersion();
  }

  public int getDatabaseMinorVersion() {
    return connection.getContext().getVersion().getMinorVersion();
  }

  @Override
  public int getJDBCMajorVersion() {
    return 4;
  }

  @Override
  public int getJDBCMinorVersion() {
    return 2;
  }

  @Override
  public int getSQLStateType() {
    return sqlStateSQL99;
  }

  public boolean locatorsUpdateCopy() {
    return false;
  }

  public boolean supportsStatementPooling() {
    return false;
  }

  public RowIdLifetime getRowIdLifetime() {
    return RowIdLifetime.ROWID_UNSUPPORTED;
  }

  public boolean supportsStoredFunctionsUsingCallSyntax() {
    return true;
  }

  public boolean autoCommitFailureClosesAllResultSets() {
    return false;
  }

  /**
   * Retrieves a list of the client info properties that the driver supports. The result set
   * contains the following columns
   *
   * <ol>
   *   <li>NAME String : The name of the client info property
   *   <li>MAX_LEN int : The maximum length of the value for the property
   *   <li>DEFAULT_VALUE String : The default value of the property
   *   <li>DESCRIPTION String : A description of the property. This will typically contain
   *       information as to where this property is stored in the database.
   * </ol>
   *
   * <p>The ResultSet is sorted by the NAME column
   *
   * @return A ResultSet object; each row is a supported client info property
   */
  public ResultSet getClientInfoProperties() {
    String[] columnNames = new String[] {"NAME", "MAX_LEN", "DEFAULT_VALUE", "DESCRIPTION"};

    DataType[] types =
        new DataType[] {
          DataType.VARSTRING, DataType.INTEGER, DataType.VARSTRING, DataType.VARSTRING
        };
    String[][] data =
        new String[][] {
          new String[] {
            "ApplicationName",
            "16777215",
            "",
            "The name of the application currently utilizing the connection"
          },
          new String[] {
            "ClientUser",
            "16777215",
            "",
            "The name of the user that the application using the connection is performing work for."
                + " This may not be the same as the user name that was used in establishing the"
                + " connection."
          },
          new String[] {
            "ClientHostname",
            "16777215",
            "",
            "The hostname of the computer the application using the connection is running on"
          }
        };

    return CompleteResult.createResultSet(columnNames, types, data, connection.getContext(), 0);
  }

  /**
   * Retrieves a description of the system and user functions available in the given catalog. Only
   * system and user function descriptions matching the schema and function name criteria are
   * returned. They are ordered by <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>, <code>
   * FUNCTION_NAME</code> and <code>SPECIFIC_ NAME</code>.
   *
   * <p>Each function description has the following columns:
   *
   * <OL>
   *   <li><B>FUNCTION_CAT</B> String {@code =>} function catalog (may be <code>null</code>)
   *   <li><B>FUNCTION_SCHEM</B> String {@code =>} function schema (may be <code>null</code>)
   *   <li><B>FUNCTION_NAME</B> String {@code =>} function name. This is the name used to invoke the
   *       function
   *   <li><B>REMARKS</B> String {@code =>} explanatory comment on the function
   *   <li><B>FUNCTION_TYPE</B> short {@code =>} kind of function:
   *       <UL>
   *         <li>functionResultUnknown - Cannot determine if a return value or table will be
   *             returned
   *         <li>functionNoTable- Does not return a table
   *         <li>functionReturnsTable - Returns a table
   *       </UL>
   *   <li><B>SPECIFIC_NAME</B> String {@code =>} the name which uniquely identifies this function
   *       within its schema. This is a user specified, or DBMS generated, name that may be
   *       different then the <code>FUNCTION_NAME</code> for example with overload functions
   * </OL>
   *
   * <p>A user may not have permission to execute any of the functions that are returned by <code>
   * getFunctions</code>
   *
   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
   *     be used to narrow the search
   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
   *     should not be used to narrow the search
   * @param functionNamePattern a function name pattern; must match the function name as it is
   *     stored in the database
   * @return <code>ResultSet</code> - each row is a function description
   * @throws SQLException if a database access error occurs
   * @see #getSearchStringEscape
   * @since 1.6
   */
  public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
      throws SQLException {
    StringBuilder sb =
        new StringBuilder(
            "SELECT ROUTINE_SCHEMA FUNCTION_CAT,"
                + "NULL FUNCTION_SCHEM, "
                + "ROUTINE_NAME FUNCTION_NAME, "
                + "ROUTINE_COMMENT REMARKS, "
                + functionNoTable
                + " FUNCTION_TYPE, "
                + "SPECIFIC_NAME "
                + " FROM INFORMATION_SCHEMA.ROUTINES");
    boolean firstCondition = catalogCond(true, sb, "ROUTINE_SCHEMA", catalog);
    firstCondition = patternCond(firstCondition, sb, "ROUTINE_NAME", functionNamePattern);
    sb.append(firstCondition ? " WHERE " : " AND ").append(" ROUTINE_TYPE='FUNCTION'");

    return executeQuery(sb.toString());
  }

  @Override
  public <T> T unwrap(Class<T> iface) throws SQLException {
    if (isWrapperFor(iface)) {
      return iface.cast(this);
    }
    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
  }

  @Override
  public boolean isWrapperFor(Class<?> iface) {
    return iface.isInstance(this);
  }

  @Override
  public long getMaxLogicalLobSize() {
    return 4294967295L;
  }

  private static class Identifier {
    public String schema;
    public String name;
  }
}
