455
458
return columnOrdinalPosition.compareTo(indexInfoKey.columnOrdinalPosition);
462
public boolean equals(Object obj) {
471
if (!(obj instanceof IndexMetaDataKey)) {
474
return compareTo((IndexMetaDataKey) obj) == 0;
479
* Helper class to provide means of comparing tables by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM and TABLE_NAME.
481
protected class TableMetaDataKey implements Comparable<TableMetaDataKey> {
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;
494
public int compareTo(TableMetaDataKey tablesKey) {
497
if ((compareResult = tableType.compareTo(tablesKey.tableType)) != 0) {
498
return compareResult;
500
if ((compareResult = tableCat.compareTo(tablesKey.tableCat)) != 0) {
501
return compareResult;
503
if ((compareResult = tableSchem.compareTo(tablesKey.tableSchem)) != 0) {
504
return compareResult;
506
return tableName.compareTo(tablesKey.tableName);
510
public boolean equals(Object obj) {
519
if (!(obj instanceof TableMetaDataKey)) {
522
return compareTo((TableMetaDataKey) obj) == 0;
527
* Helper/box class to provide means of sorting objects by using a sorting key.
529
protected class ComparableWrapper<K extends Object & Comparable<? super K>, V> implements
530
Comparable<ComparableWrapper<K, V>> {
534
public ComparableWrapper(K key, V value) {
543
public V getValue() {
547
public int compareTo(ComparableWrapper<K, V> other) {
548
return getKey().compareTo(other.getKey());
552
public boolean equals(Object obj) {
561
if (!(obj instanceof ComparableWrapper<?, ?>)) {
565
Object otherKey = ((ComparableWrapper<?, ?>) obj).getKey();
566
return key.equals(otherKey);
570
public String toString() {
571
return "{KEY:" + key + "; VALUE:" + value +"}";
576
* Enumeration for Table Types
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");
583
private byte[] nameAsBytes;
584
private String[] synonyms;
586
TableType(String tableTypeName) {
587
this(tableTypeName, null);
590
TableType(String tableTypeName, String[] tableTypeSynonyms) {
591
name = tableTypeName;
592
nameAsBytes = tableTypeName.getBytes();
593
synonyms = tableTypeSynonyms;
604
boolean equalsTo(String tableTypeName) {
605
return name.equalsIgnoreCase(tableTypeName);
608
static TableType getTableTypeEqualTo(String tableTypeName) {
609
for (TableType tableType : TableType.values()) {
610
if (tableType.equalsTo(tableTypeName)) {
617
boolean compliesWith(String tableTypeName) {
618
if (equalsTo(tableTypeName)) {
621
if (synonyms != null) {
622
for (String synonym : synonyms) {
623
if (synonym.equalsIgnoreCase(tableTypeName)) {
631
static TableType getTableTypeCompliantWith(String tableTypeName) {
632
for (TableType tableType : TableType.values()) {
633
if (tableType.compliesWith(tableTypeName)) {
642
* Enumeration for Procedure Types
644
protected enum ProcedureType {
459
648
private static String mysqlKeywordsThatArentSQL92;
461
650
protected static final int MAX_IDENTIFIER_LENGTH = 64;
463
652
private static final int DEFERRABILITY = 13;
465
654
private static final int DELETE_RULE = 10;
529
718
JDBC_4_DBMD_SHOW_CTOR = null;
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",
1550
1740
* @see #getSearchStringEscape
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);
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);
1690
boolean parsingFunction = false;
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";
1885
paramRetrievalRs = paramRetrievalStmt.executeQuery("SHOW CREATE FUNCTION " + procNameBuf.toString());
1886
fieldName = "Create Function";
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);
1709
1892
if (!this.conn.getNoAccessToProcedureBodies() &&
1710
1893
(procedureDef == null || procedureDef.length() == 0)) {
5073
5256
tableNamePat = tableNamePattern;
5076
final boolean operatingOnInformationSchema = "information_schema".equalsIgnoreCase(catalog);
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);
5082
5266
ResultSet results = null;
5086
if (!conn.versionMeetsMinimum(5, 0, 2)) {
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())) {
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())) {
5271
results = stmt.executeQuery((!conn.versionMeetsMinimum(5, 0, 2) ? "SHOW TABLES FROM "
5272
: "SHOW FULL TABLES FROM ")
5273
+ StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())
5275
+ tableNamePat + "'");
5276
} catch (SQLException sqlEx) {
5277
if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlEx.getSQLState())) {
5114
5284
boolean shouldReportTables = false;
5115
5285
boolean shouldReportViews = false;
5116
5286
boolean shouldReportSystemTables = false;
5287
boolean shouldReportSystemViews = false;
5288
boolean shouldReportLocalTemporaries = false;
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;
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;
5128
if ("VIEW".equalsIgnoreCase(types[i])) {
5301
} else if (TableType.VIEW.equalsTo(types[i])) {
5129
5302
shouldReportViews = true;
5132
if ("SYSTEM TABLE".equalsIgnoreCase(types[i])) {
5304
} else if (TableType.SYSTEM_TABLE.equalsTo(types[i])) {
5133
5305
shouldReportSystemTables = true;
5307
} else if (TableType.SYSTEM_VIEW.equalsTo(types[i])) {
5308
shouldReportSystemViews = true;
5310
} else if (TableType.LOCAL_TEMPORARY.equalsTo(types[i])) {
5311
shouldReportLocalTemporaries = true;
5186
5361
String tableType = results
5187
5362
.getString(typeColumnIndex);
5189
if (("table".equalsIgnoreCase(tableType) || "base table"
5190
.equalsIgnoreCase(tableType))
5191
&& shouldReportTables) {
5192
boolean reportTable = false;
5194
if (!operatingOnInformationSchema && shouldReportTables) {
5195
row[3] = TABLE_AS_BYTES;
5197
} else if (operatingOnInformationSchema && shouldReportSystemTables) {
5198
row[3] = SYSTEM_TABLE_AS_BYTES;
5203
if (tablesOrderedByName == null) {
5204
tablesOrderedByName = new TreeMap<String, byte[][]>();
5207
tablesOrderedByName.put(results
5208
.getString(1), row);
5210
} else if ("system view".equalsIgnoreCase(tableType) && shouldReportSystemTables) {
5211
row[3] = SYSTEM_TABLE_AS_BYTES;
5213
if (tablesOrderedByName == null) {
5214
tablesOrderedByName = new TreeMap<String, byte[][]>();
5217
tablesOrderedByName.put(results
5218
.getString(1), row);
5219
} else if ("view".equalsIgnoreCase(tableType)
5220
&& shouldReportViews) {
5221
row[3] = VIEW_AS_BYTES;
5223
if (viewsOrderedByName == null) {
5224
viewsOrderedByName = new TreeMap<String, byte[][]>();
5227
viewsOrderedByName.put(
5228
results.getString(1), row);
5229
} else if (!hasTableTypes) {
5231
row[3] = TABLE_AS_BYTES;
5233
if (tablesOrderedByName == null) {
5234
tablesOrderedByName = new TreeMap<String, byte[][]>();
5237
tablesOrderedByName.put(results
5238
.getString(1), row);
5364
switch (TableType.getTableTypeCompliantWith(tableType)) {
5366
boolean reportTable = false;
5367
TableMetaDataKey tablesKey = null;
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));
5375
} else if (!operatingOnSystemDB && shouldReportTables) {
5376
row[3] = TableType.TABLE.asBytes();
5377
tablesKey = new TableMetaDataKey(TableType.TABLE.getName(), catalogStr,
5378
null, results.getString(1));
5383
sortedRows.put(tablesKey, new ByteArrayRow(row, getExceptionInterceptor()));
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()));
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()));
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()));
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()));
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()));
5241
5431
if (shouldReportTables) {
5242
5432
// Pre-MySQL-5.0.1, tables only
5243
row[3] = TABLE_AS_BYTES;
5245
if (tablesOrderedByName == null) {
5246
tablesOrderedByName = new TreeMap<String, byte[][]>();
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()));
5255
// They are ordered by TABLE_TYPE,
5256
// * TABLE_SCHEM and TABLE_NAME.
5258
if (tablesOrderedByName != null) {
5259
Iterator<byte[][]> tablesIter = tablesOrderedByName.values()
5262
while (tablesIter.hasNext()) {
5263
tuples.add(new ByteArrayRow(tablesIter.next(), getExceptionInterceptor()));
5267
if (viewsOrderedByName != null) {
5268
Iterator<byte[][]> viewsIter = viewsOrderedByName.values()
5271
while (viewsIter.hasNext()) {
5272
tuples.add(new ByteArrayRow(viewsIter.next(), getExceptionInterceptor()));
5277
5441
if (results != null) {
5279
5443
results.close();
5280
5444
} catch (Exception ex) {
5284
5447
results = null;
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);
5338
byte[][] tableTypeRow = new byte[1][];
5339
tableTypeRow[0] = TABLE_AS_BYTES;
5340
tuples.add(new ByteArrayRow(tableTypeRow, getExceptionInterceptor()));
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()));
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) };
5500
boolean minVersion5_0_1 = this.conn.versionMeetsMinimum(5, 0, 1);
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()));
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()));
5352
5512
return buildResultSet(fields, tuples);