~ubuntu-branches/ubuntu/trusty/mysql-connector-java/trusty

« back to all changes in this revision

Viewing changes to src/com/mysql/jdbc/DatabaseMetaData.java

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2013-11-06 23:49:02 UTC
  • mfrom: (1.1.10) (3.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20131106234902-fhupetvkmt34mg01
Tags: 5.1.27-1
* New upstream release
* Refreshed the patches
* Updated Standards-Version to 3.9.5 (no changes)
* Use XZ compression for the upstream tarball
* Switch to debhelper level 9

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 */
22
22
package com.mysql.jdbc;
23
23
 
 
24
import static com.mysql.jdbc.DatabaseMetaData.ProcedureType.FUNCTION;
 
25
import static com.mysql.jdbc.DatabaseMetaData.ProcedureType.PROCEDURE;
 
26
 
24
27
import java.io.UnsupportedEncodingException;
25
28
import java.lang.reflect.Constructor;
26
29
import java.sql.ResultSet;
426
429
        /**
427
430
         * Helper class to provide means of comparing indexes by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
428
431
         */
429
 
        protected class IndexInfoKeyComparable implements Comparable<IndexInfoKeyComparable> {
 
432
        protected class IndexMetaDataKey implements Comparable<IndexMetaDataKey> {
430
433
                Boolean columnNonUnique;
431
434
                Short columnType;
432
435
                String columnIndexName;
433
436
                Short columnOrdinalPosition;
434
437
 
435
 
                IndexInfoKeyComparable(boolean columnNonUnique, short columnType, String columnIndexName,
 
438
                IndexMetaDataKey(boolean columnNonUnique, short columnType, String columnIndexName,
436
439
                                short columnOrdinalPosition) {
437
440
                        this.columnNonUnique = columnNonUnique;
438
441
                        this.columnType = columnType;
440
443
                        this.columnOrdinalPosition = columnOrdinalPosition;
441
444
                }
442
445
 
443
 
                public int compareTo(IndexInfoKeyComparable indexInfoKey) {
 
446
                public int compareTo(IndexMetaDataKey indexInfoKey) {
444
447
                        int compareResult;
445
448
 
446
449
                        if ((compareResult = columnNonUnique.compareTo(indexInfoKey.columnNonUnique)) != 0) {
454
457
                        }
455
458
                        return columnOrdinalPosition.compareTo(indexInfoKey.columnOrdinalPosition);
456
459
                }
 
460
 
 
461
                @Override
 
462
                public boolean equals(Object obj) {
 
463
                        if (obj == null) {
 
464
                                return false;
 
465
                        }
 
466
 
 
467
                        if (obj == this) {
 
468
                                return true;
 
469
                        }
 
470
 
 
471
                        if (!(obj instanceof IndexMetaDataKey)) {
 
472
                                return false;
 
473
                        }
 
474
                        return compareTo((IndexMetaDataKey) obj) == 0;
 
475
                }
 
476
        }
 
477
 
 
478
        /**
 
479
         * Helper class to provide means of comparing tables by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM and TABLE_NAME.
 
480
         */
 
481
        protected class TableMetaDataKey implements Comparable<TableMetaDataKey> {
 
482
                String tableType;
 
483
                String tableCat;
 
484
                String tableSchem;
 
485
                String tableName;
 
486
 
 
487
                TableMetaDataKey(String tableType, String tableCat, String tableSchem, String tableName) {
 
488
                        this.tableType = tableType == null ? "" : tableType;
 
489
                        this.tableCat = tableCat == null ? "" : tableCat;
 
490
                        this.tableSchem = tableSchem == null ? "" : tableSchem;
 
491
                        this.tableName = tableName == null ? "" : tableName;
 
492
                }
 
493
 
 
494
                public int compareTo(TableMetaDataKey tablesKey) {
 
495
                        int compareResult;
 
496
 
 
497
                        if ((compareResult = tableType.compareTo(tablesKey.tableType)) != 0) {
 
498
                                return compareResult;
 
499
                        }
 
500
                        if ((compareResult = tableCat.compareTo(tablesKey.tableCat)) != 0) {
 
501
                                return compareResult;
 
502
                        }
 
503
                        if ((compareResult = tableSchem.compareTo(tablesKey.tableSchem)) != 0) {
 
504
                                return compareResult;
 
505
                        }
 
506
                        return tableName.compareTo(tablesKey.tableName);
 
507
                }
 
508
 
 
509
                @Override
 
510
                public boolean equals(Object obj) {
 
511
                        if (obj == null) {
 
512
                                return false;
 
513
                        }
 
514
 
 
515
                        if (obj == this) {
 
516
                                return true;
 
517
                        }
 
518
 
 
519
                        if (!(obj instanceof TableMetaDataKey)) {
 
520
                                return false;
 
521
                        }
 
522
                        return compareTo((TableMetaDataKey) obj) == 0;
 
523
                }
 
524
        }
 
525
 
 
526
        /**
 
527
         * Helper/box class to provide means of sorting objects by using a sorting key.
 
528
         */
 
529
        protected class ComparableWrapper<K extends Object & Comparable<? super K>, V> implements
 
530
                        Comparable<ComparableWrapper<K, V>> {
 
531
                K key;
 
532
                V value;
 
533
 
 
534
                public ComparableWrapper(K key, V value) {
 
535
                        this.key = key;
 
536
                        this.value = value;
 
537
                }
 
538
 
 
539
                public K getKey() {
 
540
                        return key;
 
541
                }
 
542
 
 
543
                public V getValue() {
 
544
                        return value;
 
545
                }
 
546
 
 
547
                public int compareTo(ComparableWrapper<K, V> other) {
 
548
                        return getKey().compareTo(other.getKey());
 
549
                }
 
550
 
 
551
                @Override
 
552
                public boolean equals(Object obj) {
 
553
                        if (obj == null) {
 
554
                                return false;
 
555
                        }
 
556
 
 
557
                        if (obj == this) {
 
558
                                return true;
 
559
                        }
 
560
 
 
561
                        if (!(obj instanceof ComparableWrapper<?, ?>)) {
 
562
                                return false;
 
563
                        }
 
564
 
 
565
                        Object otherKey = ((ComparableWrapper<?, ?>) obj).getKey();
 
566
                        return key.equals(otherKey);
 
567
                }
 
568
 
 
569
                @Override
 
570
                public String toString() {
 
571
                        return "{KEY:" + key + "; VALUE:" + value +"}";
 
572
                }
 
573
        }
 
574
 
 
575
        /**
 
576
         * Enumeration for Table Types
 
577
         */
 
578
        protected enum TableType {
 
579
                LOCAL_TEMPORARY("LOCAL TEMPORARY"), SYSTEM_TABLE("SYSTEM TABLE"), SYSTEM_VIEW("SYSTEM VIEW"), TABLE("TABLE",
 
580
                                new String[] { "BASE TABLE" }), VIEW("VIEW"), UNKNOWN("UNKNOWN");
 
581
 
 
582
                private String name;
 
583
                private byte[] nameAsBytes;
 
584
                private String[] synonyms;
 
585
 
 
586
                TableType(String tableTypeName) {
 
587
                        this(tableTypeName, null);
 
588
                }
 
589
 
 
590
                TableType(String tableTypeName, String[] tableTypeSynonyms) {
 
591
                        name = tableTypeName;
 
592
                        nameAsBytes = tableTypeName.getBytes();
 
593
                        synonyms = tableTypeSynonyms;
 
594
                }
 
595
 
 
596
                String getName() {
 
597
                        return name;
 
598
                }
 
599
                
 
600
                byte[] asBytes() {
 
601
                        return nameAsBytes;
 
602
                }
 
603
 
 
604
                boolean equalsTo(String tableTypeName) {
 
605
                        return name.equalsIgnoreCase(tableTypeName);
 
606
                }
 
607
 
 
608
                static TableType getTableTypeEqualTo(String tableTypeName) {
 
609
                        for (TableType tableType : TableType.values()) {
 
610
                                if (tableType.equalsTo(tableTypeName)) {
 
611
                                        return tableType;
 
612
                                }
 
613
                        }
 
614
                        return UNKNOWN;
 
615
                }
 
616
                
 
617
                boolean compliesWith(String tableTypeName) {
 
618
                        if (equalsTo(tableTypeName)) {
 
619
                                return true;
 
620
                        }
 
621
                        if (synonyms != null) {
 
622
                                for (String synonym : synonyms) {
 
623
                                        if (synonym.equalsIgnoreCase(tableTypeName)) {
 
624
                                                return true;
 
625
                                        }
 
626
                                }
 
627
                        }
 
628
                        return false;
 
629
                }
 
630
 
 
631
                static TableType getTableTypeCompliantWith(String tableTypeName) {
 
632
                        for (TableType tableType : TableType.values()) {
 
633
                                if (tableType.compliesWith(tableTypeName)) {
 
634
                                        return tableType;
 
635
                                }
 
636
                        }
 
637
                        return UNKNOWN;
 
638
                }
 
639
        }
 
640
 
 
641
        /**
 
642
         * Enumeration for Procedure Types
 
643
         */
 
644
        protected enum ProcedureType {
 
645
                PROCEDURE, FUNCTION;
457
646
        }
458
647
        
459
648
        private static String mysqlKeywordsThatArentSQL92;
460
 
        
 
649
 
461
650
        protected static final int MAX_IDENTIFIER_LENGTH = 64;
462
 
        
 
651
 
463
652
        private static final int DEFERRABILITY = 13;
464
653
 
465
654
        private static final int DELETE_RULE = 10;
529
718
                        JDBC_4_DBMD_SHOW_CTOR = null;
530
719
                }
531
720
                
532
 
                // Current as-of MySQL-5.5.8
533
721
                String[] allMySQLKeywords = new String[] { "ACCESSIBLE", "ADD", "ALL",
534
722
                                "ALTER", "ANALYZE", "AND", "AS", "ASC", "ASENSITIVE", "BEFORE",
535
 
                                "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOTH", "BY", "CALL",
 
723
                                "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOOLEAN", "BOTH", "BY", "CALL",
536
724
                                "CASCADE", "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK",
537
725
                                "COLLATE", "COLUMN", "CONDITION", "CONNECTION", "CONSTRAINT",
538
726
                                "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT_DATE",
542
730
                                "DEFAULT", "DELAYED", "DELETE", "DESC", "DESCRIBE",
543
731
                                "DETERMINISTIC", "DISTINCT", "DISTINCTROW", "DIV", "DOUBLE",
544
732
                                "DROP", "DUAL", "EACH", "ELSE", "ELSEIF", "ENCLOSED",
545
 
                                "ESCAPED", "EXISTS", "EXIT", "EXPLAIN", "FALSE", "FETCH",
 
733
                                "ESCAPED", "EXISTS", "EXIT", "EXPANSION", "EXPLAIN", "FALSE", "FETCH",
546
734
                                "FLOAT", "FLOAT4", "FLOAT8", "FOR", "FORCE", "FOREIGN", "FROM",
547
735
                                "FULLTEXT", "GRANT", "GROUP", "HAVING", "HIGH_PRIORITY",
548
736
                                "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF",
554
742
                                "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT",
555
743
                                "LOOP", "LOW_PRIORITY", "MATCH", "MEDIUMBLOB", "MEDIUMINT",
556
744
                                "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND",
557
 
                                "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", "NOT",
 
745
                                "MINUTE_SECOND", "MOD", "MODE", "MODIFIES", "NATURAL", "NOT",
558
746
                                "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE",
559
747
                                "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER",
560
 
                                "OUTFILE", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE",
 
748
                                "OUTFILE", "QUERY", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE",
561
749
                                "RANGE", "READ", "READS", "READ_ONLY", "READ_WRITE", "REAL",
562
750
                                "REFERENCES", "REGEXP", "RELEASE", "RENAME", "REPEAT",
563
751
                                "REPLACE", "REQUIRE", "RESTRICT", "RETURN", "REVOKE", "RIGHT",
777
965
 
778
966
        protected void convertToJdbcFunctionList(String catalog,
779
967
                        ResultSet proceduresRs, boolean needsClientFiltering, String db,
780
 
                        Map<String, ResultSetRow> procedureRowsOrderedByName, int nameIndex,
 
968
                        List<ComparableWrapper<String, ResultSetRow>> procedureRows, int nameIndex,
781
969
                        Field[] fields) throws SQLException {
782
970
                while (proceduresRs.next()) {
783
971
                        boolean shouldAdd = true;
823
1011
                                        rowData[5] = s2b(functionName);                      // SPECFIC NAME
824
1012
                                }
825
1013
 
826
 
                                procedureRowsOrderedByName.put(functionName, new ByteArrayRow(rowData, getExceptionInterceptor()));
 
1014
                                procedureRows.add(new ComparableWrapper<String, ResultSetRow>(functionName, new ByteArrayRow(rowData,
 
1015
                                                getExceptionInterceptor())));
827
1016
                        }
828
1017
                }
829
1018
        }
840
1029
        
841
1030
        protected void convertToJdbcProcedureList(boolean fromSelect, String catalog,
842
1031
                        ResultSet proceduresRs, boolean needsClientFiltering, String db,
843
 
                        Map<String, ResultSetRow> procedureRowsOrderedByName, int nameIndex) throws SQLException {
 
1032
                        List<ComparableWrapper<String, ResultSetRow>> procedureRows, int nameIndex) throws SQLException {
844
1033
                while (proceduresRs.next()) {
845
1034
                        boolean shouldAdd = true;
846
1035
 
876
1065
 
877
1066
                                rowData[8] = s2b(procedureName);
878
1067
                                
879
 
                                procedureRowsOrderedByName.put(procedureName, new ByteArrayRow(rowData, getExceptionInterceptor()));
 
1068
                                procedureRows.add(new ComparableWrapper<String, ResultSetRow>(procedureName, new ByteArrayRow(rowData,
 
1069
                                                getExceptionInterceptor())));
880
1070
                        }
881
1071
                }
882
1072
        }
1549
1739
         * 
1550
1740
         * @see #getSearchStringEscape
1551
1741
         */
1552
 
        protected void getCallStmtParameterTypes(String catalog, String procName,
 
1742
        protected void getCallStmtParameterTypes(String catalog, String procName, ProcedureType procType,
1553
1743
                        String parameterNamePattern, List<ResultSetRow> resultRows) throws SQLException {
1554
 
                getCallStmtParameterTypes(catalog, procName, 
 
1744
                getCallStmtParameterTypes(catalog, procName, procType,
1555
1745
                                parameterNamePattern, resultRows, false);
1556
1746
        }
1557
1747
        
1558
 
        private void getCallStmtParameterTypes(String catalog, String procName,
 
1748
        private void getCallStmtParameterTypes(String catalog, String procName, ProcedureType procType,
1559
1749
                        String parameterNamePattern, List<ResultSetRow> resultRows, 
1560
1750
                        boolean forGetFunctionColumns) throws SQLException {
1561
1751
                java.sql.Statement paramRetrievalStmt = null;
1687
1877
                                procNameBuf.append(quoteChar);
1688
1878
                        }
1689
1879
 
1690
 
                        boolean parsingFunction = false;
1691
 
 
1692
 
                        try {
1693
 
                                paramRetrievalRs = paramRetrievalStmt
1694
 
                                                .executeQuery("SHOW CREATE PROCEDURE "
1695
 
                                                                + procNameBuf.toString());
1696
 
                                parsingFunction = false;
1697
 
                        } catch (SQLException sqlEx) {
1698
 
                                paramRetrievalRs = paramRetrievalStmt
1699
 
                                                .executeQuery("SHOW CREATE FUNCTION "
1700
 
                                                                + procNameBuf.toString());
1701
 
                                parsingFunction = true;
 
1880
                        String fieldName = null;
 
1881
                        if (procType == PROCEDURE) {
 
1882
                                paramRetrievalRs = paramRetrievalStmt.executeQuery("SHOW CREATE PROCEDURE " + procNameBuf.toString());
 
1883
                                fieldName = "Create Procedure";
 
1884
                        } else {
 
1885
                                paramRetrievalRs = paramRetrievalStmt.executeQuery("SHOW CREATE FUNCTION " + procNameBuf.toString());
 
1886
                                fieldName = "Create Function";
1702
1887
                        }
1703
1888
 
1704
1889
                        if (paramRetrievalRs.next()) {
1705
 
                                String procedureDef = parsingFunction ? paramRetrievalRs
1706
 
                                                .getString("Create Function") : paramRetrievalRs
1707
 
                                                .getString("Create Procedure");
 
1890
                                String procedureDef = paramRetrievalRs.getString(fieldName);
1708
1891
                                                
1709
1892
                                if (!this.conn.getNoAccessToProcedureBodies() &&
1710
1893
                                                (procedureDef == null || procedureDef.length() == 0)) {
1743
1926
                                        endOfParamDeclarationIndex = endPositionOfParameterDeclaration(
1744
1927
                                                        openParenIndex, procedureDef, quoteChar);
1745
1928
 
1746
 
                                        if (parsingFunction) {
 
1929
                                        if (procType == FUNCTION) {
1747
1930
 
1748
1931
                                                // Grab the return column since it needs
1749
1932
                                                // to go first in the output result set
3621
3804
 
3622
3805
                Field[] fields = createIndexInfoFields();
3623
3806
 
3624
 
                final SortedMap<IndexInfoKeyComparable, ResultSetRow> sortedRows = new TreeMap<IndexInfoKeyComparable, ResultSetRow>();
 
3807
                final SortedMap<IndexMetaDataKey, ResultSetRow> sortedRows = new TreeMap<IndexMetaDataKey, ResultSetRow>();
3625
3808
                final ArrayList<ResultSetRow> rows = new ArrayList<ResultSetRow>();
3626
3809
                final Statement stmt = this.conn.getMetadataSafeStatement();
3627
3810
 
3688
3871
                                                        row[11] = s2b("0");
3689
3872
                                                        row[12] = null;
3690
3873
 
3691
 
                                                        IndexInfoKeyComparable indexInfoKey = new IndexInfoKeyComparable(!indexIsUnique, indexType,
 
3874
                                                        IndexMetaDataKey indexInfoKey = new IndexMetaDataKey(!indexIsUnique, indexType,
3692
3875
                                                                        results.getString("Key_name").toLowerCase(), results.getShort("Seq_in_index"));
3693
3876
                                                        
3694
3877
                                                        if (unique) {
4228
4411
                        String columnNamePattern, boolean returnProcedures,
4229
4412
                        boolean returnFunctions) throws SQLException {
4230
4413
 
4231
 
                List<String> proceduresToExtractList = new ArrayList<String>();
 
4414
                List<ComparableWrapper<String, ProcedureType>> procsOrFuncsToExtractList = new ArrayList<ComparableWrapper<String, ProcedureType>>();
4232
4415
                //Main container to be passed to getProceduresAndOrFunctions
4233
 
                ResultSet procedureNameRs = null;
 
4416
                ResultSet procsAndOrFuncsRs = null;
4234
4417
                
4235
4418
                if (supportsStoredProcedures()) {
4236
4419
                        try {
4262
4445
                                        }
4263
4446
                                }
4264
4447
                                
4265
 
                                procedureNameRs = getProceduresAndOrFunctions(
 
4448
                                procsAndOrFuncsRs = getProceduresAndOrFunctions(
4266
4449
                                                createFieldMetadataForGetProcedures(),
4267
4450
                                                catalog, schemaPattern,
4268
4451
                                                tmpProcedureOrFunctionNamePattern, returnProcedures,
4278
4461
                                String tmpstrCatNameRs = null;
4279
4462
 
4280
4463
                                boolean hasResults = false;
4281
 
                                while (procedureNameRs.next()) {
4282
 
                                        tmpstrCatNameRs = procedureNameRs.getString(1);
4283
 
                                        tmpstrPNameRs = procedureNameRs.getString(3);
 
4464
                                while (procsAndOrFuncsRs.next()) {
 
4465
                                        tmpstrCatNameRs = procsAndOrFuncsRs.getString(1);
 
4466
                                        tmpstrPNameRs = procsAndOrFuncsRs.getString(3);
4284
4467
                                        
4285
4468
                                        if (!((tmpstrCatNameRs.startsWith(this.quotedId) && tmpstrCatNameRs.endsWith(this.quotedId)) || 
4286
4469
                                                        (tmpstrCatNameRs.startsWith("\"") && tmpstrCatNameRs.endsWith("\"")))) {
4291
4474
                                                tmpstrPNameRs = this.quotedId + tmpstrPNameRs + this.quotedId;
4292
4475
                                        }
4293
4476
 
4294
 
                                        if (proceduresToExtractList.indexOf(tmpstrCatNameRs + "." + tmpstrPNameRs) < 0) {
4295
 
                                                proceduresToExtractList.add(tmpstrCatNameRs + "." + tmpstrPNameRs);
4296
 
                                        }
 
4477
                                        procsOrFuncsToExtractList.add(new ComparableWrapper<String, ProcedureType>(
 
4478
                                                        tmpstrCatNameRs + "." + tmpstrPNameRs,
 
4479
                                                        procsAndOrFuncsRs.getShort(8) == procedureNoResult ? PROCEDURE
 
4480
                                                                        : FUNCTION));
4297
4481
                                        hasResults = true;
4298
4482
                                }
4299
4483
 
4305
4489
//                                                      "to have driver generate parameters that represent INOUT strings irregardless of actual parameter types.",
4306
4490
//                                                      SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());           
4307
4491
                                } else {
4308
 
                                        Collections.sort(proceduresToExtractList);                                      
 
4492
                                        Collections.sort(procsOrFuncsToExtractList);                                    
4309
4493
                                }
4310
4494
 
4311
4495
                                // Required to be sorted in name-order by JDBC spec,
4316
4500
                        } finally {
4317
4501
                                SQLException rethrowSqlEx = null;
4318
4502
 
4319
 
                                if (procedureNameRs != null) {
 
4503
                                if (procsAndOrFuncsRs != null) {
4320
4504
                                        try {
4321
 
                                                procedureNameRs.close();
 
4505
                                                procsAndOrFuncsRs.close();
4322
4506
                                        } catch (SQLException sqlEx) {
4323
4507
                                                rethrowSqlEx = sqlEx;
4324
4508
                                        }
4334
4518
                int idx = 0;
4335
4519
                String procNameToCall = "";
4336
4520
                
4337
 
                for (Iterator<String> iter = proceduresToExtractList.iterator(); iter.hasNext();) {
4338
 
                        String procName = iter.next();
 
4521
                for (ComparableWrapper<String, ProcedureType> procOrFunc : procsOrFuncsToExtractList) {
 
4522
                        String procName = procOrFunc.getKey();
 
4523
                        ProcedureType procType = procOrFunc.getValue();
4339
4524
 
4340
4525
                        //Continuing from above (database_name.sp_name)
4341
4526
                        if (!" ".equals(this.quotedId)) {
4356
4541
                                //No catalog. Not sure how to handle right now...
4357
4542
                                procNameToCall = procName;
4358
4543
                        }
4359
 
                        getCallStmtParameterTypes(catalog, procNameToCall, columnNamePattern,
4360
 
                                        resultRows, 
 
4544
                        getCallStmtParameterTypes(catalog, procNameToCall, procType, columnNamePattern,
 
4545
                                        resultRows,
4361
4546
                                        fields.length == 17 /* for getFunctionColumns */);
4362
4547
                }
4363
4548
 
4462
4647
                if (supportsStoredProcedures()) {
4463
4648
                        final String procNamePattern = procedureNamePattern;
4464
4649
 
4465
 
                        final Map<String, ResultSetRow> procedureRowsOrderedByName = new TreeMap<String, ResultSetRow>();
 
4650
                        final List<ComparableWrapper<String, ResultSetRow>> procedureRowsToSort = new ArrayList<ComparableWrapper<String, ResultSetRow>>();
4466
4651
 
4467
4652
                        new IterateBlock<String>(getCatalogIterator(catalog)) {
4468
4653
                                void forEach(String catalogStr) throws SQLException {
4480
4665
                                        } else if (!returnProcedures && returnFunctions) {
4481
4666
                                                selectFromMySQLProcSQL.append("type = 'FUNCTION' and ");
4482
4667
                                        }
4483
 
                                        selectFromMySQLProcSQL.append("name like ? and db <=> ? ORDER BY name");
 
4668
                                        selectFromMySQLProcSQL.append("name like ? and db <=> ? ORDER BY name, type");
4484
4669
 
4485
4670
                                        java.sql.PreparedStatement proceduresStmt = conn.clientPrepareStatement(selectFromMySQLProcSQL
4486
4671
                                                        .toString());
4547
4732
                                                if (returnProcedures) {
4548
4733
                                                        convertToJdbcProcedureList(fromSelect, db,
4549
4734
                                                                proceduresRs, needsClientFiltering, db,
4550
 
                                                                procedureRowsOrderedByName, nameIndex);
 
4735
                                                                procedureRowsToSort, nameIndex);
4551
4736
                                                }
4552
4737
 
4553
4738
                                                if (!hasTypeColumn) {
4572
4757
                                                if (returnFunctions) {
4573
4758
                                                        convertToJdbcFunctionList(db, proceduresRs,
4574
4759
                                                                needsClientFiltering, db,
4575
 
                                                                procedureRowsOrderedByName, nameIndex,
 
4760
                                                                procedureRowsToSort, nameIndex,
4576
4761
                                                                fields);
4577
4762
                                                }
4578
4763
 
4579
4764
                                                // Now, sort them
4580
 
 
4581
 
                                                Iterator<ResultSetRow> proceduresIter = procedureRowsOrderedByName
4582
 
                                                                .values().iterator();
4583
 
 
4584
 
                                                while (proceduresIter.hasNext()) {
4585
 
                                                        procedureRows.add(proceduresIter.next());
 
4765
                                                Collections.sort(procedureRowsToSort);
 
4766
                                                for (ComparableWrapper<String, ResultSetRow> procRow : procedureRowsToSort) {
 
4767
                                                        procedureRows.add(procRow.getValue());
4586
4768
                                                }
4587
4769
                                        } finally {
4588
4770
                                                SQLException rethrowSqlEx = null;
5049
5231
                        }
5050
5232
                }
5051
5233
 
 
5234
                final SortedMap<TableMetaDataKey, ResultSetRow> sortedRows = new TreeMap<TableMetaDataKey, ResultSetRow>();
5052
5235
                final ArrayList<ResultSetRow> tuples = new ArrayList<ResultSetRow>();
5053
5236
 
5054
5237
                final Statement stmt = this.conn.getMetadataSafeStatement();
5073
5256
                        tableNamePat = tableNamePattern;
5074
5257
                }
5075
5258
 
5076
 
                final boolean operatingOnInformationSchema = "information_schema".equalsIgnoreCase(catalog);
5077
 
                
5078
5259
                try {
5079
 
 
5080
5260
                        new IterateBlock<String>(getCatalogIterator(catalog)) {
5081
5261
                                void forEach(String catalogStr) throws SQLException {
 
5262
                                        boolean operatingOnSystemDB = "information_schema".equalsIgnoreCase(catalogStr)
 
5263
                                                        || "mysql".equalsIgnoreCase(catalogStr)
 
5264
                                                        || "performance_schema".equalsIgnoreCase(catalogStr);
 
5265
 
5082
5266
                                        ResultSet results = null;
5083
5267
 
5084
5268
                                        try {
5085
5269
 
5086
 
                                                if (!conn.versionMeetsMinimum(5, 0, 2)) {
5087
 
                                                        try {
5088
 
                                                                results = stmt
5089
 
                                                                        .executeQuery("SHOW TABLES FROM "
5090
 
                                                                                        + StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())
5091
 
                                                                                        + " LIKE '" + tableNamePat + "'");
5092
 
                                                        } catch (SQLException sqlEx) {
5093
 
                                                                if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlEx.getSQLState())) {
5094
 
                                                                        throw sqlEx;
5095
 
                                                                }
5096
 
                                                                
5097
 
                                                                return;
5098
 
                                                        }
5099
 
                                                } else {
5100
 
                                                        try {
5101
 
                                                                results = stmt
5102
 
                                                                        .executeQuery("SHOW FULL TABLES FROM "
5103
 
                                                                                        + StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())
5104
 
                                                                                        + " LIKE '" + tableNamePat + "'");
5105
 
                                                        } catch (SQLException sqlEx) {
5106
 
                                                                if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlEx.getSQLState())) {
5107
 
                                                                        throw sqlEx;
5108
 
                                                                }
5109
 
                                                                
5110
 
                                                                return;
5111
 
                                                        }
 
5270
                                                try {
 
5271
                                                        results = stmt.executeQuery((!conn.versionMeetsMinimum(5, 0, 2) ? "SHOW TABLES FROM "
 
5272
                                                                        : "SHOW FULL TABLES FROM ")
 
5273
                                                                        + StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())
 
5274
                                                                        + " LIKE '"
 
5275
                                                                        + tableNamePat + "'");
 
5276
                                                } catch (SQLException sqlEx) {
 
5277
                                                        if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlEx.getSQLState())) {
 
5278
                                                                throw sqlEx;
 
5279
                                                        }
 
5280
 
 
5281
                                                        return;
5112
5282
                                                }
5113
5283
 
5114
5284
                                                boolean shouldReportTables = false;
5115
5285
                                                boolean shouldReportViews = false;
5116
5286
                                                boolean shouldReportSystemTables = false;
 
5287
                                                boolean shouldReportSystemViews = false;
 
5288
                                                boolean shouldReportLocalTemporaries = false;
5117
5289
                                                
5118
5290
                                                if (types == null || types.length == 0) {
5119
5291
                                                        shouldReportTables = true;
5120
5292
                                                        shouldReportViews = true;
5121
5293
                                                        shouldReportSystemTables = true;
 
5294
                                                        shouldReportSystemViews = true;
 
5295
                                                        shouldReportLocalTemporaries = true;
5122
5296
                                                } else {
5123
5297
                                                        for (int i = 0; i < types.length; i++) {
5124
 
                                                                if ("TABLE".equalsIgnoreCase(types[i])) {
 
5298
                                                                if (TableType.TABLE.equalsTo(types[i])) {
5125
5299
                                                                        shouldReportTables = true;
5126
 
                                                                }
5127
5300
 
5128
 
                                                                if ("VIEW".equalsIgnoreCase(types[i])) {
 
5301
                                                                } else if (TableType.VIEW.equalsTo(types[i])) {
5129
5302
                                                                        shouldReportViews = true;
5130
 
                                                                }
5131
 
                                                                
5132
 
                                                                if ("SYSTEM TABLE".equalsIgnoreCase(types[i])) {
 
5303
 
 
5304
                                                                } else if (TableType.SYSTEM_TABLE.equalsTo(types[i])) {
5133
5305
                                                                        shouldReportSystemTables = true;
 
5306
 
 
5307
                                                                } else if (TableType.SYSTEM_VIEW.equalsTo(types[i])) {
 
5308
                                                                        shouldReportSystemViews = true;
 
5309
 
 
5310
                                                                } else if (TableType.LOCAL_TEMPORARY.equalsTo(types[i])) {
 
5311
                                                                        shouldReportLocalTemporaries = true;
5134
5312
                                                                }
5135
5313
                                                        }
5136
5314
                                                }
5166
5344
                                                        }
5167
5345
                                                }
5168
5346
 
5169
 
                                                TreeMap<String, byte[][]> tablesOrderedByName = null;
5170
 
                                                TreeMap<String, byte[][]> viewsOrderedByName = null;
5171
 
 
5172
5347
                                                while (results.next()) {
5173
5348
                                                        byte[][] row = new byte[10][];
5174
5349
                                                        row[0] = (catalogStr == null) ? null
5186
5361
                                                                String tableType = results
5187
5362
                                                                                .getString(typeColumnIndex);
5188
5363
 
5189
 
                                                                if (("table".equalsIgnoreCase(tableType) || "base table"
5190
 
                                                                                .equalsIgnoreCase(tableType))
5191
 
                                                                                && shouldReportTables) {
5192
 
                                                                        boolean reportTable = false;
5193
 
                                                                        
5194
 
                                                                        if (!operatingOnInformationSchema && shouldReportTables) {
5195
 
                                                                                row[3] = TABLE_AS_BYTES;
5196
 
                                                                                reportTable = true;
5197
 
                                                                        } else if (operatingOnInformationSchema && shouldReportSystemTables) {
5198
 
                                                                                row[3] = SYSTEM_TABLE_AS_BYTES;
5199
 
                                                                                reportTable = true;
5200
 
                                                                        }
5201
 
                                                                        
5202
 
                                                                        if (reportTable) {
5203
 
                                                                                if (tablesOrderedByName == null) {
5204
 
                                                                                        tablesOrderedByName = new TreeMap<String, byte[][]>();
5205
 
                                                                                }
5206
 
        
5207
 
                                                                                tablesOrderedByName.put(results
5208
 
                                                                                                .getString(1), row);
5209
 
                                                                        }
5210
 
                                                                } else if ("system view".equalsIgnoreCase(tableType) && shouldReportSystemTables) {
5211
 
                                                                        row[3] = SYSTEM_TABLE_AS_BYTES;
5212
 
 
5213
 
                                                                        if (tablesOrderedByName == null) {
5214
 
                                                                                tablesOrderedByName = new TreeMap<String, byte[][]>();
5215
 
                                                                        }
5216
 
 
5217
 
                                                                        tablesOrderedByName.put(results
5218
 
                                                                                        .getString(1), row);
5219
 
                                                                } else if ("view".equalsIgnoreCase(tableType)
5220
 
                                                                                && shouldReportViews) {
5221
 
                                                                        row[3] = VIEW_AS_BYTES;
5222
 
 
5223
 
                                                                        if (viewsOrderedByName == null) {
5224
 
                                                                                viewsOrderedByName = new TreeMap<String, byte[][]>();
5225
 
                                                                        }
5226
 
 
5227
 
                                                                        viewsOrderedByName.put(
5228
 
                                                                                        results.getString(1), row);
5229
 
                                                                } else if (!hasTableTypes) {
5230
 
                                                                        // punt?
5231
 
                                                                        row[3] = TABLE_AS_BYTES;
5232
 
 
5233
 
                                                                        if (tablesOrderedByName == null) {
5234
 
                                                                                tablesOrderedByName = new TreeMap<String, byte[][]>();
5235
 
                                                                        }
5236
 
 
5237
 
                                                                        tablesOrderedByName.put(results
5238
 
                                                                                        .getString(1), row);
 
5364
                                                                switch (TableType.getTableTypeCompliantWith(tableType)) {
 
5365
                                                                        case TABLE:
 
5366
                                                                                boolean reportTable = false;
 
5367
                                                                                TableMetaDataKey tablesKey = null;
 
5368
 
 
5369
                                                                                if (operatingOnSystemDB && shouldReportSystemTables) {
 
5370
                                                                                        row[3] = TableType.SYSTEM_TABLE.asBytes();
 
5371
                                                                                        tablesKey = new TableMetaDataKey(TableType.SYSTEM_TABLE.getName(),
 
5372
                                                                                                        catalogStr, null, results.getString(1));
 
5373
                                                                                        reportTable = true;
 
5374
 
 
5375
                                                                                } else if (!operatingOnSystemDB && shouldReportTables) {
 
5376
                                                                                        row[3] = TableType.TABLE.asBytes();
 
5377
                                                                                        tablesKey = new TableMetaDataKey(TableType.TABLE.getName(), catalogStr,
 
5378
                                                                                                        null, results.getString(1));
 
5379
                                                                                        reportTable = true;
 
5380
                                                                                }
 
5381
 
 
5382
                                                                                if (reportTable) {
 
5383
                                                                                        sortedRows.put(tablesKey, new ByteArrayRow(row, getExceptionInterceptor()));
 
5384
                                                                                }
 
5385
                                                                                break;
 
5386
 
 
5387
                                                                        case VIEW:
 
5388
                                                                                if (shouldReportViews) {
 
5389
                                                                                        row[3] = TableType.VIEW.asBytes();
 
5390
                                                                                        sortedRows.put(new TableMetaDataKey(TableType.VIEW.getName(),
 
5391
                                                                                                        catalogStr, null, results.getString(1)), new ByteArrayRow(row,
 
5392
                                                                                                        getExceptionInterceptor()));
 
5393
                                                                                }
 
5394
                                                                                break;
 
5395
 
 
5396
                                                                        case SYSTEM_TABLE:
 
5397
                                                                                if (shouldReportSystemTables) {
 
5398
                                                                                        row[3] = TableType.SYSTEM_TABLE.asBytes();
 
5399
                                                                                        sortedRows.put(new TableMetaDataKey(TableType.SYSTEM_TABLE.getName(),
 
5400
                                                                                                        catalogStr, null, results.getString(1)), new ByteArrayRow(row,
 
5401
                                                                                                        getExceptionInterceptor()));
 
5402
                                                                                }
 
5403
                                                                                break;
 
5404
 
 
5405
                                                                        case SYSTEM_VIEW:
 
5406
                                                                                if (shouldReportSystemViews) {
 
5407
                                                                                        row[3] = TableType.SYSTEM_VIEW.asBytes();
 
5408
                                                                                        sortedRows.put(new TableMetaDataKey(TableType.SYSTEM_VIEW.getName(),
 
5409
                                                                                                        catalogStr, null, results.getString(1)), new ByteArrayRow(row,
 
5410
                                                                                                        getExceptionInterceptor()));
 
5411
                                                                                }
 
5412
                                                                                break;
 
5413
                                                                                
 
5414
                                                                        case LOCAL_TEMPORARY:
 
5415
                                                                                if (shouldReportLocalTemporaries) {
 
5416
                                                                                        row[3] = TableType.LOCAL_TEMPORARY.asBytes();
 
5417
                                                                                        sortedRows.put(new TableMetaDataKey(TableType.LOCAL_TEMPORARY.getName(),
 
5418
                                                                                                        catalogStr, null, results.getString(1)), new ByteArrayRow(row,
 
5419
                                                                                                        getExceptionInterceptor()));
 
5420
                                                                                }
 
5421
                                                                                break;
 
5422
                                                                                
 
5423
                                                                        default:
 
5424
                                                                                row[3] = TableType.TABLE.asBytes();
 
5425
                                                                                sortedRows.put(new TableMetaDataKey(TableType.TABLE.getName(), catalogStr,
 
5426
                                                                                                null, results.getString(1)), new ByteArrayRow(row,
 
5427
                                                                                                getExceptionInterceptor()));
 
5428
                                                                                break;
5239
5429
                                                                }
5240
5430
                                                        } else {
5241
5431
                                                                if (shouldReportTables) {
5242
5432
                                                                        // Pre-MySQL-5.0.1, tables only
5243
 
                                                                        row[3] = TABLE_AS_BYTES;
5244
 
 
5245
 
                                                                        if (tablesOrderedByName == null) {
5246
 
                                                                                tablesOrderedByName = new TreeMap<String, byte[][]>();
5247
 
                                                                        }
5248
 
 
5249
 
                                                                        tablesOrderedByName.put(results
5250
 
                                                                                        .getString(1), row);
 
5433
                                                                        row[3] = TableType.TABLE.asBytes();
 
5434
                                                                        sortedRows.put(new TableMetaDataKey(TableType.TABLE.getName(), catalogStr, null,
 
5435
                                                                                        results.getString(1)), new ByteArrayRow(row, getExceptionInterceptor()));
5251
5436
                                                                }
5252
5437
                                                        }
5253
5438
                                                }
5254
5439
 
5255
 
                                                // They are ordered by TABLE_TYPE,
5256
 
                                                // * TABLE_SCHEM and TABLE_NAME.
5257
 
 
5258
 
                                                if (tablesOrderedByName != null) {
5259
 
                                                        Iterator<byte[][]> tablesIter = tablesOrderedByName.values()
5260
 
                                                                        .iterator();
5261
 
 
5262
 
                                                        while (tablesIter.hasNext()) {
5263
 
                                                                tuples.add(new ByteArrayRow(tablesIter.next(), getExceptionInterceptor()));
5264
 
                                                        }
5265
 
                                                }
5266
 
 
5267
 
                                                if (viewsOrderedByName != null) {
5268
 
                                                        Iterator<byte[][]> viewsIter = viewsOrderedByName.values()
5269
 
                                                                        .iterator();
5270
 
 
5271
 
                                                        while (viewsIter.hasNext()) {
5272
 
                                                                tuples.add(new ByteArrayRow(viewsIter.next(), getExceptionInterceptor()));
5273
 
                                                        }
5274
 
                                                }
5275
 
 
5276
5440
                                        } finally {
5277
5441
                                                if (results != null) {
5278
5442
                                                        try {
5279
5443
                                                                results.close();
5280
5444
                                                        } catch (Exception ex) {
5281
 
                                                                ;
5282
5445
                                                        }
5283
5446
 
5284
5447
                                                        results = null;
5285
5448
                                                }
5286
 
 
5287
5449
                                        }
5288
5450
                                }
5289
5451
                        }.doForAll();
5293
5455
                        }
5294
5456
                }
5295
5457
 
 
5458
                tuples.addAll(sortedRows.values());
5296
5459
                java.sql.ResultSet tables = buildResultSet(createTablesFields(), tuples);
5297
5460
 
5298
5461
                return tables;
5332
5495
         */
5333
5496
        public java.sql.ResultSet getTableTypes() throws SQLException {
5334
5497
                ArrayList<ResultSetRow> tuples = new ArrayList<ResultSetRow>();
5335
 
                Field[] fields = new Field[1];
5336
 
                fields[0] = new Field("", "TABLE_TYPE", Types.VARCHAR, 5);
5337
 
 
5338
 
                byte[][] tableTypeRow = new byte[1][];
5339
 
                tableTypeRow[0] = TABLE_AS_BYTES;
5340
 
                tuples.add(new ByteArrayRow(tableTypeRow, getExceptionInterceptor()));
5341
 
 
5342
 
                if (this.conn.versionMeetsMinimum(5, 0, 1)) {
5343
 
                        byte[][] viewTypeRow = new byte[1][];
5344
 
                        viewTypeRow[0] = VIEW_AS_BYTES;
5345
 
                        tuples.add(new ByteArrayRow(viewTypeRow, getExceptionInterceptor()));
5346
 
                }
5347
 
 
5348
 
                byte[][] tempTypeRow = new byte[1][];
5349
 
                tempTypeRow[0] = s2b("LOCAL TEMPORARY");
5350
 
                tuples.add(new ByteArrayRow(tempTypeRow, getExceptionInterceptor()));
 
5498
                Field[] fields = new Field[] { new Field("", "TABLE_TYPE", Types.VARCHAR, 256) };
 
5499
 
 
5500
                boolean minVersion5_0_1 = this.conn.versionMeetsMinimum(5, 0, 1);
 
5501
 
 
5502
                tuples.add(new ByteArrayRow(new byte[][] { TableType.LOCAL_TEMPORARY.asBytes() }, getExceptionInterceptor()));
 
5503
                tuples.add(new ByteArrayRow(new byte[][] { TableType.SYSTEM_TABLE.asBytes() }, getExceptionInterceptor()));
 
5504
                if (minVersion5_0_1) {
 
5505
                        tuples.add(new ByteArrayRow(new byte[][] { TableType.SYSTEM_VIEW.asBytes() }, getExceptionInterceptor()));
 
5506
                }
 
5507
                tuples.add(new ByteArrayRow(new byte[][] { TableType.TABLE.asBytes() }, getExceptionInterceptor()));
 
5508
                if (minVersion5_0_1) {
 
5509
                        tuples.add(new ByteArrayRow(new byte[][] { TableType.VIEW.asBytes() }, getExceptionInterceptor()));
 
5510
                }
5351
5511
 
5352
5512
                return buildResultSet(fields, tuples);
5353
5513
        }