thibaultcha / lua-cassandra

Pure Lua driver for Apache Cassandra
https://thibaultcha.github.io/lua-cassandra
Other
98 stars 35 forks source link

Trying to run prepare statements on cluster #93

Closed avadhutp closed 7 years ago

avadhutp commented 7 years ago

So, I am trying to run a prepared statement on a cluster. I have a cluster object like so:

local cluster, err = Cluster.new {
    shm = 'cassandra_conn_set',
    contact_points = {HOST:PORT},
    keyspace = CASSANDRA_KEYSPACE,
    timeout_connect = CASSANDRA_CONNECT_TIMEOUT,
}

if err ~= nil then
   ngx.log(ngx.ERR, 'Cassandra connection error: ' .. err)
   return nil
end

cluster:refresh()                                                         
cluster.prepared_ids = {}

I then generata a prepared statement like so:

local stmt = 'SELECT * FROM SOMETABLE WHERE x = ?'

local coordinator = cluster:first_coordinator()
local query_id = cluster:get_or_prepare(coordinator, stmt)

cluster.prepared_ids[stmt] = query_id

I try to run this query on the cluster like so:

local res, err = cluster:execute(
    cluster.prepared_ids[stmt],
    {123},
    {prepared = false}
)

But I see an error like so:

2017/04/20 09:18:39 [error] 20#0: *118 [lua] datastores.lua:257: execute(): Cassandra error: could not prepare query: [Protocol error] Cannot decode string as UTF8: 'cec0a523972eadbf922132ce0a8f'; java.nio.charset.MalformedInputException: Input length = 1, client: 10.5.0.4, server: , request: "GET /timestamp/uncacheable_header HTTP/1.1", host: "10.5.0.2:8888"

I see that in your code here, when you see that opts.prepared is set to true, you go ahead and execute get_or_prepare again. Is this correct? Should we not simply do this:

if opts.prepared then
    -- query is the prepared query id
    request = prep_req(query, args, opts)
else
    request = query_req(query, args, opts)
end

return send_request(self, coordinator, request)
thibaultcha commented 7 years ago

Yes, it is correct to call get_or_prepare there. I would highly recommend not try to work around the cluster module and simply use it as it is intended to be, which means passing this plain query but setting the prepared = true option.

avadhutp commented 7 years ago

@thibaultcha You're right. Thanks.