Files
scylladb/db
Dawid Mędrek f913ae571f db/view: Don't generate view updates for unselected columns
The semantics of Scylla's materialized views may vary depending on how their
primary keys correspond to the base table's one. One of the differences is
how we handle writes to columns in the base table that are not selected by
a view:

* Case 1: The view's PK is a permutation of the base table's PK:

  Since the view's primary key cannot be changed in an update, a row in
  the view remains alive as long as the corresponding row in the base table
  is alive.

  The tricky part comes when the base table has columns that are NOT selected
  by the view. CQL3 used to not allow for defining a table that didn't have
  any other columns besides its primary key. Also, when inserting a row into
  a table, it was mandatory to provide at least one value aside from the
  primary key. At some point it changed [1] and the implementation of the
  solution relied on the notion of the row marker.

  Putting the details aside, consider the following scenario:

  (i)   the base table has a primary key consisting of columns
        c_1, ..., c_k, and it has regular columns rc_1, ..., rc_n,
  (ii)  the primary key of an MV defined on that table consists of
        a permutation of c_1, ..., c_k. The MV doesn't select at least
        one of the regular columns of the base table. Without loss of
        generality, let that unselected column be rc_1.
  (iii) the base table has a row R whose only non-null value is the one
        in the regular column rc_1.

  Now, what will R correspond to in the MV? The base table doesn't have a row
  marker, but all of its regular columns in the MV will be NULLs. That's NOT
  allowed.

  To solve that problem, all unselected columns have corresponding virtual
  columns in the MV; the only information they provide is whether there is
  a value in the base table or not. This way, the MV knows if a row is still
  alive or not.

  For that reason, we send view updates to virtual columns in the following
  cases:

  (i)  the value in the column changes from NULL to a value, i.e. it's
       created,
  (ii) the value in the column exists, but its TTL has been updated.

* Case 2: The view's PK has one more column that the base table's one:

  Since the primary key of the view has a regular column C from the base
  table, it is guaranteed that if there's a row in the MV, the corresponding
  row in the base table can remain alive: since C is part of the view's PK,
  it must have a value, so the row in the base table has a value in C too.
  The problem with virtual columns from the previous case doesn't manifest
  in this one. The liveness of the cell in C determines the liveness of
  the whole row in the view.

The semantics gets more complex, but the conclusion is this: in case 1,
virtual columns exist and we may need to generate view updates for them,
while in case 2 virtual columns do NOT exist and so we don't generate
view updates for them.

What changes in this patch is we adjust the code to it. If a view has
a regular column from the base table as part of its primary key, we
no longer emit view updates when we change a column unselected by that
view. It is purely an OPTIMIZATION change.

[1]: https://issues.apache.org/jira/browse/CASSANDRA-4361

Fixes scylladb/scylladb#21652

Closes scylladb/scylladb#21653
2024-11-24 19:01:28 +02:00
..
2024-10-04 20:48:18 +08:00
2024-10-04 20:48:18 +08:00
2024-10-04 20:48:18 +08:00
2024-10-04 20:48:18 +08:00
2024-10-04 20:48:18 +08:00