Ошибка оракула

В одном из проектов при исправлении ошибки всплыло неожиданное. Кусок кода, который работал ошибочно, родился где-то в двухтысячных и по всей видимости в те времена работал правильно. В нём проверялось — если тип переменной «целое», то переменная передавалась в «Оракл» с флагом SQLT_INT, иначе — с SQLT_CHR.

Всё работало хорошо, пока ПХП был 32-битным. Проверка is_int в этом языке возвращала «истину» только для чисел в диапазоне -2147483648…2147483647, всё что шире, трактовалось как float. В 64-битном интерпретаторе целыми считаются числа из гораздо более широкого диапазона, соответственно, в каком-то коде такое значение попало в драйвер «Оракла», промаркированное как SQLT_INT.

Беда в том, что драйвер (в этом месте), похоже, остался в пределах 32 бит, код:
$var = null;
$st = oci_parse($con, "SELECT :int FROM DUAL");
oci_bind_by_name($st, 'int', $var, -1, SQLT_INT);

foreach ([100500, PHP_INT_MAX, 2147483648] as $var) {
	oci_execute($st);
	echo oci_fetch_array($st, OCI_NUM)[0], "\n";
}
Выведет: 100500, -1, -2147483648. Решение я пока знаю только одно: не использовать для целых, которые не помещаются в 32 бита указание типа SQLT_INT.

Проблема в файле oci8_statement.c (это текущий код драйвера из PHP 5.7):
switch (bind->array.type) {
	case SQLT_NUM:
	case SQLT_INT:
	case SQLT_LNG:

		...
		ZVAL_LONG(entry, ((ub4 *)(bind->array.elements))[i]);
		...
Значение в этом месте приводится к четырёхбайтному целому.
20 декабря 2014 16:02

PHP (инкогнито)
20 декабря 2014, 17:04

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

bolknote.ru (bolknote.ru)
20 декабря 2014, 17:08, ответ предназначен PHP

Спасибо за ваше интересное мнение!

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)