Bug #16960: [Sybase-CT] sybase_fetch_row() and types

From: Date: Thu, 02 May 2002 09:37:18 +0000
Subject: Bug #16960: [Sybase-CT] sybase_fetch_row() and types
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-6696@lists.php.net to get a copy of this message
From:             thekid@thekid.de
Operating system: All
PHP version:      4.0CVS-2002-05-02
PHP Bug Type:     Feature/Change Request
Bug description:  [Sybase-CT] sybase_fetch_row() and types

First of all: I'm putting this in here since my mail to
php-dev@list.php.net was rejected thanks to an overefficient spam
protection filter (kundenserver.de).
Please see http://relaytest.kundenserver.de/ for
details.

Here's my mail:
--------------------------------------------------------
Hello,
as you might know, the sybase extension is very bad when it comes to
data types, since it returns almost everything as a string, except for
NULL values, which become FALSE.
        
Short example:
--- SQL -------------------------------
select
      NULL as "null",
      "string" as string,
      6100 as integer,
      6.1 as float,
      getdate() as date

--- var_dump() of resultset -----------  
array(10) {
  [0]=>
  string(0) ""
  ["null"]=>
  string(0) ""
  [1]=>   
  string(6) "string"
  ["string"]=>
  string(6) "string"
  [2]=>
  string(4) "6100"
  ["integer"]=>
  string(4) "6100"
  [3]=>
  string(3) "6.1"
  ["float"]=>
  string(3) "6.1"
  [4]=>
  string(4) "   :"
  ["date"]=>  
  string(4) "   :"
}
      
Well, when writing applications communicating via SOAP with type-secure
languages - in my case PHP as server, Java as client - this comes quite
unhandy, since on ends up going through the resultset and changing types
for each entry, thus producing unnecessary overhead.
        
Something like this would be much nicer:
--- var_dump() of resultset -----------
array(10) {
  [0]=>
  NULL
  ["null"]=>  
  NULL
  [1]=>
  string(6) "string"
  ["string"]=>
  string(6) "string"
  [2]=>
  int(6100)
  ["integer"]=>
  int(6100)
  [3]=>
  float(6.1)
  ["float"]=>
  float(6.1)
  [4]=>
  string(19) "May 02 2002 11:15AM"
  ["date"]=>
  string(19) "May 02 2002 11:15AM"
}

OK, so I went ahead and patched ext/sybase_ct/php_sybase_ct.c to
accomplish my wishes. I must admit though I'm a total lamer when it goes
to writing C sourcecode and utilizing the Zend API, so - after studying
a couple of files, wrote a couple of lines, compiled, watched the thing
segfault once or twice, I finally managed to get a running PHP binary
and a sybase_ct.so compiled.

Attached is the patch, however ugly it may be, it compiles and produces
the resultset as intended - maybe you guys want to take a look at it
and correct it to be much nicer and much better:-)

-- 
Timm Friebe
Systems developer Schlund+Partner AG
Karlsruhe, Germany

[patch-ext_sybase_ct_php_sybase_ct.c]
--- php4-200205012100/ext/sybase_ct/php_sybase_ct.c	Tue Mar 12 21:34:06
2002
+++ __build__/ext/sybase_ct/php_sybase_ct.c	Thu May  2 10:47:53 2002
@@ -953,33 +953,33 @@
 				break;
 			case CS_SMALLINT_TYPE:
 				datafmt[i].maxlength = 7;
-				numerics[i] = 1;
+				numerics[i] = 1;                               
 				break;
 			case CS_INT_TYPE:
 				datafmt[i].maxlength = 12;
-				numerics[i] = 1;
+				numerics[i] = 1;                                
 				break;
 			case CS_REAL_TYPE:
 			case CS_FLOAT_TYPE:
 				datafmt[i].maxlength = 24;
-				numerics[i] = 1;
-				break;
+				numerics[i] = 2;
+                                break;
 			case CS_MONEY_TYPE:
 			case CS_MONEY4_TYPE:
 				datafmt[i].maxlength = 24;
-				numerics[i] = 0;
+				numerics[i] = 0;                                
 				break;
 			case CS_DATETIME_TYPE:
 			case CS_DATETIME4_TYPE:
 				datafmt[i].maxlength = 30;
 				numerics[i] = 0;
-				break;
+                                break;
 			case CS_NUMERIC_TYPE:
 			case CS_DECIMAL_TYPE:
 				datafmt[i].maxlength = datafmt[i].precision + 3;
-				numerics[i] = 1;
+				numerics[i] = 2;                                
 				break;
-			default:
+			default:                                
 				datafmt[i].maxlength++;
 				numerics[i] = 0;
 				break;
@@ -1004,11 +1004,19 @@
 		result->data[i] = (pval *) emalloc(sizeof(pval)*num_fields);
 		for (j=0; j<num_fields; j++) {
 			if (indicators[j] == -1) { /* null value */
-				ZVAL_FALSE(&result->data[i][j]);
+				ZVAL_NULL(&result->data[i][j]);
 			} else {
 				Z_STRLEN(result->data[i][j]) = lengths[j]-1;  /* we don't need the
NULL in the length */
 				Z_STRVAL(result->data[i][j]) = estrndup(tmp_buffer[j], lengths[j]);
 				Z_TYPE(result->data[i][j]) = IS_STRING;
+                          
+				// Here we go, i want those types!:-) 
+				// Perhaps there is a nicer way of doing this, instead of making
strings first 
+				// and then converting them back, but I'm a Zend-API-lamer.
+				switch (numerics[j]) {
+                                      case 1:
convert_to_long(&result->data[i][j]); break;
+                                      case 2:
convert_to_double(&result->data[i][j]); numerics[j]= 1; break;
+				}
 			}
 		}
 	}

-- 
Edit bug report at http://bugs.php.net/?id=16960&edit=1
-- 
Fixed in CVS:        http://bugs.php.net/fix.php?id=16960&r=fixedcvs
Fixed in release:    http://bugs.php.net/fix.php?id=16960&r=alreadyfixed
Need backtrace:      http://bugs.php.net/fix.php?id=16960&r=needtrace
Try newer version:   http://bugs.php.net/fix.php?id=16960&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=16960&r=support
Expected behavior:   http://bugs.php.net/fix.php?id=16960&r=notwrong
Not enough info:     http://bugs.php.net/fix.php?id=16960&r=notenoughinfo
Submitted twice:     http://bugs.php.net/fix.php?id=16960&r=submittedtwice



Thread (8 messages)

« previous php.bugs (#6696) next »