Inserting special characters - cassandra

I'm trying to insert special characters in my Cassandra table but I couldn't insert it.
Inserting data in table with umlaut is not possible
As mentioned in the link i tried above link even though my character set is UTF8 as mentioned.I'm not able to insert. I've tried using quotes also still didn't work
CREATE TABLE test.calendar (
race_id int,
race_start_date timestamp,
race_end_date timestamp,
race_name text,
PRIMARY KEY (race_id, race_start_date, race_end_date)
) WITH CLUSTERING ORDER BY (race_start_date ASC, race_end_date ASC
insert into test.calendar (race_id, race_start_date , race_end_date , race_name ) values (501,2016-02-18 05:00:00+0000 ,2016-02-22 05:00:00+0000 ,'Hotel in der Nähe von mir');
ERROR MESSAGE :
SyntaxException: <ErrorMessage code=2000 [Syntax error in CQL query] message="line 1:99 mismatched input '-02' expecting ')' (...race_name ) values (501,2016[-02]-18...)">

You didn't quote your date values, so 2016-02-22 05:00:00+0000 is seen as "2016 minus 02 minus 22 blah blah blah" - an arithmetic operation followed by some random numerical garbage.
Try
INSERT .... VALUES(... '2016-02-22 05:00:00+0000', ...)
^------------------------^
instead. Note the ' quotes.

Related

ScyllaDB - [Invalid query] message="marshaling error: Milliseconds length exceeds expected (6)"

I have a table with a column of type timestamp and when I insert a value, Scylla saves it with 3 zeros more.
According to Scylla Documentation (https://docs.scylladb.com/getting-started/types/#timestamps):
Timestamps can be input in CQL either using their value as an integer, or using a string that represents an ISO 8601 date. For instance, all of the values below are valid timestamp values for Mar 2, 2011, at 04:05:00 AM, GMT:
1299038700000
'2011-02-03 04:05+0000'
'2011-02-03 04:05:00+0000'
'2011-02-03 04:05:00.000+0000'
'2011-02-03T04:05+0000'
'2011-02-03T04:05:00+0000'
'2011-02-03T04:05:00.000+0000'
So when I create a table for example:
CREATE TABLE callers (phone text, timestamp timestamp, callID text, PRIMARY KEY(phone, timestamp));
And insert values into it:
INSERT INTO callers (phone, timestamp, callID) VALUES ('6978311845', 1299038700000, '123');
INSERT INTO callers (phone, timestamp, callID) VALUES ('6978311846', '2011-02-03 04:05+0000', '456');
INSERT INTO callers (phone, timestamp, callID) VALUES ('6978311847', '2011-02-03 04:05:00.000+0000', '789');
The SELECT * FROM callers; will show all timestamps with 3 zeros more after the dot:
phone | timestamp | callid
------------+---------------------------------+--------
6978311847 | 2011-02-03 04:05:00.000000+0000 | 789
6978311845 | 2011-03-02 04:05:00.000000+0000 | 123
6978311846 | 2011-02-03 04:05:00.000000+0000 | 456
As a result when I try for example to delete a row:
DELETE FROM callers WHERE phone = '6978311845' AND timestamp = '2011-03-02 04:05:00.000000+0000';
An error occurs:
InvalidRequest: Error from server: code=2200 [Invalid query] message="marshaling error: unable to parse date '2011-03-02 04:05:00.000000+0000': marshaling error: Milliseconds length exceeds expected (6)"
How can I store timestamp without getting this error?
You have hr:min:sec.millisec -> Millisec can be up to 999/1000 so essentially that's what the error is saying.
The 3 INSERT statement you did are correct in terms of syntax.
The DELETE statement should be in the same format as the INSERT:
AND timestamp = '2011-03-02 04:05:00.00+0000'
AND timestamp = '2011-03-02 04:05:00.000+0000'
AND timestamp = '2011-03-02 04:05:00+0000'
AND timestamp = '2011-03-02 04:05:00'
The additional 000 that appear in the table are just a display issue.

How to update timeuuid column in cassandra

How can I update a timeuuid column in Cassandra?
I tried the following query
cqlsh:mydb> UPDATE mytable SET mycolumn = '99b47d70-b465-11e9-8080-808080808080' WHERE mycolumn= '99a53b30-b465-11e9-8080-808080808080';
and it failed with message
InvalidRequest: Error from server: code=2200 [Invalid query] message="Invalid STRING constant (99b47d70-b465-11e9-8080-808080808080) for "mycolumn" of type timeuuid"
So I tried casting the constant values to timeuuid
cqlsh:mydb> UPDATE mytable SET mycolumn = cast('99b47d70-b465-11e9-8080-808080808080' as timeuuid) WHERE mycolumn= cast('99a53b30-b465-11e9-8080-808080808080' as timeuuid);
This time it failed with error
SyntaxException: line 1:34 no viable alternative at input '(' (UPDATE mytable SET mycolumn = cast
I saw the documentation on the cast function, and timeuuid is not listed under the output type for any other type.
https://docs.datastax.com/en/dse/5.1/cql/cql/cql_reference/refCqlFunction.html#refCqlFunction__cast
Does that mean a timeuuid column cannot be updated once created?
Update:
I came across the following information on the above page
UPDATE statements SET clause cannot be used to change PRIMARY KEY fields; therefore a new timeuuid can only be set if the target field is not part of the PRIMARY KEY field.
So, it is possible to update timeuuid columns. mycolumn is not part of the PRIMARY key.
Update 2:
Even the following command is failing with the same error no viable alternative at input
UPDATE website SET api_key = api_key WHERE 1;
So what is it that I am doing wrong?
I found the solution at Inserting a hard-coded UUID via CQLsh (Cassandra)
You shouldn't put the quotes around the UUID to stop it being interpreted as a string i.e.
There was no need to quote the uuid

How to convert 52:34 string value to bigint

How to cast a value 52:35 which is stored as a string in the DB and I want only 52 in BigInt value in PostgreSQL DB as a query.
I tried with this following query
select cast(substr(a,1,strpos(a,':')-1) AS bigint) as value from abc
which returned me an error "negative substring length not allowed"
That query will fail when it encounters a value that does not contain a colon :. Use a case...when...else...end construct to attempt the extraction only when the value contains a colon. Something like (untested)
CASE WHEN strpos(a,':') > 0
THEN cast(substr(a,1,strpos(a,':')-1) AS bigint
else null
END
For the else case, substitute whatever you need. There might also be a way to use split_part(...) instead of the above, but I had trouble finding documentation saying what happens if the delimiter is not present.
You could use split_part(string text, delimiter text, field int)
postgres=# select split_part('52:35', ':', 1)::bigint;
split_part
------------
52
postgres=# select split_part('52', ':', 1)::bigint;
split_part
------------
52

Does CQL3 support nested AND and OR

Given this sample table schema:
CREATE TABLE foo (
pk1 text,
pk2 text,
pk3 text,
pk4 text,
data map<text, text>,
PRIMARY KEY ((pk1, pk2, pk3), pk4)
);
I wonder if it is possible to have a query that selects different combinations of pk2, pk3, pk4 with a fixed pk1. Something like:
SELECT * FROM foo WHERE pk1 = 'abc' AND
((pk2 = 'x' AND pk3 = 'y' AND pk4 = 'z') OR ((pk2 = 'd' AND pk3 = 'e' AND pk4 = 'f'));
I don't get this working. I have a set of pk2, pk3, pk4 tuples and a fixed pk1 and want to select all matching rows using a single query if possible (Cassandra 2.2.x).
I wonder if it is possible to have a query that selects different combinations of pk2, pk3, pk4 with a fixed pk1.
No, it is not.
As Doan pointed out, OR is not supported (yet). This leaves you with AND which makes nesting WHERE conditions superfluous.
Also, adding parens around your AND parts is not supported either. Without parens this works, but not with them:
aploetz#cqlsh:stackoverflow> SELECT * FROM row_historical_game_outcome_data
WHERE customer_id=123123 AND (game_id=673 AND game_time = '2015-07-01 05:01:42+0000');
SyntaxException: <ErrorMessage code=2000 [Syntax error in CQL query] message="line 1:89 missing ')' at 'AND' (...=123123 AND (game_id=673 [AND] game_time...)">
That being said, the IN predicate will work on either the last partition or last clustering key. But using it on a partition key is considered to be an anti-pattern. In any case, in your case this would work (syntactically):
SELECT * FROM foo WHERE pk1 = 'abc' AND pk2 = 'x' AND pk3 = 'y' AND pk4 IN ('z','f');
CQL supports AND predicate on columns
that belong to the PRIMARY KEY
that are indexed by the secondary index system
OR predicate is not supported. It will be supported as future enhancement of the new SASI secondary index

CQL3 and millions of columns composite key use case

How in CQL3 do we do millions of columns? We have one special table where all rows are basically composite keys and very very wide.
I was reading this question that implied two ways
Does collections in CQL3 have certain limits?
Also, the types of our composite keys are String.bytes and ordered by STring
We have an exact matching table that is Decimal.bytes and ordered by decimal.
How would one handle this in CQL3?
thanks,
Dean
"oh, and part of my question was missing since SO formatted it out of the question. I was looking for Decimal.bytes and String.bytes as my composite key....there is no "value", just a col name and I want all columns were decimal > 10 and decimal < 20 so to speak and the column name = 10 occurs multiple times as in 10.a, 10.b 11.c, 11.d, 11.e"
CREATE TABLE widerow
(
row_key text, //whatever
column_composite1 decimal,
column_composite2 text,
PRIMARY KEY(row_key,column_composite1,column_composite2)
)
SELECT * FROM widerow WHERE row_key=...
AND column_composite1>=10.0
AND column_composite1<=20.0
In that case, you can query with range over column_composite1 and have for EACH column_composite1, different values of column_composite2 (10.a, 10.b 11.c, 11.d, 11.e...)
"How do I get all the columns where row_composite1 > "a" and row_composite1 < "b" in that use case? ie. I dont' care about the second half of the composite name. "
2 possible solutions here
Make row_composite1 a composite component of column
Use OrderPreservingPartitioner (this is indeed strongly discouraged)
For solution 1
CREATE TABLE widerow
(
fake_row_key text, //whatever
column_composite1 text, // previously row_composite1
column_composite2 decimal,
column_composite3 text,
PRIMARY KEY(row_key,column_composite1,column_composite2,column_composite3)
)
SELECT * FROM widerow WHERE row_key=...
AND column_composite1>='a'
AND column_composite1<='b'
This modeling has some drawback though. To be able to range query over DOUBLE values, you need to provide first the column_composite1:
SELECT * FROM widerow WHERE row_key=...
AND column_composite1='a'
AND column_composite2>=10.0
AND column_composite2<=20.0
CREATE TABLE widerow
(
row_composite1 text,
row_composite2 text,
column_name decimal,
value text,
PRIMARY KEY((row_composite1,row_composite2),column_name)
)
SELECT * FROM widerow WHERE row_composite1=...
AND row_composite2=...
AND column_name>=10.0
AND column_name<=20.0
ORDER BY column_name DESC

Resources