kreynolds/cassandra-cql — Issue #17: Quotes are quoted wrong.
Author: twhaples
Created: 2011-10-10 22:58:33+00:00
State: open

I have a Cassandra::Database handle, @handle.
I run ```@handle.execute(*args)```, where
```args = [
"insert into anonymizing_my_schema (KEY, ?) values (?, ?) USING consistency ANY",
,
"00cb0c2c-f38f-11e0-9adb-f7b503e95f4c__88:FE:74:43:DF:9F",
"{\"some_json\":\"this string's got some 'cool' quotes\",\"other_nonsense\":\"anonymized\"}",
]```

Thrift produces an exception:
```
CassandraCQL::Error::InvalidRequestException: line 1:290 mismatched character '' expecting '''
/Users/anonymized/.rvm/gems/ruby-1.9.2-p180@storenet/bundler/gems/cassandra-cql-257dcf6c622a/lib/cassandra-cql/database.rb:74:in `rescue in execute_cql_query'
/Users/anonymized/.rvm/gems/ruby-1.9.2-p180@storenet/bundler/gems/cassandra-cql-257dcf6c622a/lib/cassandra-cql/database.rb:72:in `execute_cql_query'
/Users/anonymized/.rvm/gems/ruby-1.9.2-p180@storenet/bundler/gems/cassandra-cql-257dcf6c622a/lib/cassandra-cql/statement.rb:34:in `execute'
/Users/anonymized/.rvm/gems/ruby-1.9.2-p180@storenet/bundler/gems/cassandra-cql-257dcf6c622a/lib/cassandra-cql/database.rb:61:in `execute'
/my/code:1234 in `anonymized'
```

Looking at the CQL gem, it appears when it tries to sanitize the query, it installs parameters by doing
```quote(cast_to_cql(bind_vars.shift))```

Now, on a string, self.quote returns
```"'" + escape(obj) + "'"```
But cast_to_cql already calls escape on strings:
```
elsif obj.kind_of?(String) and Utility.binary_data?(obj)
escape(obj.unpack('H*')[0])
else
escape(obj.to_s)
```

and escape is just defined as
```
def self.escape(obj)
obj.gsub("'", "\\\\'")
end
```
so we end up executing the following CQL:
```insert into anonymizing_my_schema (KEY, '52690c00-f2ea-11e0-86a3-92f41137a4fa') values ('6bd62b04-f390-11e0-86fd-42cdfbee4a2f__88:FE:74:43:DF:9F', '{"some_json":"this string\\'s got \\'cool\\' quotes","other_terms":"anonymized"}') USING consistency ANY```

There are two issues here:
* Calling escape twice is probably going to do the wrong thing most of the time.
* \' is not how you're supposed to escape a single quote: you're supposed to use two single-quotes (`''`) to be more like SQL.