Binding отрицательных значений на 64-разрядной платформе

DeadMorozBLR

Новичок
При переходе на 64-разрядный веб-сервер возникла проблема: отрицательное значение, возвращаемое функцией Oracle, отображается как положительное в приложении. СУБД работает на отдельном 64-разрядном сервере.

Пример для воспроизведения:
PHP:
$conn = oci_connect(...);

$query = <<<EOL
BEGIN
  :result := -3007;
END;
EOL;

$stmt = oci_parse($conn, $query);
oci_bind_by_name($stmt, ':result', $result, -1, SQLT_INT);
oci_execute($stmt);

var_dump($result);
На 32-разрядном клиенте значение отображается как int(-3007), а на 64-разрядном — как int(4294964289).

В чём может быть причина проблемы и как её можно исправить?
 

confguru

ExAdmin
Команда форума
Grezz

Человек все равно ждал ответа :) Даже написал мне об этом.
 

DeadMorozBLR

Новичок
Это типа workaround? На самом деле, проблема уже отпала, и я больше не работаю над этим проектом, просто интересно, в чём дело.
 

Grezz

Новичок
Проблема в том, что почему-то int становится беззнаковым, но в то же время сам знаковый бит сохраняется, эффект хорошо виден если заменить vardump на printf("%b\n", $result);

Что самое интересное - похоже аналогичный костыль используется и в PDO:
PHP:
<?php

$conn = new PDO('oci:dbname=....');

$query = <<<EOL
BEGIN
  :result := -3007;
  END;
EOL;

$result = 0;
$stmt = $conn->prepare($query);
$stmt->bindParam(':result', $result, PDO::PARAM_INT, 10);
$stmt->execute();

var_dump($result);

?>
 

DeadMorozBLR

Новичок
Проблема в том, что почему-то int становится беззнаковым, но в то же время сам знаковый бит сохраняется
Я бы скорее сказал так, что отрицательное число в двоичном представлении на x64 почему-то выглядит так, как должно выглядеть на x32, но не на x64. То есть единицами недозаполняются все старшие биты, в т.ч. и бит знака. Видимо, Оракл, записывая результат в переменную, не знает о разрядности целевой платформы.
Код:
$ php -r 'printf("%b\n", 4294964289);'
11111111111111111111010001000001
$ php -r 'printf("%b\n", -3007);'
1111111111111111111111111111111111111111111111111111010001000001
 

флоппик

promotor fidei
Команда форума
Партнер клуба
А собственно клиент оракла на веб-сервере-то был 64битный? :)
 

DeadMorozBLR

Новичок
Сейчас точно не скажу, но факт, что сервер работал в каком-то режиме совместимости, когда на 64-битном линуксе можно было запускать 32-битный бинарный файл (от которого были потеряны исходники). Может дело и было в этом.

А как можно узнать разрядность установленного клиента?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Самый простой способ, который пришел в голову - в $ORACLE_HOME/bin посмотреть на папки — если там есть lib32 и lib — это 64-битный клиент :) Если только lib - 32х битный.
Наверняка, есть и более умный способ :)
 
Сверху