[ 
https://issues.apache.org/jira/browse/CASSANDRA-12060?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15490098#comment-15490098
 ] 

Sylvain Lebresne commented on CASSANDRA-12060:
----------------------------------------------

I'll have to apologize here because while reviewing this I'm realizing that 
I've been confused and have pushed for the wrong thing.

My confusion had to do with the fact that CQL doesn't behave as I though it 
did. Let me explain. This ticket and CASSANDRA-9842 are about what differences 
CAS queries with conditions on static columns make between existing and 
non-existing partitions. For that, my guideline was to make it consistent with 
how CAS queries with conditions on regular columns differenciate between 
existing and non-existing rows, and that where I was wrong.

Let's consider the following example:
{noformat}
CREATE TABLE test (k int, t int, v int, PRIMARY KEY (k, t));
SELECT v FROM test WHERE k = 0 AND t = 0;
>  v
> ------
>
> (0 rows)
INSERT INTO test(k, t) VALUES (0, 0);
SELECT v FROM test WHERE k = 0 AND t = 0;
>  v
> ------
>  null
>
> (1 rows)
UPDATE test SET v = 42 WHERE k = 0 AND t = 1 IF v = 1;  // Note we try updating 
another row
>  [applied]
> -----------
>      False
UPDATE test SET v = 42 WHERE k = 0 AND t = 0 IF v = 1; // The row we've 
inserted before, but v is null
>  [applied] | v
> -----------+------
>      False | null
{noformat}
Both in SELECT and in CAS queries result set, we make a difference between a 
row existing or not existing. For some reason, I though this difference 
somewhat carried on to whether a {{IF v = null}} would apply (or any {{IF v != 
<something>}} condition). I was sure that it was applied if the row existed but 
had no value for {{v}} but did *not* applied if the row didn't existed at all. 
In other words, what I _though_ we had was:
{noformat}
UPDATE test SET v = 42 WHERE k = 0 AND t = 1 IF v = null; // Trying to updated 
a non existing row
>  [applied]
> -----------
>      False
UPDATE test SET v = 42 WHERE k = 0 AND t = 0 IF v = null; // The row exist and 
v is null
>  [applied]
> -----------
>       True
{noformat}
and I advocated we did the same for static columns and existing/non-existing 
partitions. But that's *not* how it works and the first query above does apply. 
That is, even though we always make a difference in result sets between 
existing row (but with null value) and non-existing row, we don't make one when 
evaluating if a {{IF v = null}} condition applies.

So anyway, what semantic would be better in theory doesn't matter much. The way 
{{IF v = null}} currently works for normal column is that it makes no 
difference between the row existing (and having no value for v) or not existing 
and it's probably too late to change that, so we should make that work 
consistently for static column and hence you should just have ignored me on 
this ticket since that's how it works in 3.0 after CASSANDRA-9842.

With that all said, we still should do what this ticket initiall sets to do: we 
should make that existing versus not existing partition difference for static 
columns in CAS result sets because that's how it works for rows/normal columns 
and we should be consistent.

Doing that last part requires most of the linked patch, though I have the 
following remarks on said patch:
* I'm not sure I understand the reason for the change in 
{{CQL3CasRequest.columnsToRead()}}. In particular, the comment talks about 
having to query a row, but that method is about which columns we bother 
fetching, not which row we query.
* I'm not fond of using {{null}} for empty partitions since we can just test 
with {{isEmpty()}} directly. Granted, the current code is confusing as 
{{appliesTo()}} test for {{null}} even though it's neither passed currently and 
that's really oversight from CASSANDRA-8099. I think we should stick to 
{{isEmpty()}} but remove the useless code.
* Regarding querying the first row of a partition when we only have static 
conditions, I think the code would be easier to follow if we separated static 
conditions in {{CQL3CasRequest}}. In fact, once we do that, we can also use 
names queries for "normal" conditions (instead of doing slices of one row, the 
former being potentially more optimized), which is not all that related to this 
patch tbh, but is kind of an oversight of the code so we might as well fix it 
while we're at it.

Anyway, as I felt bad about the back and forth on this, I took the liberty to 
made the changes related to what's above:
| [12060-3.0-v2|https://github.com/pcmanus/cassandra/commits/12060-3.0-v2] | 
[utests|http://cassci.datastax.com/job/pcmanus-12060-3.0-v2-testall] | 
[dtests|http://cassci.datastax.com/job/pcmanus-12060-3.0-v2-dtest] |
| [12060-trunk-v2|https://github.com/pcmanus/cassandra/commits/12060-trunk-v2] 
| [utests|http://cassci.datastax.com/job/pcmanus-12060-trunk-v2-testall] | 
[dtests|http://cassci.datastax.com/job/pcmanus-12060-trunk-v2-dtest] |


> Establish consistent distinction between non-existing partition and NULL 
> value for LWTs on static columns
> ---------------------------------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-12060
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-12060
>             Project: Cassandra
>          Issue Type: Bug
>            Reporter: Alex Petrov
>            Assignee: Alex Petrov
>
> When executing following CQL commands: 
> {code}
> CREATE KEYSPACE test WITH replication = {'class': 'NetworkTopologyStrategy', 
> 'datacenter1': '1' };
> USE test;
> CREATE TABLE testtable (a int, b int, s1 int static, s2 int static, v int, 
> PRIMARY KEY (a, b));
> INSERT INTO testtable (a,b,s1,s2,v) VALUES (2,2,2,null,2);
> DELETE s1 FROM testtable WHERE a = 2 IF s2 IN (10,20,30);
> {code}
> The output is different between {{2.x}} and {{3.x}}:
> 2.x:
> {code}
> cqlsh:test> DELETE s1 FROM testtable WHERE a = 2 IF s2 = 5;
>  [applied] | s2
> -----------+------
>      False | null
> {code}
> 3.x:
> {code}
> cqlsh:test> DELETE s1 FROM testtable WHERE a = 2 IF s2 = 5;
>  [applied]
> -----------
>      False
> {code}
> {{2.x}} would although return same result if executed on a partition that 
> does not exist at all:
> {code}
> cqlsh:test> DELETE s1 FROM testtable WHERE a = 5 IF s2 = 5;
>  [applied]
> -----------
>      False
> {code}
> It _might_ be related to static column LWTs, as I could not reproduce same 
> behaviour with non-static column LWTs. The most recent change was 
> [CASSANDRA-10532], which enabled LWT operations on static columns with 
> partition keys only. -Another possible relation is [CASSANDRA-9842], which 
> removed distinction between {{null}} column and non-existing row.- (striked 
> through since same happens on pre-[CASSANDRA-9842] code.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to