Prepare and execute a query in CQL - cassandra

Hello i have read a lots of docs and articles, but i couldn't find any CQL commands that can Prepare and execute a query, i want the client to send PREPARE and EXECUTE requests to the server, is there any way to call that requests manually ?
For example i found a PostgreSQL command that Prepare a query then execute it:
PREPARE fooplan (int, text, bool, numeric) AS
INSERT INTO foo VALUES($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
How can i do the same in CQL ?

You can't do this in the pure CQL - the prepare/execute is available only in drivers.
So, for example, for Java it will be:
PreparedStatement prepared = session.prepare(
"insert into product (sku, description) values (?, ?)");
BoundStatement bound = prepared.bind("234827", "Mouse");
session.execute(bound);
In other languages, approach is the same (although there c. You prepare statement once (it should be stored somewhere for reuse), then you create a bound statement providing the actual data values, and that bound statement is then executed.

Related

Howto expose a native SQL function as a predicate

I have a table in my database which stores a list of string values as a jsonb field.
create table rabbits_json (
rabbit_id bigserial primary key,
name text,
info jsonb not null
);
insert into rabbits_json (name, info) values
('Henry','["lettuce","carrots"]'),
('Herald','["carrots","zucchini"]'),
('Helen','["lettuce","cheese"]');
I want to filter my rows checking if info contains a given value.
In SQL, I would use ? operator:
select * from rabbits_json where info ? 'carrots';
If my googling skills are fine today, I believe that this is not implemented yet in JOOQ:
https://github.com/jOOQ/jOOQ/issues/9997
How can I use a native predicate in my query to write an equivalent query in JOOQ?
For anything that's not supported natively in jOOQ, you should use plain SQL templating, e.g.
Condition condition = DSL.condition("{0} ? {1}", RABBITS_JSON.INFO, DSL.val("carrots"));
Unfortunately, in this specific case, you will run into this issue here. With JDBC PreparedStatement, you still cannot use ? for other usages than bind variables. As a workaround, you can:
Use Settings.statementType == STATIC_STATEMENT to prevent using a PreparedStatement in this case
Use the jsonb_exists_any function (not indexable) instead of ?, see https://stackoverflow.com/a/38370973/521799

Does pg (node-postgres) automatically sanitize data

I am using node-postgres for a production application and I am wondering if there is anything I should be concerned about? Is the data sanitized automatically by node-postgres?
I couldn't find anything about it on the github page: https://github.com/brianc/node-postgres
Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:
client.query("INSERT INTO user(name) VALUES($1)", ["'; DROP TABLE user;"], function (err, result) {
// ...
});
This is from their documentation.
It basically depends on how you execute your queries as #vitaly-t described
Suppose you will define query in a string and execute as follows:
var query = `SELECT * FROM table where username='${username}' and password='${password}`;
pool.query(query, (error, results) => {
});
This case if i would pass username=' 'or 1=1; -- and password=' 'or 1=1; --
Then it will return all records from the table (means SQL injection works)
But if I would execute the following query
pool.query('SELECT * FROM table where username=$1 and password=$2', [username, password], (error, results) => {
});
Then SQL injection will never work because pg will sanitize the data.
So it's depends on how you execute the queries.
It depends on how you execute your queries:
Formatting via Prepared Statements is executed by the server, which in turn sanitizes your query from any SQL injection. But it has other restrictions, like you cannot execute more than one query at a time, and you cannot provide sanitizied entity names when needed.
Client-side query formatting, like the one implemented by pg-promise, sanitizes values, plus offers flexibility in formatting entity names and multiple queries.

Using variables while inserting in Cassandra

I am new to Cassandra and trying to write a program in C# for insertion and deletion.
I want to know if there is a way i can use variables instead of values in the insert command ?
When i try the following:
string s1="A";
string s2="B";
session.Execute("insert into users (lastname, firstname) values (s1,s2)");
The error occurs: A first chance exception of type 'Cassandra.SyntaxError' occurred in Cassandra.dll
Assuming that you are using the DataStax CQL3 C# Driver, the best way to go about this is to use a prepared statement. Once you set that up, you bind your variables and Execute, like this:
string strCQL = "INSERT INTO users (lastname, firstname) VALUES (?,?)";
string s1 = "A";
string s2 = "B";
PreparedStatement preparedStatement = session.Prepare(strCQL);
BoundStatement boundStatement = preparedStatement.Bind(s1,s2);
session.Execute(boundStatement);
Please don't ever build a CQL statement with string.Format (or string concatenation) and execute it. Cassandra/CQL can also be subject to injection-based attacks, so you should always use a prepared statement and bind your variables to it. Also, if you have a statement that you are going to run multiple times (ex: within a loop), you can get better performance by preparing it prior to the loop, and binding/executing within.
You need String.format or better yet use prepared statements.
http://www.datastax.com/documentation/developer/csharp-driver/2.1/csharp-driver/reference/21features/namedParameters.html

cassandra cql query substitution

Explanation with an example:
import cql
cql connect to CF/Keyspace
last_key = XYZ (say it's getting fetched from else where)
cursor.execute(select * from domain_dimension where key=:key", key="last_key")
The CQL documentation says it can be done, but on console it says execute() got unexpected keyword argument.
Does Cassandra CQL really support query substitution?
It looks like you need to pass the substitutions in a dict as a single arg, not as keyword args.
cursor.execute("select * from domain_dimension where key=:key", {'key': last_key})
That is how it specified in the example on the project homepage: http://code.google.com/a/apache-extras.org/p/cassandra-dbapi2/

Cassandra Client - examining columns as Strings

I am new to Cassandra & I am using the Hector Java Client for writing/reading from it.
I've the following code to insert values -
Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());
mutator.insert("jsmith", stdColumnDefinition, HFactory.createStringColumn("first", "John"));
Now, when I get the values back via the Hector client - it works cleanly -
columnQuery.setColumnFamily(stdColumnDefinition).setKey("jsmith").setName("first");
QueryResult<HColumn<String, String>> result = columnQuery.execute();
However, when I try to get the values from the command line cassandra client, I get the data in bytes, rather than human readable String format. Is there a way for me to fix this so that I can use the cassandra client to spit out Strings -
here is the sample output
[default#keyspaceUno] list StandardUno ;
Using default limit of 100
RowKey: 6a736d697468
=> (column=6669727374, value=4a6f686e, timestamp=1317183324576000)
=> (column=6c617374, value=536d697468, timestamp=1317183324606000)
1 Row Returned.
Thanks.
You can either modify the schema so that Cassandra interprets the column as a string by default, or you can tell the CLI how to interpret the data, either on a one-shot basis, or for the rest of the session, using the "assume" command.
See http://www.datastax.com/docs/0.8/dml/using_cli#reading-rows-and-columns for examples.

Resources