Правильно ли, что ResultSet.getMetaData.getTableName (col) драйвера jdbc для postgresql всегда возвращает пустую строку? - PullRequest
7 голосов
/ 12 февраля 2012

Когда я использую postgresql, я нашел следующий код:

Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from t");

String tableName = rs.getMetaData().getTableName(1);
System.out.println(tableName);

Он печатает пустую строку.

Итак, я проверил исходный код и обнаружил, что метод org.postgresql.jdbc2.AbstractJdbc2ResultSetMetaData#getTableName всегда возвращает пустую строку.

Исходный код:

public abstract class AbstractJdbc2ResultSetMetaData implements PGResultSetMetaData {

    /*
     * @param column the first column is 1, the second is 2...
     * @return column name, or "" if not applicable
     * @exception SQLException if a database access error occurs
     */
    public String getTableName(int column) throws SQLException
    {
        return "";
    }
}

Вы можете видеть, что это просто возвращает "".

Я нашел обсуждение по этому поводу, см .: http://archives.postgresql.org/pgsql-jdbc/2009-12/msg00100.php

Они думают «rs.getMetaData.getTableName (col)» должен вернуть псевдоним в запрос не имя базовой таблицы. Но это сложно реализовать, поэтому лучше оставить его пустым.

Также они дали метод для получения имени таблицы, используйте:

PGResultSetMetaData.getBaseTableName() 

Пример:

ResultSet rs = stmt.executeQuery("select * from x");
// convert it to PGResultSetMetaData 
PGResultSetMetaData meta = (PGResultSetMetaData)rs.getMetaData(); 
String tableName = meta.getBaseTableName(1);

Теперь можно печатать правильное имя таблицы.

Я не знаю, правильна ли реализация postgresql, но возвращение имени базовой таблицы гораздо более полезно, чем пустая строка, и большинство других баз данных предоставляют имя базовой таблицы вместо пустой строки.

У меня проблема с использованием платформы anorm play2 с postgesql: Anorm Play2 не может работать на postgresql , но это хорошо работает в других базах данных.

Как вы думаете, правильная реализация драйвера jdbc для postgresql? Вернуть пустую строку, имя таблицы или что-то еще?

Ответы [ 2 ]

3 голосов
/ 07 января 2013

Я бы сказал, что возвращение пустой строки, очевидно, является неправильной реализацией интерфейса, поскольку имя таблицы никогда не может считаться пустой строкой.

Проблема, с которой, по-моему, они борются, заключается в том, что, хотя их текущая реализация неверна, как только они выберут реализацию, они застрянут с ней, пока не решат, что нарушение зависимости от поведения приемлемо. Поэтому они решили добавить метод, имя которого однозначно, и предоставить данные, от которых большинство пользователей ожидали получить getTableName, и оставить явно нарушенную реализацию метода getTableName, пока не будет достигнут консенсус относительно того, что он должен возвращать. или пока не будет представлен патч, реализующий консенсус.

Моя внутренняя реакция заключается в том, что метод getTableName должен возвращать псевдоним, используемый для этой таблицы. Таблица может быть объединена с самим собой, и использование псевдонима позволит вам определить, на какую ссылку ссылались. Таблица могла быть сгенерирована в запросе (например, удалить массив) и поэтому даже не иметь имени таблицы в базе данных. Если вы принимаете решение «абсолютно всегда, getTableName возвращает псевдоним», то, по крайней мере, пользователи знают, чего ожидать; в противном случае вы не поймете, что должен возвращать метод.

Однако, даже если я предполагаю, что моя внутренняя реакция - «правильная реализация», это поднимает вопрос совместимости. Желательно, чтобы можно было переключаться с другой СУБД на PostgreSQL с минимальными затратами, если одна из целей PostgreSQL - это рост популярности. Поэтому такие вещи, как «как другие JDBC реализуют интерфейсы java.sql?», Становятся актуальными. Как вы говорите, существует фреймворк, в котором есть ожидания того, как должен быть реализован ResultSetMetaData, и, вероятно, он не единственный с определенными ожиданиями того, как будут реализованы интерфейсы java.sql.

Какую бы реализацию они в итоге ни выбрали, это будет компромиссом, поэтому я понимаю, почему «выбить из строя» - это их выбор. Как только они выбирают компромисс, который хотят сделать, они блокируются.

РЕДАКТИРОВАТЬ: Я хотел бы предложить, что бросить исключение в отношении не реализованных было бы лучше, чем просто молча провал. Я ожидаю, что фреймворки, которые полагаются на конкретную реализацию getTableName, в любом случае не будут иметь большого значения для пустой строки, и либо ошибки, либо сами по себе завершатся сбоем.

0 голосов
/ 27 декабря 2013

кажется, это будет изменено в следующей версии: https://github.com/pgjdbc/pgjdbc/pull/107

...