[ https://issues.apache.org/jira/browse/CASSANDRA-15926?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
David Capwell updated CASSANDRA-15926: -------------------------------------- Change Category: Semantic Complexity: Normal Status: Open (was: Triage Needed) > When schema does not match sstable serialization header can fail when merging > rows > ---------------------------------------------------------------------------------- > > Key: CASSANDRA-15926 > URL: https://issues.apache.org/jira/browse/CASSANDRA-15926 > Project: Cassandra > Issue Type: Improvement > Components: Cluster/Schema, Local/SSTable > Reporter: David Capwell > Priority: Normal > > If the table schema had timeuuid and then an alter is done to change the > column to uuid, then the on-disk serialization header won’t match the table > schema; this is problematic as there isn’t logic to migrate the column from > the old type to the new type. > The ALTER TABLE command does not directly allow this type of schema change > (though possible before 3.0.11, see CASSANDRA-12443), but this is possible if > the following is done > {code} > INSERT INTO system_schema.columns (keyspace_name, table_name, column_name, > clustering_order, column_name_bytes, kind, position, type) VALUES (‘ks', > ’table', ‘col', 'none', bytes, 'regular', -1, 'uuid’); > ALTER TABLE ks.table WITH comment = 'something’; — this will trigger the > schema to migrate across the cluster > {code} > The below is a test to show this > {code} > package org.apache.cassandra.distributed.test; > import java.util.UUID; > import org.junit.Test; > import org.apache.cassandra.distributed.Cluster; > import org.apache.cassandra.distributed.impl.IInvokableInstance; > import org.apache.cassandra.utils.UUIDGen; > public class AlterWithOnDiskMismatch extends DistributedTestBase > { > @Test > public void alterTypeMixedSSTablesNoConflict() throws Throwable > { > try (Cluster cluster = init(Cluster.create(1))) > { > IInvokableInstance node = cluster.get(1); > cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".mismatch (key > text primary key, value timeuuid)"); > // write valid timeuuid then flush > node.executeInternal("INSERT INTO " + KEYSPACE + ".mismatch (key, > value) VALUES (?, ?)", "k1", UUIDGen.getTimeUUID()); > node.flush(KEYSPACE); > // alter schema > Object[] columns = node.executeInternal("SELECT keyspace_name, > table_name, column_name, clustering_order, column_name_bytes, kind, position, > type " + > "FROM system_schema.columns WHERE > keyspace_name=? AND table_name=? AND column_name=?", KEYSPACE, "mismatch", > "value")[0]; > columns[columns.length - 1] = "uuid"; > node.executeInternal("INSERT INTO system_schema.columns > (keyspace_name, table_name, column_name, clustering_order, column_name_bytes, > kind, position, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", columns); > cluster.schemaChange("ALTER TABLE " + KEYSPACE + ".mismatch WITH > comment='upgrade'"); > node.executeInternal("INSERT INTO " + KEYSPACE + ".mismatch (key, > value) VALUES (?, ?)", "k2", UUID.randomUUID()); > node.flush(KEYSPACE); > node.forceCompact(KEYSPACE, "mismatch"); > } > } > @Test > public void alterTypeMixedSSTablesConflict() throws Throwable > { > try (Cluster cluster = init(Cluster.create(1))) > { > IInvokableInstance node = cluster.get(1); > cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".mismatch (key > text primary key, value timeuuid)"); > // write valid timeuuid then flush > node.executeInternal("INSERT INTO " + KEYSPACE + ".mismatch (key, > value) VALUES (?, ?)", "k1", UUIDGen.getTimeUUID()); > node.flush(KEYSPACE); > // alter schema > Object[] columns = node.executeInternal("SELECT keyspace_name, > table_name, column_name, clustering_order, column_name_bytes, kind, position, > type " + > "FROM > system_schema.columns WHERE keyspace_name=? AND table_name=? AND > column_name=?", KEYSPACE, "mismatch", "value")[0]; > columns[columns.length - 1] = "uuid"; > node.executeInternal("INSERT INTO system_schema.columns > (keyspace_name, table_name, column_name, clustering_order, column_name_bytes, > kind, position, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", columns); > cluster.schemaChange("ALTER TABLE " + KEYSPACE + ".mismatch WITH > comment='upgrade'"); > node.executeInternal("INSERT INTO " + KEYSPACE + ".mismatch (key, > value) VALUES (?, ?)", "k1", UUID.randomUUID()); > node.flush(KEYSPACE); > node.forceCompact(KEYSPACE, "mismatch"); > } > } > } > {code} > The following is the exception > {code} > java.lang.IllegalArgumentException: Trying to compare 2 different types: > org.apache.cassandra.db.marshal.TimeUUIDType and > org.apache.cassandra.db.marshal.UUIDType > at > org.apache.cassandra.db.rows.AbstractTypeVersionComparator.compare(AbstractTypeVersionComparator.java:42) > at > org.apache.cassandra.db.rows.AbstractTypeVersionComparator.compare(AbstractTypeVersionComparator.java:30) > at > org.apache.cassandra.db.rows.Row$Merger$ColumnDataReducer.useColumnDefinition(Row.java:650) > at > org.apache.cassandra.db.rows.Row$Merger$ColumnDataReducer.reduce(Row.java:634) > at > org.apache.cassandra.db.rows.Row$Merger$ColumnDataReducer.reduce(Row.java:605) > at > org.apache.cassandra.utils.MergeIterator$ManyToOne.consume(MergeIterator.java:216) > {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