dataframe icon indicating copy to clipboard operation
dataframe copied to clipboard

table name could not be available for Kotlin dataframe JDBC

Open linux-china opened this issue 7 months ago • 3 comments

From https://github.com/Kotlin/dataframe/blob/5f5f6a1c253e609666bcb1f0665342d7fa132f08/dataframe-jdbc/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/readJdbc.kt#L923

private fun getTableColumnsMetadata(rs: ResultSet): MutableList<TableColumnMetadata> {
    val metaData: ResultSetMetaData = rs.metaData
    val numberOfColumns: Int = metaData.columnCount
    val tableColumns = mutableListOf<TableColumnMetadata>()
    val columnNameCounter = mutableMapOf<String, Int>()
    val databaseMetaData: DatabaseMetaData = rs.statement.connection.metaData
    val catalog: String? = rs.statement.connection.catalog.takeUnless { it.isNullOrBlank() }
    val schema: String? = rs.statement.connection.schema.takeUnless { it.isNullOrBlank() }

    for (i in 1 until numberOfColumns + 1) {
        val tableName = metaData.getTableName(i)

val tableName = metaData.getTableName(i) could be not available for some DB vendors, such as Hive JDBC with throw new SQLFeatureNotSupportedException("Method not supported");

It is possible to make table name empty if exception thrown.

val tableName = try {
            metaData.getTableName(i)
        }   catch (e: Exception) {
            ""
        }

linux-china avatar May 27 '25 06:05 linux-china

Thanks for sharing, I suppose it’s possible, but I need some additional info:

  • are you connecting via our functional or using a custom DB class, overriding our classes?
  • what kind of vendors do you use (probably I will have a chance to test it properly)

zaleslaw avatar May 27 '25 09:05 zaleslaw

@zaleslaw yes, I create a custom DB class:

object HiveDB : DbType("hive2") {
    override val driverClassName: String
        get() = "org.apache.hive.jdbc.HiveDriver"

DB vendor is Apache Hive, and code link is. https://github.com/apache/hive/blob/2d1405e7feed176aeed337581292b8438cf13326/jdbc/src/java/org/apache/hive/jdbc/HiveResultSetMetaData.java#L101


  public String getCatalogName(int column) throws SQLException {
    throw new SQLFeatureNotSupportedException("Method not supported");
  }


 public String getSchemaName(int column) throws SQLException {
    throw new SQLFeatureNotSupportedException("Method not supported");
  }

  public String getTableName(int column) throws SQLException {
    throw new SQLFeatureNotSupportedException("Method not supported");
  }

linux-china avatar May 27 '25 10:05 linux-china

BTW, the last Apache Hive JDBC Snapshot uses empty string instead of exception thrown.

  public String getSchemaName(int column) throws SQLException {
    String tableName = getTableName(column);
    int index = tableName.lastIndexOf(DOT);
    if (index >= 0) {
      return tableName.substring(0, index);
    }
    // Impala usually doesn't return fully qualified column names. Return "" to avoid
    // giving false results.
    return "";
  }

  public String getTableName(int column) throws SQLException {
    String columnName = getColumnName(column);
    int index = columnName.lastIndexOf(DOT);
    if (index >= 0) {
      return columnName.substring(0, index);
    }
    return "";
  }

Maybe dataframe could read table name from column with . included.

        val columnName = metaData.getColumnName(i)
        val tableName = try {
            metaData.getTableName(i)
        }   catch (e: Exception) {
            ""
            // get table name from column if `.` included
        }


linux-china avatar May 27 '25 10:05 linux-china