phpcassandraprepared-statementdatastax-php-driver

Cassandra Prepared Statements error with datastax php driver


I'm facing strange error with Prepared Statements with DataStax php driver 1.0.0-rc and Cassandra 2.2.3. I got an Exception on this line:

$statement = $this->session->prepare("SELECT ? FROM ? WHERE ? = ?");

I am seeing this error:

"error_code":33562624
"error_message":"Bind variables cannot be used for keyspace names"

Below a stub of class used to comunicate with Cassandra:

class ClsCassandra extends ClsDbObject
{
    private $hostname="";
    private $username="";
    private $password="";
    private $keyspace="";
    private $poi_table="";
    private $poi_table_key_field="";
    private $poi_table_content_field="";

    private $cluster = NULL;
    private $session = NULL;

    private $threads = 1;

    function __construct()
    {
        ...
        ...
        //
        // i set up all the properties above
        //
        ...
        ...
    }

    public function runQuery(&$error)
    {
        try 
        {           
            $this->cluster   = Cassandra::cluster()
            ->withContactPoints($this->hostname)
            ->withCredentials($this->username, $this->password)
            ->withIOThreads($this->threads)
            ->build();

            $this->session = $this->cluster->connect($this->keyspace);

            // error on next line...
            $statement = $this->session->prepare("SELECT ? FROM ? WHERE ? = ?");
            $results = $this->session->execute($statement, new Cassandra\ExecutionOptions(array(
                    'arguments' => array($this->poi_table_content_field, $this->poi_table, $this->poi_table_key_field, $keypattern)
            )));

        }
        catch(Cassandra\Exception $ce)
        {
            $error->setError($ce->getCode(), $ce->getMessage(), $ce->getTraceAsString());
            $this->log(LOG_LEVEL, $error->getErrorMessage(), __FILE__, __LINE__, __CLASS__);
            return false;
        }
        return true;
    }

    ...
    ...
    ...
}

If I use Simple Statemetn with standard select query instead it works.

Any suggestions?


Solution

  • You are seeing this error because you can only bind variables to the WHERE clause. The prepared statement mechanism isn't just a glorified string formatter. It has rules about what can and cannot be bound, and how you have to bind things to remove any ambiguity when sending to Cassandra.

    You'll need to try something like this:

    $statement = $this->session->prepare(
        "SELECT key1, key2, col1, col2 FROM yourKeyspaceName.yourTableName WHERE key1 = ? AND key2 = ?");
    $results = $this->session->execute($statement, new Cassandra\ExecutionOptions(array(
        'arguments' => array($key1,$key2)
        )));