public ResultSet getColumns()

in src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaDataMysqlSchema.java [1423:1571]


    public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
        final String columnNameFilter = normalizeIdentifierQuoting(columnNamePattern);

        final List<Row> rows = new ArrayList<>();
        try (final Statement stmt = getJdbcConnection().getMetaDataSafeStatement()) {
            SortedMap<String, List<String>> tableNamesPerDb = new TreeMap<>();
            ResultSet tables = null;
            try {
                tables = getTables(catalog, schemaPattern, tableNamePattern, null);
                while (tables.next()) {
                    final String db = tables.getString(chooseBasedOnDatabaseTerm(() -> "TABLE_CAT", () -> "TABLE_SCHEM"));
                    List<String> tableNames = tableNamesPerDb.get(db);
                    if (tableNames == null) {
                        tableNames = new ArrayList<>();
                    }
                    tableNames.add(tables.getString("TABLE_NAME"));
                    tableNamesPerDb.put(db, tableNames);
                }
            } finally {
                if (tables != null) {
                    try {
                        tables.close();
                    } catch (Exception sqlEx) {
                        AssertionFailedException.shouldNotHappen(sqlEx);
                    }
                    tables = null;
                }
            }

            for (String dbName : tableNamesPerDb.keySet()) {
                for (String tableName : tableNamesPerDb.get(dbName)) {
                    ResultSet rs = null;
                    try {
                        StringBuilder query = new StringBuilder("SHOW FULL COLUMNS FROM ");
                        query.append(StringUtils.quoteIdentifier(tableName, getQuoteId(), true));
                        query.append(" FROM ");
                        query.append(StringUtils.quoteIdentifier(dbName, getQuoteId(), true));

                        // Find column ordinals if column name pattern is not '%'.
                        // SHOW COLUMNS does not include ordinal information so another round trip is required to return all columns in the table and compute
                        // their ordinal positions.
                        boolean fixUpOrdinalsRequired = false;
                        Map<String, Integer> ordinalFixUpMap = null;
                        if (columnNameFilter != null && !columnNameFilter.equals("%")) {
                            fixUpOrdinalsRequired = true;
                            ordinalFixUpMap = new HashMap<>();
                            rs = stmt.executeQuery(query.toString());
                            int ordinalPos = 1;
                            while (rs.next()) {
                                String columnName = rs.getString("Field");
                                ordinalFixUpMap.put(columnName, ordinalPos++);
                            }
                            rs.close();
                        }

                        if (columnNameFilter != null) {
                            query.append(" LIKE ");
                            query.append(StringUtils.quoteIdentifier(columnNameFilter, "'", true));
                        }
                        rs = stmt.executeQuery(query.toString());

                        int ordPos = 1;
                        while (rs.next()) {
                            TypeDescriptor typeDesc = new TypeDescriptor(rs.getString("Type"), rs.getString("Null"));

                            byte[][] row = new byte[24][];
                            row[0] = chooseBasedOnDatabaseTerm(() -> s2b(dbName), () -> s2b("def"));                        // TABLE_CAT
                            row[1] = chooseBasedOnDatabaseTerm(() -> null, () -> s2b(dbName));                              // TABLE_SCHEM
                            row[2] = s2b(tableName);                                                                        // TABLE_NAME
                            row[3] = rs.getBytes("Field");                                                                  // COLUMN_NAME
                            row[4] = n2b(typeDesc.getJdbcType());                                                           // DATA_TYPE
                            row[5] = s2b(typeDesc.mysqlType.getName());                                                     // TYPE_NAME
                            if (typeDesc.columnSize == null) {
                                row[6] = null;                                                                              // COLUMN_SIZE
                            } else {
                                String collation = rs.getString("Collation");
                                int mbminlen = 1;
                                if (collation != null) {
                                    // Not null collation could only be returned by server for character types, so no need to check type name.
                                    if (collation.indexOf("ucs2") > -1 || collation.indexOf("utf16") > -1) {
                                        mbminlen = 2;
                                    } else if (collation.indexOf("utf32") > -1) {
                                        mbminlen = 4;
                                    }
                                }
                                row[6] = mbminlen == 1 ? n2b(typeDesc.columnSize) : n2b(typeDesc.columnSize / mbminlen);    // COLUMN_SIZE
                            }
                            row[7] = n2b(typeDesc.bufferLength);                                                            // BUFFER_LENGTH
                            row[8] = typeDesc.decimalDigits == null ? null : n2b(typeDesc.decimalDigits);                   // DECIMAL_DIGITS
                            row[9] = n2b(typeDesc.numPrecRadix);                                                            // NUM_PREC_RADIX
                            row[10] = n2b(typeDesc.nullability);                                                            // NULLABLE
                            row[11] = rs.getBytes("Comment");                                                               // REMARKS
                            row[12] = rs.getBytes("Default");                                                               // COLUMN_DEF
                            row[13] = new byte[] { (byte) '0' };                                                            // SQL_DATA_TYPE
                            row[14] = new byte[] { (byte) '0' };                                                            // SQL_DATETIME_SUB
                            if (StringUtils.indexOfIgnoreCase(typeDesc.mysqlType.getName(), "CHAR") != -1
                                    || StringUtils.indexOfIgnoreCase(typeDesc.mysqlType.getName(), "BLOB") != -1
                                    || StringUtils.indexOfIgnoreCase(typeDesc.mysqlType.getName(), "TEXT") != -1
                                    || StringUtils.indexOfIgnoreCase(typeDesc.mysqlType.getName(), "ENUM") != -1
                                    || StringUtils.indexOfIgnoreCase(typeDesc.mysqlType.getName(), "SET") != -1
                                    || StringUtils.indexOfIgnoreCase(typeDesc.mysqlType.getName(), "BINARY") != -1) {
                                row[15] = row[6];                                                                           // CHAR_OCTET_LENGTH
                            } else {
                                row[15] = null;                                                                             // CHAR_OCTET_LENGTH
                            }
                            if (!fixUpOrdinalsRequired) {
                                row[16] = n2b(ordPos++);                                                                    // ORDINAL_POSITION
                            } else {
                                String origColName = rs.getString("Field");
                                Integer realOrdinal = ordinalFixUpMap.get(origColName);
                                if (realOrdinal != null) {
                                    row[16] = n2b(realOrdinal);                                                             // ORDINAL_POSITION
                                } else {
                                    throw SQLError.createSQLException(Messages.getString("DatabaseMetaData.10"), MysqlErrorNumbers.SQLSTATE_CONNJ_GENERAL_ERROR,
                                            getExceptionInterceptor());
                                }
                            }
                            row[17] = s2b(typeDesc.isNullable);                                                             // IS_NULLABLE
                            row[18] = null;                                                                                 // SCOPE_CATALOG
                            row[19] = null;                                                                                 // SCOPE_SCHEMA
                            row[20] = null;                                                                                 // SCOPE_TABLE
                            row[21] = null;                                                                                 // SOURCE_DATA_TYPE
                            String extra = rs.getString("Extra");
                            if (extra != null) {
                                row[22] = s2b(StringUtils.indexOfIgnoreCase(extra, "auto_increment") != -1 ? "YES" : "NO"); // IS_AUTOINCREMENT
                                row[23] = s2b(StringUtils.indexOfIgnoreCase(extra, "generated") != -1 ? "YES" : "NO");      // IS_GENERATEDCOLUMN
                            } else {
                                row[22] = s2b("");                                                                          // IS_AUTOINCREMENT
                                row[23] = s2b("");                                                                          // IS_GENERATEDCOLUMN
                            }

                            rows.add(new ByteArrayRow(row, getExceptionInterceptor()));
                        }
                    } finally {
                        if (rs != null) {
                            try {
                                rs.close();
                            } catch (Exception e) {
                            }
                            rs = null;
                        }
                    }
                }
            }
        }

        return getResultSetFactory().createFromResultsetRows(ResultSet.CONCUR_READ_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE,
                new ResultsetRowsStatic(rows, new DefaultColumnDefinition(createColumnsFields())));
    }