madhabkirank / google-api-adwords-php

Automatically exported from code.google.com/p/google-api-adwords-php
0 stars 0 forks source link

Bulk mutate job ID overflows float precision on 32-bit machines #55

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Which version of the library are you using?
2.5.1

Which version of PHP are you using?
5.2.6-windows, 5.3.5-linux

What steps will reproduce the problem?
0. Enable SOAP logs
1. Create new job in BulkMutateJobService
2. Get ID of this Job
3. Try to check status of already created job
4. On x86 machines you should get error. Check logs for matching IDs.
They will be different

What is the expected output? What do you see instead?
Id should be equal. For example if library get '-9184257096638504859', when it 
should send '-9184257096638504859', not '-9184257096638504978' or something 
like that.

Please provide any additional information below.
I've solve this problem by 2 steps:
1. Manual loading IDs. (Parsing SOAP reply as a string)
2. Creating Soap value by hand, like this:
// Create selector.
  $selector = '<ns1:jobIds>'.$jobId.'</ns1:jobIds>';
  $toSendSelector = new SoapVar('<ns1:selector xmlns:ns2="https://
adwords.google.com/api/adwords/cm/v201008"
xsi:type="ns2:BulkMutateJobSelector">'.$selector.'</ns1:selector>',
XSD_ANYXML); 

More details can be found on 
http://groups.google.com/group/adwords-api/browse_thread/thread/f01b24ffd022b26e
#

Original issue reported on code.google.com by evgeniy_...@mail.ru on 8 Apr 2011 at 5:28

GoogleCodeExporter commented 8 years ago
I believe this is related to how PHP and the SOAP Library handle integer 
values.  See the Issue #5 for more information.

Original comment by ekoleda+devrel@googlers.com on 11 Apr 2011 at 8:31

GoogleCodeExporter commented 8 years ago
It similar to Issue #5, but using cast type to float is not help for such 
digits.

Original comment by evgeniy_...@mail.ru on 11 Apr 2011 at 8:38

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
The issue here is on 32 bit systems, casting as a float doesn't help because 
the value will overflow a float. The log is generated not from the raw value 
received but after is has been processed by the SOAP addon which attempts to 
convert the long data type in a soap transfer to an int.

To fix this in AdsSoapClient.php I added an option to preform a custom 
conversion on long in the constructor:
    $options['typemap'] = array(
        array(
            'type_ns'=>'http://www.w3.org/2001/XMLSchema',
            'type_name'=>'long',
            'from_xml'=>'from_long_xml',
            'to_xml'=>'to_long_xml'
        )
    ); 
    parent::__construct($wsdl, $options);

Which then called these functions to handle the number as a string.

function to_long_xml($long_val)
{
    return '<long>'.$long_val.'</long>';
}

function from_long_xml($xml_fragment)
{
    return (string)strip_tags($xml_fragment);
}

Not exactly sure on the <long> tags, can apparently be named anything but 
worked with them and not without.

Original comment by rob...@gmail.com on 2 May 2011 at 5:02

GoogleCodeExporter commented 8 years ago
I like your approach of using typemap conversion functions to handle this case, 
but I don't understand why casting to a float didn't work in your case.  Can 
you go into more detail about the problems encountered when casting to floats?

Original comment by ekoleda+devrel@googlers.com on 2 May 2011 at 3:42

GoogleCodeExporter commented 8 years ago
Yes, type casting is good idea. :) Your implementation better than my.

@Eric, just try to call BulkMutateService example (in real environment not in 
sandbox) on x86 machine with your current code and you will see problem. 
Casting to float is not efficient because it will overflow error. Numbers will 
be striped and changed similar to problem with "int" in past, except that this 
is float and where no more way to go in.

Original comment by telesoci...@gmail.com on 2 May 2011 at 9:25

GoogleCodeExporter commented 8 years ago
Yeah, I'm not sure of the actual length because the my log is still displaying 
the overflowed number, but a job id for me would either overflow negative or 
stay positive but loose some precision so when passed back it would no longer 
be the same number.

Original comment by rob...@gmail.com on 4 May 2011 at 2:58

GoogleCodeExporter commented 8 years ago
Reopening, as this does appear to be an issue that isn't solved by casting to a 
float.

Original comment by ekoleda+devrel@googlers.com on 8 Jul 2011 at 3:28

GoogleCodeExporter commented 8 years ago
Fixed in r192.

Original comment by ekoleda+devrel@googlers.com on 8 Jul 2011 at 6:36

GoogleCodeExporter commented 8 years ago
Not at all informative

Original comment by mo...@proisc.com on 25 Jul 2011 at 1:28

GoogleCodeExporter commented 8 years ago
http://code.google.com/p/google-api-adwords-php/source/diff?spec=svn192&r=192&fo
rmat=side&path=/trunk/src/Google/Api/Ads/Common/Lib/AdsSoapClient.php

The library now attempts to cast longs as ints, and if they won't fit then 
tries floats, and if they still don't fit finally just leaves them as strings.  
This will ensure that getting the value and sending it back against will result 
in consistent output.

Original comment by ekoleda+devrel@googlers.com on 25 Jul 2011 at 2:05