JRuby on Rails с использованием jdbc postgres (8.4) игнорирует значения по умолчанию - PullRequest
0 голосов
/ 08 февраля 2011

У меня есть таблица, созданная в процессе миграции (только для упрощения проблемы), которая выглядит следующим образом:

create_table :test_defaults, :force => true do |table|
     table.integer   :failure,       :default => -1, :null => false
end

Итак, один столбец назван сбой. Когда я выполняю эту команду rails:

td = TestDefault.create!

JRuby завершается неудачно с:

ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: ERROR: null value in column
"failure" violates not-null constraint: INSERT INTO "test_defaults" ("failure")
VALUES(NULL) RETURNING "id"

тогда как версия ruby ​​успешно справляется с таким запросом:

INSERT INTO "test_defaults" ("failure") VALUES(-1) RETURNING "id"

Я бегу:

ruby 1.8.7, 
rails 2.2.2, 
jruby 1.5.6, 
activerecord-jdbc-adapter (1.1.0)
activerecord-jdbcpostgresql-adapter (1.1.0)
jdbc-postgres (8.4.702)

Предложения приветствуются. Не удалось найти ничего полезного в Google, и даже не знаю, кому сообщить об ошибке.

Приветствие.

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

EDIT2: Из моего ответа ниже, это проблема кода в квадратных скобках для отрицательных значений по умолчанию в postgres 8.4. Если кто-то может предложить способ обойти эту проблему, не дожидаясь обновления гема (например, сказать postgres, чтобы убрать эти скобки), это было бы очень полезно.

1 Ответ

0 голосов
/ 08 февраля 2011

Хорошо. Нашел ответ на этот вопрос:

activerecord-jdbc-adapter-1.1.0/lib/arjdbc/postgresql/adapter.rb

у нас есть строки (@ 59):

def default_value(value)
    # Boolean types
    return "t" if value =~ /true/i
    return "f" if value =~ /false/i

    # Char/String/Bytea type values
    return $1 if value =~ /^'(.*)'::(bpchar|text|character varying|bytea)$/

    # Numeric values
    return value if value =~ /^-?[0-9]+(\.[0-9]*)?/

    # Fixed dates / timestamp
    return $1 if value =~ /^'(.+)'::(date|timestamp)/

    # Anything else is blank, some user type, or some function
    # and we can't know the value of that, so return nil.
    return nil
  end
end

Когда отрицательное значение по умолчанию возвращается из postgres, оно возвращает, скажем, "(-1)" в квадратных скобках. Однако приведенное выше регулярное выражение для чисел не совпадает в скобках.

Пытался зарегистрироваться, чтобы зарегистрировать ошибку (на http://kenai.com/jira/browse/ACTIVERECORD_JDBC),, но при регистрации сервер не работал.

РЕДАКТИРОВАТЬ: Создана ошибка: http://kenai.com/jira/browse/ACTIVERECORD_JDBC-151

РЕДАКТИРОВАТЬ: Также в конечном итоге это нужно в том же месте, что и предыдущий код. "(-1)".to_i возвращает 0, что обычно плохо.

    def type_cast(value)
        case type
            when :integer then value = remove_brackets_from_negative(value)
        end
        super
    end
    def remove_brackets_from_negative(value)
        value.gsub!(/[\)\(]/,"") if value.is_a?(String)
        value
    end
...