Ostico / PhpOrient

PhpOrient - Official Php driver based on the binary protocol of OrientDB.
Other
68 stars 37 forks source link

PhpOrient doesn't properly handle saving of "null" value fields #15

Closed alaimos closed 9 years ago

alaimos commented 9 years ago

PHP Code to reproduce bug:

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
require('ws/vendor/autoload.php');

try {

    $client = new \PhpOrient\PhpOrient('localhost', 2424);
    $client->username = 'root';
    $client->password = 'vagrant';
    $client->connect();
    $doCreate = false;
    if (!$client->dbExists('temp')) {
        $client->dbCreate('temp', \PhpOrient\Protocols\Common\Constants::STORAGE_TYPE_MEMORY,
            \PhpOrient\Protocols\Common\Constants::DATABASE_TYPE_DOCUMENT);
        $doCreate = true;
    }
    $client->dbOpen('temp');
    if ($doCreate) {
        $client->sqlBatch('
            create class Prova1;
            create property Prova1.aString string;
            insert into Prova1 (aString) VALUES ("b"),("c"),("d");
            create class Prova2;
            create property Prova2.aString string;
            create property Prova2.anEmbeddedSetOfString embeddedset string;
            create property Prova2.prova1 link Prova1;');
    }

    $clusterProva1 = $client->query("select classes[name='Prova1'].defaultClusterId from 0:1", -1)[0]['classes'];
    $clusterProva2 = $client->query("select classes[name='Prova2'].defaultClusterId from 0:1", -1)[0]['classes'];

    echo "Default cluster for Prova1: $clusterProva1\n";
    echo "Default cluster for Prova2: $clusterProva2\n\n";

    $newRecord = ['oClass' => 'Prova2', 'oData' => [
        'aString'               => 'record di prova',
        'anEmbeddedSetOfString' => ['qualcosa 1', 'qualcosa 2', 'ancora altro'],
        'prova1'                => null
    ]];

    $newRecordObject = \PhpOrient\Protocols\Binary\Data\Record::fromConfig($newRecord);
    $newRecordObject->setRid(new \PhpOrient\Protocols\Binary\Data\ID($clusterProva2));

    $tmp = $client->recordCreate($newRecordObject);

    $record = $client->recordLoad($tmp->getRid())[0];

    print_r($record->getOData());

} catch (\Exception $e) {
    echo $e . "\n";
}

_Expected Result:_

    Default cluster for Prova1: 9
    Default cluster for Prova2: 10

    Array
    (
        [aString] => record di prova
        [anEmbeddedSetOfString] => Array
            (
                [0] => ancora altro
                [1] => qualcosa 1
                [2] => qualcosa 2
            )

        [prova1] =>
    )

_Actual outcome obtained after code execution:_

    Default cluster for Prova1: 9
    Default cluster for Prova2: 10

    Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 1731087990 bytes) in /vagrant/src/www/ws/vendor/ostico/phporient/src/PhpOrient/Protocols/Binary/OrientSocket.php on line 135

_Output of "select * from Prova2" from OrientDb Console:_

    vagrant@vagrant-ubuntu-trusty-64:~$ /opt/orientdb/bin/console.sh

    OrientDB console v.2.0 (build UNKNOWN@r; 2015-01-20 16:41:17+0000) www.orientechnologies.com
    Type 'help' to display all the supported commands.
    Installing extensions for GREMLIN language v.2.6.0

    orientdb> connect remote:localhost/temp root vagrant;

    Connecting to database [remote:localhost/temp] with user 'root'...OK
    orientdb {db=temp}> SELECT * FROM Prova2

    ----+-----+------+---------------+---------------------+------
    #   |@RID |@CLASS|aString        |anEmbeddedSetOfString|prova1
    ----+-----+------+---------------+---------------------+------
    0   |#10:0|Prova2|record di prova|[3]                  |#-1:-1
    ----+-----+------+---------------+---------------------+------

    1 item(s) found. Query executed in 0.002 sec(s).

_Environment:_

_Possible cause of the bug:_ From "https://github.com/orientechnologies/orientdb/wiki/Record-CSV-Serialization":

    Null fields have an empty value part of the field. E.g. salary_cloned:,salary:

_Proposed fix:_

In class \PhpOrient\Protocols\Binary\Serialization\CSV line 499 replace:

    return 'null';

with:

    return '';
Ostico commented 9 years ago

Hi @alaimos ,

i tried the code and I have no exceptions or fatal errors, both on 32-bit platform than on 64bit.

I also think that the bug is related to the null value, but this is a OrientDB bug or wrong communication issue . You used an old version of OrientDB.

On your version i found:

2015-03-07 18:20:55:843 INFO  /127.0.0.1:39200 - Flush [OChannelBinaryServer]Sent run-time exception to the client /127.0.0.1:39200: java.lang.NullPointerException

I tried with OrientDB 2.0.2 and all works fine.

By the way. applying your patch the communication works on both versions.

Tnx, i will patch master branch as soon as possible.