[ https://issues.apache.org/jira/browse/CASSANDRA-13776?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Josh McKenzie updated CASSANDRA-13776: -------------------------------------- Component/s: Local/SSTable > Adding a field to an UDT can corrupte the tables using it > --------------------------------------------------------- > > Key: CASSANDRA-13776 > URL: https://issues.apache.org/jira/browse/CASSANDRA-13776 > Project: Cassandra > Issue Type: Bug > Components: Local/SSTable > Reporter: Benjamin Lerer > Assignee: Benjamin Lerer > Priority: Urgent > Fix For: 3.0.15, 3.11.1, 4.0 > > > Adding a field to an UDT which is used as a {{Set}} element or as a {{Map}} > element can corrupt the table. > The problem can be reproduced using the following test case: > {code} > @Test > public void testReadAfterAlteringUserTypeNestedWithinSet() throws > Throwable > { > String ut1 = createType("CREATE TYPE %s (a int)"); > String columnType = KEYSPACE + "." + ut1; > try > { > createTable("CREATE TABLE %s (x int PRIMARY KEY, y set<frozen<" + > columnType + ">>)"); > disableCompaction(); > execute("INSERT INTO %s (x, y) VALUES(1, ?)", set(userType(1), > userType(2))); > assertRows(execute("SELECT * FROM %s"), row(1, set(userType(1), > userType(2)))); > flush(); > assertRows(execute("SELECT * FROM %s WHERE x = 1"), > row(1, set(userType(1), userType(2)))); > execute("ALTER TYPE " + KEYSPACE + "." + ut1 + " ADD b int"); > execute("UPDATE %s SET y = y + ? WHERE x = 1", > set(userType(1, 1), userType(1, 2), userType(2, 1))); > flush(); > assertRows(execute("SELECT * FROM %s WHERE x = 1"), > row(1, set(userType(1), > userType(1, 1), > userType(1, 2), > userType(2), > userType(2, 1)))); > compact(); > assertRows(execute("SELECT * FROM %s WHERE x = 1"), > row(1, set(userType(1), > userType(1, 1), > userType(1, 2), > userType(2), > userType(2, 1)))); > } > finally > { > enableCompaction(); > } > } > {code} > There are in fact 2 problems: > # When the {{sets}} from the 2 versions are merged the {{ColumnDefinition}} > being picked up can be the older one. In which case when the tuples are > sorted it my lead to an {{IndexOutOfBoundsException}}. > # During compaction, the old column definition can be the one being kept for > the SSTable metadata. If it is the case the SSTable will not be readable any > more and will be marked as {{corrupted}}. > If one of the tables using the type has a Materialized View attached to it, > the MV updates can also fail with {{IndexOutOfBoundsException}}. > This problem can be reproduced using the following test: > {code} > @Test > public void testAlteringUserTypeNestedWithinSetWithView() throws Throwable > { > String columnType = typeWithKs(createType("CREATE TYPE %s (a int)")); > createTable("CREATE TABLE %s (pk int, c int, v int, s set<frozen<" + > columnType + ">>, PRIMARY KEY (pk, c))"); > execute("CREATE MATERIALIZED VIEW " + keyspace() + ".view1 AS SELECT > c, pk, v FROM %s WHERE pk IS NOT NULL AND c IS NOT NULL AND v IS NOT NULL > PRIMARY KEY (c, pk)"); > execute("INSERT INTO %s (pk, c, v, s) VALUES(?, ?, ?, ?)", 1, 1, 1, > set(userType(1), userType(2))); > flush(); > execute("ALTER TYPE " + columnType + " ADD b int"); > execute("UPDATE %s SET s = s + ?, v = ? WHERE pk = ? AND c = ?", > set(userType(1, 1), userType(1, 2), userType(2, 1)), 2, 1, 1); > assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c = ?", 1, 1), > row(1, 1, 2, set(userType(1), > userType(1, 1), > userType(1, 2), > userType(2), > userType(2, 1)))); > } > {code} -- This message was sent by Atlassian Jira (v8.3.4#803005) --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org