|
8 | 8 |
|
9 | 9 | import java.sql.DatabaseMetaData; |
10 | 10 | import java.sql.ResultSet; |
| 11 | +import java.sql.ResultSetMetaData; |
11 | 12 | import java.sql.SQLException; |
| 13 | +import java.sql.Statement; |
12 | 14 | import java.util.ArrayList; |
13 | 15 | import java.util.Collections; |
14 | 16 | import java.util.HashMap; |
@@ -540,62 +542,53 @@ protected boolean isPhysicalTableType(String tableType) { |
540 | 542 | } |
541 | 543 |
|
542 | 544 | private void addColumns(TableInformation tableInformation) { |
543 | | - final QualifiedTableName tableName = tableInformation.getName(); |
544 | | - final Identifier catalog = tableName.getCatalogName(); |
545 | | - final Identifier schema = tableName.getSchemaName(); |
546 | | - |
547 | | - final String catalogFilter; |
548 | | - final String schemaFilter; |
549 | | - |
550 | | - if ( catalog == null ) { |
551 | | - catalogFilter = ""; |
552 | | - } |
553 | | - else { |
554 | | - catalogFilter = catalog.getText(); |
555 | | - } |
556 | | - |
557 | | - if ( schema == null ) { |
558 | | - schemaFilter = ""; |
559 | | - } |
560 | | - else { |
561 | | - schemaFilter = schema.getText(); |
562 | | - } |
563 | | - |
564 | | - try { |
565 | | - ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getColumns( |
566 | | - catalogFilter, |
567 | | - schemaFilter, |
568 | | - tableName.getTableName().getText(), |
569 | | - "%" |
570 | | - ); |
571 | | - |
572 | | - try { |
573 | | - while ( resultSet.next() ) { |
574 | | - final String columnName = resultSet.getString( "COLUMN_NAME" ); |
575 | | - final ColumnInformationImpl columnInformation = new ColumnInformationImpl( |
576 | | - tableInformation, |
577 | | - DatabaseIdentifier.toIdentifier( columnName ), |
578 | | - resultSet.getInt( "DATA_TYPE" ), |
579 | | - new StringTokenizer( resultSet.getString( "TYPE_NAME" ), "() " ).nextToken(), |
580 | | - resultSet.getInt( "COLUMN_SIZE" ), |
581 | | - resultSet.getInt( "DECIMAL_DIGITS" ), |
582 | | - interpretTruthValue( resultSet.getString( "IS_NULLABLE" ) ) |
583 | | - ); |
584 | | - tableInformation.addColumn( columnInformation ); |
585 | | - } |
586 | | - } |
587 | | - finally { |
588 | | - resultSet.close(); |
| 545 | + // We use this dummy query to retrieve the table information through the ResultSetMetaData |
| 546 | + // This is significantly better than to use the DatabaseMetaData especially on Oracle with synonyms enabled |
| 547 | + final String tableName = extractionContext.getJdbcEnvironment().getQualifiedObjectNameFormatter().format( |
| 548 | + // The name comes from the database, so the case is correct |
| 549 | + // But we quote here to avoid issues with reserved words |
| 550 | + tableInformation.getName().quote(), |
| 551 | + extractionContext.getJdbcEnvironment().getDialect() |
| 552 | + ); |
| 553 | + final String query = "select * from " + tableName + " where 1=0"; |
| 554 | + try (Statement statement = extractionContext.getJdbcConnection() |
| 555 | + .createStatement(); ResultSet resultSet = statement.executeQuery( query )) { |
| 556 | + final ResultSetMetaData metaData = resultSet.getMetaData(); |
| 557 | + final int columnCount = metaData.getColumnCount(); |
| 558 | + |
| 559 | + for ( int i = 1; i <= columnCount; i++ ) { |
| 560 | + final String columnName = metaData.getColumnName( i ); |
| 561 | + final ColumnInformationImpl columnInformation = new ColumnInformationImpl( |
| 562 | + tableInformation, |
| 563 | + DatabaseIdentifier.toIdentifier( columnName ), |
| 564 | + metaData.getColumnType( i ), |
| 565 | + new StringTokenizer( metaData.getColumnTypeName( i ), "() " ).nextToken(), |
| 566 | + metaData.getPrecision( i ), |
| 567 | + metaData.getScale( i ), |
| 568 | + interpretNullable( metaData.isNullable( i ) ) |
| 569 | + ); |
| 570 | + tableInformation.addColumn( columnInformation ); |
589 | 571 | } |
590 | 572 | } |
591 | 573 | catch (SQLException e) { |
592 | 574 | throw convertSQLException( |
593 | 575 | e, |
594 | | - "Error accessing column metadata: " + tableName.toString() |
| 576 | + "Error accessing column metadata: " + tableInformation.getName().toString() |
595 | 577 | ); |
596 | 578 | } |
597 | 579 | } |
598 | 580 |
|
| 581 | + private TruthValue interpretNullable(int nullable) { |
| 582 | + switch ( nullable ) { |
| 583 | + case ResultSetMetaData.columnNullable: |
| 584 | + return TruthValue.TRUE; |
| 585 | + case ResultSetMetaData.columnNoNulls: |
| 586 | + return TruthValue.FALSE; |
| 587 | + default: |
| 588 | + return TruthValue.UNKNOWN; |
| 589 | + } |
| 590 | + } |
| 591 | + |
599 | 592 | private TruthValue interpretTruthValue(String nullable) { |
600 | 593 | if ( "yes".equalsIgnoreCase( nullable ) ) { |
601 | 594 | return TruthValue.TRUE; |
|
0 commit comments