Merge "lwt: for each statement in cas_request provide a row in CAS result set" from Pavel Solodovnikov

Previously batch statement result set included rows for only
those updates which have a prefetch data present (i.e. there
was an "old" (pre-existing) row for a key).

Also, these rows were sorted not in the order in which statements
appear in the batch, but in the order of updated clustering keys.

If we have a batch which updates a few non-existent keys, then
it's impossible to figure out which update inserted a new key
by looking at the query response. Not only because the responses
may not correspond to the order of statements in the batch, but
even some rows may not show up in the result set at all.

Please see #7113 on Github for detailed description
of the problem:
https://github.com/scylladb/scylla/issues/7113

The patch set proposes the following fix:

For conditional batch statements the result set now always
includes a row for each LWT statement, in the same order
in which individual statements appear in the batch.

This way we can always tell which update did actually insert
a new key or update the existing one.

Technically, the following changes were made:
 * `update_parameters::prefetch_data::row::is_in_cas_result_set`
   member removed as well as the supporting code in
   `cas_request::applies_to` which iterated through cas updates
   and marked individual `prefetch_data` rows as "need to be in
   cas result set".
 * `cas_request::applies_to` substantially simplified since it
   doesn't do anything more than checking `stmt.applies_to()`
   in short-circuiting manner.
 * `modification_statement::build_cas_result_set` method moved
   to `cas_request`. This allows to easily iterate through
   individual `cas_row_update` instances and preserve the order
   of the rows in the result set.
 * A little helper `cas_request::find_old_row`
   is introduced to find a row in `prefetch_data` based on the
   (pk, ck) combination obtained from the current `cas_request`
   and a given `cas_row_update`.
 * A few tests for the issue #7113 are written, other lwt-batch-related
   tests adjusted accordingly.
This commit is contained in:
Tomasz Grabiec
2020-09-04 16:09:45 +02:00
9 changed files with 426 additions and 110 deletions

View File

@@ -1105,6 +1105,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -1130,6 +1133,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -1532,6 +1538,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true",
"a" : "2",
"b" : "2"
},
{
"[applied]" : "true",
"a" : "2",
@@ -1560,6 +1571,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true",
"a" : "4",
"b" : "4"
},
{
"[applied]" : "true",
"a" : "4",
@@ -1588,6 +1604,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true",
"a" : "5",
"b" : "5"
},
{
"[applied]" : "true",
"a" : "5",
@@ -1616,6 +1637,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -1642,6 +1666,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false",
"a" : "3",
"b" : "3"
},
{
"[applied]" : "false",
"a" : "3",
@@ -1656,6 +1685,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false",
"a" : "3",
"b" : "3"
},
{
"[applied]" : "false",
"a" : "3",
@@ -1670,6 +1704,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false",
"a" : "3",
"b" : "3"
},
{
"[applied]" : "false",
"a" : "3",
@@ -1684,6 +1723,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false",
"a" : "3",
"b" : "3"
},
{
"[applied]" : "false",
"a" : "3",
@@ -1698,6 +1742,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false",
"a" : "3",
"b" : "3"
},
{
"[applied]" : "false",
"a" : "3",
@@ -1724,6 +1773,11 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false",
"a" : "6",
"b" : "6"
},
{
"[applied]" : "false",
"a" : "6",
@@ -1970,6 +2024,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -1995,6 +2052,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false"
},
{
"[applied]" : "false"
}
@@ -2011,6 +2071,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false"
},
{
"[applied]" : "false"
}
@@ -2027,6 +2090,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false"
},
{
"[applied]" : "false"
}
@@ -2043,6 +2109,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false"
},
{
"[applied]" : "false"
}
@@ -2059,6 +2128,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false"
},
{
"[applied]" : "false"
}
@@ -2077,6 +2149,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "false"
},
{
"[applied]" : "false"
}
@@ -2093,6 +2168,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -2117,6 +2195,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -2141,6 +2222,9 @@ APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}

View File

@@ -221,4 +221,46 @@ begin batch
insert into lwt (key, ck, cv) values (1, 0, {'b', 'c'})
apply batch;
select * from lwt;
drop table lwt;
drop table lwt;
--
-- A test case for Issue #7113
-- Return one row per each LWT statement
-- in a batch, in statement order.
--
CREATE TABLE IF NOT EXISTS gh7113 (
part int,
key int,
lwt_trivial int,
int1 int,
int2 int,
PRIMARY KEY (part, key)
);
BEGIN BATCH
UPDATE gh7113 SET int1 = 6 WHERE part = 0 AND key = 4 IF lwt_trivial = null
APPLY BATCH;
BEGIN BATCH
UPDATE gh7113 SET int2 = 0, int1 = 0 WHERE part = 0 AND key = 0 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 1, int1 = 6 WHERE part = 0 AND key = 7 IF lwt_trivial = null
APPLY BATCH;
BEGIN BATCH
UPDATE gh7113 SET int2 = 0, int1 = 2 WHERE part = 0 AND key = 9 IF lwt_trivial = null
UPDATE gh7113 SET int1 = 7 WHERE part = 0 AND key = 0 IF lwt_trivial = null
APPLY BATCH;
BEGIN BATCH
UPDATE gh7113 SET int1 = 6, int2 = 7 WHERE part = 0 AND key = 1 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 4 WHERE part = 0 AND key = 0 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 2 WHERE part = 0 AND key = 3 IF lwt_trivial = null
APPLY BATCH;
BEGIN BATCH
UPDATE gh7113 SET int2 = 1 WHERE part = 0 AND key = 4 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 1 WHERE part = 0 AND key = 0 IF lwt_trivial = null
UPDATE gh7113 SET int1 = 4, int2 = 8 WHERE part = 0 AND key = 9 IF lwt_trivial = null
UPDATE gh7113 SET int1 = 0, int2 = 9 WHERE part = 0 AND key = 0 IF lwt_trivial = null
APPLY BATCH;

View File

@@ -68,6 +68,9 @@ apply batch;
"[applied]" : "false",
"a" : "1",
"b" : "1"
},
{
"[applied]" : "false"
}
]
}
@@ -83,6 +86,9 @@ apply batch;
"[applied]" : "false",
"a" : "1",
"b" : "1"
},
{
"[applied]" : "false"
}
]
}
@@ -127,6 +133,11 @@ apply batch;
{
"rows" :
[
{
"[applied]" : "false",
"a" : "1",
"b" : "1"
},
{
"[applied]" : "false",
"a" : "1",
@@ -204,6 +215,9 @@ apply batch;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -245,6 +259,9 @@ apply batch;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
@@ -279,6 +296,9 @@ apply batch;
"b" : "1",
"c" : "[\"1\"]",
"d" : "[\"1\", \"2\"]"
},
{
"[applied]" : "true"
}
]
}
@@ -310,6 +330,9 @@ apply batch;
"a" : "1",
"b" : "1",
"c" : "[\"1\", \"3\"]"
},
{
"[applied]" : "true"
}
]
}
@@ -450,6 +473,13 @@ apply batch;
{
"rows" :
[
{
"[applied]" : "true",
"a" : "1",
"b" : "1",
"c" : "1",
"d" : "1"
},
{
"[applied]" : "true",
"a" : "1",
@@ -543,6 +573,12 @@ apply batch;
"c" : "1",
"i" : "1",
"p" : "1"
},
{
"[applied]" : "false",
"c" : "2",
"i" : "2",
"p" : "1"
}
]
}
@@ -559,6 +595,12 @@ apply batch;
"c" : "1",
"i" : "1",
"p" : "1"
},
{
"[applied]" : "true",
"c" : "2",
"i" : "2",
"p" : "1"
}
]
}
@@ -572,6 +614,13 @@ apply batch;
[
{
"[applied]" : "false"
},
{
"[applied]" : "false",
"c" : "2",
"i" : "2",
"l" : "[1, 3, 4]",
"p" : "1"
}
]
}
@@ -589,6 +638,13 @@ apply batch;
"i" : "2",
"l" : "[1, 2]",
"p" : "1"
},
{
"[applied]" : "true",
"c" : "2",
"i" : "2",
"l" : "[1, 3, 4]",
"p" : "1"
}
]
}
@@ -633,6 +689,9 @@ apply batch;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true",
"p" : "1",
@@ -690,6 +749,12 @@ apply batch;
{
"rows" :
[
{
"[applied]" : "true",
"ck" : "0",
"cv" : "[\"a\", \"b\"]",
"key" : "1"
},
{
"[applied]" : "true",
"ck" : "0",
@@ -730,6 +795,12 @@ apply batch;
{
"rows" :
[
{
"[applied]" : "true",
"ck" : "0",
"cv" : "[\"a\", \"b\"]",
"key" : "1"
},
{
"[applied]" : "true",
"ck" : "0",
@@ -753,3 +824,121 @@ drop table lwt;
{
"status" : "ok"
}
--
-- A test case for Issue #7113
-- Return one row per each LWT statement
-- in a batch, in statement order.
--
CREATE TABLE IF NOT EXISTS gh7113 (
part int,
key int,
lwt_trivial int,
int1 int,
int2 int,
PRIMARY KEY (part, key)
);
{
"status" : "ok"
}
BEGIN BATCH
UPDATE gh7113 SET int1 = 6 WHERE part = 0 AND key = 4 IF lwt_trivial = null
APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
}
]
}
BEGIN BATCH
UPDATE gh7113 SET int2 = 0, int1 = 0 WHERE part = 0 AND key = 0 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 1, int1 = 6 WHERE part = 0 AND key = 7 IF lwt_trivial = null
APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true"
}
]
}
BEGIN BATCH
UPDATE gh7113 SET int2 = 0, int1 = 2 WHERE part = 0 AND key = 9 IF lwt_trivial = null
UPDATE gh7113 SET int1 = 7 WHERE part = 0 AND key = 0 IF lwt_trivial = null
APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true",
"key" : "0",
"part" : "0"
}
]
}
BEGIN BATCH
UPDATE gh7113 SET int1 = 6, int2 = 7 WHERE part = 0 AND key = 1 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 4 WHERE part = 0 AND key = 0 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 2 WHERE part = 0 AND key = 3 IF lwt_trivial = null
APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true"
},
{
"[applied]" : "true",
"key" : "0",
"part" : "0"
},
{
"[applied]" : "true"
}
]
}
BEGIN BATCH
UPDATE gh7113 SET int2 = 1 WHERE part = 0 AND key = 4 IF lwt_trivial = null
UPDATE gh7113 SET int2 = 1 WHERE part = 0 AND key = 0 IF lwt_trivial = null
UPDATE gh7113 SET int1 = 4, int2 = 8 WHERE part = 0 AND key = 9 IF lwt_trivial = null
UPDATE gh7113 SET int1 = 0, int2 = 9 WHERE part = 0 AND key = 0 IF lwt_trivial = null
APPLY BATCH;
{
"rows" :
[
{
"[applied]" : "true",
"key" : "4",
"part" : "0"
},
{
"[applied]" : "true",
"key" : "0",
"part" : "0"
},
{
"[applied]" : "true",
"key" : "9",
"part" : "0"
},
{
"[applied]" : "true",
"key" : "0",
"part" : "0"
}
]
}