On Sun, 2004-05-16 at 18:16, Timm Friebe wrote:
> [...]
> Or, replying to myself, simply use convert_scalar_to_number() from
> Zend/zend_operators.c which (AFAIS) does pretty much the same. The
> testcase I wrote for this (attached) is passed here.
>
> Ard, do you use sybase_ct? If so, could you verify it works for you,
> too?
For convenience, here is a complete patch.
- Timm
Index: php_sybase_ct.c
===================================================================
RCS file: /repository/php-src/ext/sybase_ct/php_sybase_ct.c,v
retrieving revision 1.93
diff -u -r1.93 php_sybase_ct.c
--- php_sybase_ct.c 16 Apr 2004 16:27:13 -0000 1.93
+++ php_sybase_ct.c 16 May 2004 17:33:13 -0000
@@ -1127,15 +1127,14 @@
convert_to_long(&result->data[i][j]);
break;
case 2:
- /* We also get numbers that are actually integers here due to the check on
- * precision against > 9 (ranges are -1E10 to -1E9 and 1E9 to 1E10). As we
- * cannot be sure that they "fit" into MIN_LONG <= x <= MAX_LONG, we call
- * convert_to_double() on them. This is a small performance penalty, but
- * ensures that "select 2147483648" will be a float and "select 2147483647"
- * will be become an int.
- */
convert_to_double(&result->data[i][j]);
break;
+ case 3:
+ /* This signals we have an integer datatype, but we need to convert to double if we
+ * overflow.
+ */
+ convert_scalar_to_number(&result->data[i][j]);
+ break;
}
}
}
@@ -1243,7 +1242,7 @@
case CS_DECIMAL_TYPE:
result->datafmt[i].maxlength = result->datafmt[i].precision + 3;
/* numeric(10) vs numeric(10, 1) */
- result->numerics[i] = (result->datafmt[i].scale == 0 && result->datafmt[i].precision <= 9) ? 1 : 2;
+ result->numerics[i] = (result->datafmt[i].scale == 0) ? 3 : 2;
break;
default:
result->datafmt[i].maxlength++;
Index: tests/test_long.phpt
===================================================================
RCS file: tests/test_long.phpt
diff -N tests/test_long.phpt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/test_long.phpt 16 May 2004 17:33:13 -0000
@@ -0,0 +1,80 @@
+--TEST--
+Sybase-CT select LONG_MAX / LONG_MIN
+--SKIPIF--
+<?php require('skipif.inc'); ?>
+--FILE--
+<?php
+/* This file is part of PHP test framework for ext/sybase_ct
+ *
+ * $Id: test_types.phpt,v 1.2 2004/01/24 15:18:52 thekid Exp $
+ */
+
+ require('test.inc');
+
+ define('LONG_MAX', is_int(2147483648) ? 9223372036854775807 : 2147483647);
+ define('LONG_MIN', -LONG_MAX - 1);
+
+ $db= sybase_connect_ex();
+ var_dump(sybase_select_db('tempdb', $db));
+
+ // Create table and insert some values
+ var_dump(sybase_query('create table test_long (value numeric(20, 0))'));
+ var_dump(sybase_query('insert test_long values ('.(LONG_MAX - 1).')'));
+ var_dump(sybase_query('insert test_long values ('.(LONG_MAX).')'));
+ var_dump(sybase_query('insert test_long values ('.(LONG_MAX + 1).')'));
+ var_dump(sybase_query('insert test_long values ('.(LONG_MIN + 1).')'));
+ var_dump(sybase_query('insert test_long values ('.(LONG_MIN).')'));
+ var_dump(sybase_query('insert test_long values ('.(LONG_MIN - 1).')'));
+
+ // Select values
+ var_dump(sybase_select_ex($db, 'select value from test_long'));
+
+ // Drop table
+ var_dump(sybase_query('drop table test_long'));
+
+ sybase_close($db);
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+>>> Query: select value from test_long
+<<< Return: resource
+array(6) {
+ [0]=>
+ array(1) {
+ ["value"]=>
+ int(%s)
+ }
+ [1]=>
+ array(1) {
+ ["value"]=>
+ int(%s)
+ }
+ [2]=>
+ array(1) {
+ ["value"]=>
+ float(%s)
+ }
+ [3]=>
+ array(1) {
+ ["value"]=>
+ int(-%s)
+ }
+ [4]=>
+ array(1) {
+ ["value"]=>
+ int(-%s)
+ }
+ [5]=>
+ array(1) {
+ ["value"]=>
+ float(-%s)
+ }
+}
+bool(true)
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php