void forEach()

in src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaData.java [2071:2244]


                void forEach(String dbStr) throws SQLException {

                    ArrayList<String> tableNameList = new ArrayList<>();

                    java.sql.ResultSet tables = null;

                    try {
                        tables = dbMapsToSchema ? getTables(null, dbStr, tableNamePattern, new String[0])
                                : getTables(dbStr, schemaPattern, tableNamePattern, new String[0]);

                        while (tables.next()) {
                            String tableNameFromList = tables.getString("TABLE_NAME");
                            tableNameList.add(tableNameFromList);
                        }
                    } finally {
                        if (tables != null) {
                            try {
                                tables.close();
                            } catch (Exception sqlEx) {
                                AssertionFailedException.shouldNotHappen(sqlEx);
                            }

                            tables = null;
                        }
                    }

                    for (String tableName : tableNameList) {

                        ResultSet results = null;

                        try {
                            StringBuilder queryBuf = new StringBuilder("SHOW FULL COLUMNS FROM ");
                            queryBuf.append(StringUtils.quoteIdentifier(tableName, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.pedantic));
                            queryBuf.append(" FROM ");
                            queryBuf.append(StringUtils.quoteIdentifier(dbStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.pedantic));
                            if (colPattern != null) {
                                queryBuf.append(" LIKE ");
                                queryBuf.append(StringUtils.quoteIdentifier(colPattern, "'", true));
                            }

                            // Return correct ordinals if column name pattern is not '%'
                            // Currently, MySQL doesn't show enough data to do this, so we do it the 'hard' way...Once _SYSTEM tables are in, this should be
                            // much easier
                            boolean fixUpOrdinalsRequired = false;
                            Map<String, Integer> ordinalFixUpMap = null;

                            if (colPattern != null && !colPattern.equals("%")) {
                                fixUpOrdinalsRequired = true;

                                StringBuilder fullColumnQueryBuf = new StringBuilder("SHOW FULL COLUMNS FROM ");
                                fullColumnQueryBuf
                                        .append(StringUtils.quoteIdentifier(tableName, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.pedantic));
                                fullColumnQueryBuf.append(" FROM ");
                                fullColumnQueryBuf.append(StringUtils.quoteIdentifier(dbStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.pedantic));

                                results = stmt.executeQuery(fullColumnQueryBuf.toString());

                                ordinalFixUpMap = new HashMap<>();

                                int fullOrdinalPos = 1;

                                while (results.next()) {
                                    String fullOrdColName = results.getString("Field");

                                    ordinalFixUpMap.put(fullOrdColName, Integer.valueOf(fullOrdinalPos++));
                                }
                                results.close();
                            }

                            results = stmt.executeQuery(queryBuf.toString());

                            int ordPos = 1;

                            while (results.next()) {
                                TypeDescriptor typeDesc = new TypeDescriptor(results.getString("Type"), results.getString("Null"));

                                byte[][] rowVal = new byte[24][];
                                rowVal[0] = DatabaseMetaData.this.databaseTerm.getValue() == DatabaseTerm.SCHEMA ? s2b("def") : s2b(dbStr);    // TABLE_CAT
                                rowVal[1] = DatabaseMetaData.this.databaseTerm.getValue() == DatabaseTerm.SCHEMA ? s2b(dbStr) : null;          // TABLE_SCHEM
                                rowVal[2] = s2b(tableName);                     // TABLE_NAME
                                rowVal[3] = results.getBytes("Field");
                                rowVal[4] = Short.toString((short) typeDesc.mysqlType.getJdbcType()).getBytes();// DATA_TYPE (jdbc)
                                rowVal[5] = s2b(typeDesc.mysqlType.getName());  // TYPE_NAME (native)
                                if (typeDesc.columnSize == null) {              // COLUMN_SIZE
                                    rowVal[6] = null;
                                } else {
                                    String collation = results.getString("Collation");
                                    int mbminlen = 1;
                                    if (collation != null) {
                                        // not null collation could only be returned by server for character types, so we don't need to check type name
                                        if (collation.indexOf("ucs2") > -1 || collation.indexOf("utf16") > -1) {
                                            mbminlen = 2;
                                        } else if (collation.indexOf("utf32") > -1) {
                                            mbminlen = 4;
                                        }
                                    }
                                    rowVal[6] = mbminlen == 1 ? s2b(typeDesc.columnSize.toString())
                                            : s2b(((Integer) (typeDesc.columnSize / mbminlen)).toString());
                                }
                                rowVal[7] = s2b(Integer.toString(typeDesc.bufferLength));
                                rowVal[8] = typeDesc.decimalDigits == null ? null : s2b(typeDesc.decimalDigits.toString());
                                rowVal[9] = s2b(Integer.toString(typeDesc.numPrecRadix));
                                rowVal[10] = s2b(Integer.toString(typeDesc.nullability));

                                //
                                // Doesn't always have this field, depending on version
                                //
                                try {
                                    rowVal[11] = results.getBytes("Comment");   // REMARK column
                                } catch (Exception E) {
                                    rowVal[11] = new byte[0];                   // REMARK column
                                }

                                rowVal[12] = results.getBytes("Default");       // COLUMN_DEF
                                rowVal[13] = new byte[] { (byte) '0' };         // SQL_DATA_TYPE
                                rowVal[14] = new byte[] { (byte) '0' };         // SQL_DATE_TIME_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) {
                                    rowVal[15] = rowVal[6];                     // CHAR_OCTET_LENGTH
                                } else {
                                    rowVal[15] = null;
                                }

                                // ORDINAL_POSITION
                                if (!fixUpOrdinalsRequired) {
                                    rowVal[16] = Integer.toString(ordPos++).getBytes();
                                } else {
                                    String origColName = results.getString("Field");
                                    Integer realOrdinal = ordinalFixUpMap.get(origColName);

                                    if (realOrdinal != null) {
                                        rowVal[16] = realOrdinal.toString().getBytes();
                                    } else {
                                        throw SQLError.createSQLException(Messages.getString("DatabaseMetaData.10"), MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR,
                                                getExceptionInterceptor());
                                    }
                                }

                                rowVal[17] = s2b(typeDesc.isNullable);

                                // We don't support REF or DISTINCT types
                                rowVal[18] = null;
                                rowVal[19] = null;
                                rowVal[20] = null;
                                rowVal[21] = null;

                                rowVal[22] = s2b("");

                                String extra = results.getString("Extra");

                                if (extra != null) {
                                    rowVal[22] = s2b(StringUtils.indexOfIgnoreCase(extra, "auto_increment") != -1 ? "YES" : "NO");
                                    rowVal[23] = s2b(StringUtils.indexOfIgnoreCase(extra, "generated") != -1 ? "YES" : "NO");
                                }

                                rows.add(new ByteArrayRow(rowVal, getExceptionInterceptor()));
                            }
                        } finally {
                            if (results != null) {
                                try {
                                    results.close();
                                } catch (Exception ex) {
                                }

                                results = null;
                            }
                        }
                    }
                }