evseevnn-zz / php-cassandra-binary

PHP library for Cassandra database via a binary protocol.
http://evseevnn.github.io/php-cassandra-binary/
MIT License
69 stars 33 forks source link

Limit on batches with prepared statements #49

Open paguan opened 9 years ago

paguan commented 9 years ago

Hey,

I'm playing around with your driver double checking if it fits our needs and just found out that when doing batches with preparedstatements and with more than 95 statements PHP crashes with "PHP Fatal error: Maximum function nesting level", this is coming from the recursive call to appendQueryToStack. This is working fine with normal statements though. Is there any way you can remove that recursion? I don't really like the idea of tune php configuration to support as many recursive calls as my biggest batch.

Thanks

evseevnn-zz commented 9 years ago

Please, show me the queries in which an error occurs.

paguan commented 9 years ago

This is a little example where this happens:

$connection = new Database($nodes); 
$connection->connect();
$connection->setKeyspace('tests');
$queryString = 'INSERT INTO test_table (tid, some_content) VALUES (:tid, :some_content)';
$connection->beginBatch();
for ($cont = 0; $cont < 100; $cont++) {
    $uuid = getUUID();
    $content = 'Random string with UUID: '.$uuid;
    echo 'Cont: '.$cont.' UUID: '.$uuid."\n";
    $connection->query($queryString, ['tid' => $uuid, 'some_content' => $content]);
}
$connection->applyBatch();
teanooki commented 9 years ago

There is a problem with the appendQueryToStack function in Database.php. Replacing the POSTFIX_DUPLICATE_QUERY_VARIABLE by an counter should work:

    /**
     * @var int
     */ 
    private $key_index = 0;

    private function appendQueryToStack($cql, array $values) {
        $valuesModified = false;
        foreach($values as $key => $value) {
            if (is_string($key) && isset($this->batchQueryData[$key])) {
                $newFieldName = $key . "_" . ++$this->key_index;
                $cql = str_replace(":{$key}", ":{$newFieldName}", $cql);
                unset($values[$key]);
                $values[$newFieldName] = $value;
                $valuesModified = true;
            }
        }
paguan commented 9 years ago

Yes, that fixed the issue.

Thanks guys