http://git-wip-us.apache.org/repos/asf/cassandra/blob/418c7936/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
index 9275da7,0000000..1e1c799
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
+++ b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
@@@ -1,549 -1,0 +1,549 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.cassandra.schema;
 +
 +import java.nio.ByteBuffer;
 +import java.util.*;
 +import java.util.stream.Collectors;
 +
 +import com.google.common.collect.ImmutableList;
 +import org.junit.Test;
 +
 +import org.apache.cassandra.SchemaLoader;
 +import org.apache.cassandra.cache.CachingOptions;
 +import org.apache.cassandra.config.*;
 +import org.apache.cassandra.cql3.ColumnIdentifier;
 +import org.apache.cassandra.cql3.functions.*;
 +import org.apache.cassandra.db.*;
 +import org.apache.cassandra.db.compaction.LeveledCompactionStrategy;
 +import org.apache.cassandra.db.marshal.*;
 +
 +import static java.lang.String.format;
 +import static junit.framework.Assert.assertEquals;
 +import static junit.framework.Assert.assertTrue;
 +import static org.apache.cassandra.cql3.QueryProcessor.executeOnceInternal;
 +import static org.apache.cassandra.utils.ByteBufferUtil.bytes;
 +import static org.apache.cassandra.utils.FBUtilities.json;
 +
 +@SuppressWarnings("deprecation")
 +public class LegacySchemaMigratorTest
 +{
 +    private static final long TIMESTAMP = 1435908994000000L;
 +
 +    private static final String KEYSPACE_PREFIX = "LegacySchemaMigratorTest";
 +
 +    /*
 +     * 1. Write a variety of different keyspaces/tables/types/function in the 
legacy manner, using legacy schema tables
 +     * 2. Run the migrator
 +     * 3. Read all the keyspaces from the new schema tables
 +     * 4. Make sure that we've read *exactly* the same set of 
keyspaces/tables/types/functions
 +     * 5. Validate that the legacy schema tables are now empty
 +     */
 +    @Test
 +    public void testMigrate()
 +    {
 +        List<KeyspaceMetadata> expected = keyspaceToMigrate();
 +        expected.sort((k1, k2) -> k1.name.compareTo(k2.name));
 +
 +        // write the keyspaces into the legacy tables
 +        expected.forEach(LegacySchemaMigratorTest::legacySerializeKeyspace);
 +
 +        // run the migration
 +        LegacySchemaMigrator.migrate();
 +
 +        // read back all the metadata from the new schema tables
 +        List<KeyspaceMetadata> actual = 
SchemaKeyspace.readSchemaFromSystemTables();
 +        actual.sort((k1, k2) -> k1.name.compareTo(k2.name));
 +
 +        // make sure that we've read *exactly* the same set of 
keyspaces/tables/types/functions
 +        assertEquals(expected, actual);
 +
 +        // need to load back CFMetaData of those tables (CFS instances will 
still be loaded)
 +        loadLegacySchemaTables();
 +
 +        // verify that nothing's left in the old schema tables
 +        for (CFMetaData table : LegacySchemaMigrator.LegacySchemaTables)
 +        {
 +            String query = format("SELECT * FROM %s.%s", SystemKeyspace.NAME, 
table.cfName);
 +            //noinspection ConstantConditions
 +            assertTrue(executeOnceInternal(query).isEmpty());
 +        }
 +    }
 +
 +    private static void loadLegacySchemaTables()
 +    {
 +        KeyspaceMetadata systemKeyspace = 
Schema.instance.getKSMetaData(SystemKeyspace.NAME);
 +
 +        Tables systemTables = systemKeyspace.tables;
 +        for (CFMetaData table : LegacySchemaMigrator.LegacySchemaTables)
 +            systemTables = systemTables.with(table);
 +
 +        
LegacySchemaMigrator.LegacySchemaTables.forEach(Schema.instance::load);
 +
 +        
Schema.instance.setKeyspaceMetadata(systemKeyspace.withSwapped(systemTables));
 +    }
 +
 +    private static List<KeyspaceMetadata> keyspaceToMigrate()
 +    {
 +        List<KeyspaceMetadata> keyspaces = new ArrayList<>();
 +
 +        // A whole bucket of shorthand
 +        String ks1 = KEYSPACE_PREFIX + "Keyspace1";
 +        String ks2 = KEYSPACE_PREFIX + "Keyspace2";
 +        String ks3 = KEYSPACE_PREFIX + "Keyspace3";
 +        String ks4 = KEYSPACE_PREFIX + "Keyspace4";
 +        String ks5 = KEYSPACE_PREFIX + "Keyspace5";
 +        String ks6 = KEYSPACE_PREFIX + "Keyspace6";
 +        String ks_rcs = KEYSPACE_PREFIX + "RowCacheSpace";
 +        String ks_nocommit = KEYSPACE_PREFIX + "NoCommitlogSpace";
 +        String ks_prsi = KEYSPACE_PREFIX + "PerRowSecondaryIndex";
 +        String ks_cql = KEYSPACE_PREFIX + "cql_keyspace";
 +
 +        // Make it easy to test compaction
 +        Map<String, String> compactionOptions = new HashMap<>();
 +        compactionOptions.put("tombstone_compaction_interval", "1");
 +        Map<String, String> leveledOptions = new HashMap<>();
 +        leveledOptions.put("sstable_size_in_mb", "1");
 +
 +        keyspaces.add(KeyspaceMetadata.create(ks1,
 +                                              KeyspaceParams.simple(1),
 +                                              
Tables.of(SchemaLoader.standardCFMD(ks1, "Standard1")
 +                                                                    
.compactionStrategyOptions(compactionOptions),
 +                                                        
SchemaLoader.standardCFMD(ks1, "StandardGCGS0").gcGraceSeconds(0),
 +                                                        
SchemaLoader.standardCFMD(ks1, "StandardLong1"),
 +                                                        
SchemaLoader.superCFMD(ks1, "Super1", LongType.instance),
 +                                                        
SchemaLoader.superCFMD(ks1, "Super2", UTF8Type.instance),
 +                                                        
SchemaLoader.superCFMD(ks1, "Super5", BytesType.instance),
 +                                                        
SchemaLoader.superCFMD(ks1, "Super6", LexicalUUIDType.instance, 
UTF8Type.instance),
 +                                                        
SchemaLoader.keysIndexCFMD(ks1, "Indexed1", true),
 +                                                        
SchemaLoader.keysIndexCFMD(ks1, "Indexed2", false),
 +                                                        
SchemaLoader.superCFMD(ks1, "SuperDirectGC", BytesType.instance)
 +                                                                    
.gcGraceSeconds(0),
 +                                                        
SchemaLoader.jdbcCFMD(ks1, "JdbcUtf8", UTF8Type.instance)
 +                                                                    
.addColumnDefinition(SchemaLoader.utf8Column(ks1, "JdbcUtf8")),
 +                                                        
SchemaLoader.jdbcCFMD(ks1, "JdbcLong", LongType.instance),
 +                                                        
SchemaLoader.jdbcCFMD(ks1, "JdbcBytes", BytesType.instance),
 +                                                        
SchemaLoader.jdbcCFMD(ks1, "JdbcAscii", AsciiType.instance),
 +                                                        
SchemaLoader.standardCFMD(ks1, "StandardLeveled")
 +                                                                    
.compactionStrategyClass(LeveledCompactionStrategy.class)
 +                                                                    
.compactionStrategyOptions(leveledOptions),
 +                                                        
SchemaLoader.standardCFMD(ks1, "legacyleveled")
 +                                                                    
.compactionStrategyClass(LeveledCompactionStrategy.class)
 +                                                                    
.compactionStrategyOptions(leveledOptions),
 +                                                        
SchemaLoader.standardCFMD(ks1, "StandardLowIndexInterval")
 +                                                                    
.minIndexInterval(8)
 +                                                                    
.maxIndexInterval(256)
 +                                                                    
.caching(CachingOptions.NONE))));
 +
 +        // Keyspace 2
 +        keyspaces.add(KeyspaceMetadata.create(ks2,
 +                                              KeyspaceParams.simple(1),
 +                                              
Tables.of(SchemaLoader.standardCFMD(ks2, "Standard1"),
 +                                                        
SchemaLoader.superCFMD(ks2, "Super3", BytesType.instance),
 +                                                        
SchemaLoader.superCFMD(ks2, "Super4", TimeUUIDType.instance),
 +                                                        
SchemaLoader.keysIndexCFMD(ks2, "Indexed1", true),
 +                                                        
SchemaLoader.compositeIndexCFMD(ks2, "Indexed2", true),
 +                                                        
SchemaLoader.compositeIndexCFMD(ks2, "Indexed3", true)
 +                                                                    
.gcGraceSeconds(0))));
 +
 +        // Keyspace 3
 +        keyspaces.add(KeyspaceMetadata.create(ks3,
 +                                              KeyspaceParams.simple(5),
 +                                              
Tables.of(SchemaLoader.standardCFMD(ks3, "Standard1"),
 +                                                        
SchemaLoader.keysIndexCFMD(ks3, "Indexed1", true))));
 +
 +        // Keyspace 4
 +        keyspaces.add(KeyspaceMetadata.create(ks4,
 +                                              KeyspaceParams.simple(3),
 +                                              
Tables.of(SchemaLoader.standardCFMD(ks4, "Standard1"),
 +                                                        
SchemaLoader.superCFMD(ks4, "Super3", BytesType.instance),
 +                                                        
SchemaLoader.superCFMD(ks4, "Super4", TimeUUIDType.instance),
 +                                                        
SchemaLoader.superCFMD(ks4, "Super5", TimeUUIDType.instance, 
BytesType.instance))));
 +
 +        // Keyspace 5
 +        keyspaces.add(KeyspaceMetadata.create(ks5,
 +                                              KeyspaceParams.simple(2),
 +                                              
Tables.of(SchemaLoader.standardCFMD(ks5, "Standard1"))));
 +        // Keyspace 6
 +        keyspaces.add(KeyspaceMetadata.create(ks6,
 +                                              KeyspaceParams.simple(1),
 +                                              
Tables.of(SchemaLoader.keysIndexCFMD(ks6, "Indexed1", true))));
 +
 +        // RowCacheSpace
 +        keyspaces.add(KeyspaceMetadata.create(ks_rcs,
 +                                              KeyspaceParams.simple(1),
 +                                              
Tables.of(SchemaLoader.standardCFMD(ks_rcs, "CFWithoutCache")
 +                                                                    
.caching(CachingOptions.NONE),
 +                                                        
SchemaLoader.standardCFMD(ks_rcs, "CachedCF")
 +                                                                    
.caching(CachingOptions.ALL),
 +                                                        
SchemaLoader.standardCFMD(ks_rcs, "CachedIntCF")
 +                                                                    
.caching(new CachingOptions(new 
CachingOptions.KeyCache(CachingOptions.KeyCache.Type.ALL),
 +                                                                              
                  new 
CachingOptions.RowCache(CachingOptions.RowCache.Type.HEAD, 100))))));
 +
 +
 +        keyspaces.add(KeyspaceMetadata.create(ks_nocommit,
 +                                              
KeyspaceParams.simpleTransient(1),
 +                                              
Tables.of(SchemaLoader.standardCFMD(ks_nocommit, "Standard1"))));
 +
 +        // PerRowSecondaryIndexTest
 +        keyspaces.add(KeyspaceMetadata.create(ks_prsi,
 +                                              KeyspaceParams.simple(1),
 +                                              
Tables.of(SchemaLoader.perRowIndexedCFMD(ks_prsi, "Indexed1"))));
 +
 +        // CQLKeyspace
 +        keyspaces.add(KeyspaceMetadata.create(ks_cql,
 +                                              KeyspaceParams.simple(1),
 +                                              
Tables.of(CFMetaData.compile("CREATE TABLE table1 ("
 +                                                                           + 
"k int PRIMARY KEY,"
 +                                                                           + 
"v1 text,"
 +                                                                           + 
"v2 int"
 +                                                                           + 
')', ks_cql),
 +
 +                                                        
CFMetaData.compile("CREATE TABLE table2 ("
 +                                                                           + 
"k text,"
 +                                                                           + 
"c text,"
 +                                                                           + 
"v text,"
 +                                                                           + 
"PRIMARY KEY (k, c))", ks_cql),
 +
 +                                                        
CFMetaData.compile("CREATE TABLE foo ("
 +                                                                           + 
"bar text, "
 +                                                                           + 
"baz text, "
 +                                                                           + 
"qux text, "
 +                                                                           + 
"PRIMARY KEY(bar, baz) ) "
 +                                                                           + 
"WITH COMPACT STORAGE", ks_cql),
 +
 +                                                        
CFMetaData.compile("CREATE TABLE foofoo ("
 +                                                                           + 
"bar text, "
 +                                                                           + 
"baz text, "
 +                                                                           + 
"qux text, "
 +                                                                           + 
"quz text, "
 +                                                                           + 
"foo text, "
 +                                                                           + 
"PRIMARY KEY((bar, baz), qux, quz) ) "
 +                                                                           + 
"WITH COMPACT STORAGE", ks_cql))));
 +
 +        keyspaces.add(keyspaceWithTriggers());
 +        keyspaces.add(keyspaceWithUDTs());
 +        keyspaces.add(keyspaceWithUDFs());
 +        keyspaces.add(keyspaceWithUDAs());
 +
 +        return keyspaces;
 +    }
 +
 +    private static KeyspaceMetadata keyspaceWithTriggers()
 +    {
 +        String keyspace = KEYSPACE_PREFIX + "Triggers";
 +
 +        Triggers.Builder triggers = Triggers.builder();
 +        CFMetaData table = SchemaLoader.standardCFMD(keyspace, 
"WithTriggers");
 +        for (int i = 0; i < 10; i++)
 +            triggers.add(new TriggerMetadata("trigger" + i, "DummyTrigger" + 
i));
 +        table.triggers(triggers.build());
 +
 +        return KeyspaceMetadata.create(keyspace, KeyspaceParams.simple(1), 
Tables.of(table));
 +    }
 +
 +    private static KeyspaceMetadata keyspaceWithUDTs()
 +    {
 +        String keyspace = KEYSPACE_PREFIX + "UDTs";
 +
 +        UserType udt1 = new UserType(keyspace,
 +                                     bytes("udt1"),
 +                                     new ArrayList<ByteBuffer>() {{ 
add(bytes("col1")); add(bytes("col2")); }},
 +                                     new ArrayList<AbstractType<?>>() {{ 
add(UTF8Type.instance); add(Int32Type.instance); }});
 +
 +        UserType udt2 = new UserType(keyspace,
 +                                     bytes("udt2"),
 +                                     new ArrayList<ByteBuffer>() {{ 
add(bytes("col3")); add(bytes("col4")); }},
 +                                     new ArrayList<AbstractType<?>>() {{ 
add(BytesType.instance); add(BooleanType.instance); }});
 +
 +        UserType udt3 = new UserType(keyspace,
 +                                     bytes("udt3"),
 +                                     new ArrayList<ByteBuffer>() {{ 
add(bytes("col5")); }},
 +                                     new ArrayList<AbstractType<?>>() {{ 
add(AsciiType.instance); }});
 +
 +        return KeyspaceMetadata.create(keyspace,
 +                                       KeyspaceParams.simple(1),
 +                                       Tables.none(),
 +                                       Types.of(udt1, udt2, udt3),
 +                                       Functions.none());
 +    }
 +
 +    private static KeyspaceMetadata keyspaceWithUDFs()
 +    {
 +        String keyspace = KEYSPACE_PREFIX + "UDFs";
 +
 +
 +        UDFunction udf1 = UDFunction.create(new FunctionName(keyspace, "udf"),
 +                                            ImmutableList.of(new 
ColumnIdentifier("col1", false), new ColumnIdentifier("col2", false)),
 +                                            
ImmutableList.of(BytesType.instance, Int32Type.instance),
 +                                            LongType.instance,
 +                                            false,
 +                                            "java",
 +                                            "return 42L;");
 +
 +        // an overload with the same name, not a typo
 +        UDFunction udf2 = UDFunction.create(new FunctionName(keyspace, "udf"),
 +                                            ImmutableList.of(new 
ColumnIdentifier("col3", false), new ColumnIdentifier("col4", false)),
 +                                            
ImmutableList.of(AsciiType.instance, LongType.instance),
 +                                            Int32Type.instance,
 +                                            true,
 +                                            "java",
 +                                            "return 42;");
 +
 +        UDFunction udf3 = UDFunction.create(new FunctionName(keyspace, 
"udf3"),
 +                                            ImmutableList.of(new 
ColumnIdentifier("col4", false)),
 +                                            
ImmutableList.of(UTF8Type.instance),
 +                                            BooleanType.instance,
 +                                            false,
 +                                            "java",
 +                                            "return true;");
 +
 +        return KeyspaceMetadata.create(keyspace,
 +                                       KeyspaceParams.simple(1),
 +                                       Tables.none(),
 +                                       Types.none(),
 +                                       Functions.of(udf1, udf2, udf3));
 +    }
 +
 +    // TODO: add representative UDAs set
 +    private static KeyspaceMetadata keyspaceWithUDAs()
 +    {
 +        String keyspace = KEYSPACE_PREFIX + "UDAs";
 +
 +        return KeyspaceMetadata.create(keyspace,
 +                                       KeyspaceParams.simple(1),
 +                                       Tables.none(),
 +                                       Types.none(),
 +                                       Functions.of());
 +    }
 +
 +    /*
 +     * Serializing keyspaces
 +     */
 +
 +    private static void legacySerializeKeyspace(KeyspaceMetadata keyspace)
 +    {
 +        makeLegacyCreateKeyspaceMutation(keyspace, TIMESTAMP).apply();
 +    }
 +
 +    private static Mutation makeLegacyCreateKeyspaceMutation(KeyspaceMetadata 
keyspace, long timestamp)
 +    {
 +        // Note that because Keyspaces is a COMPACT TABLE, we're really only 
setting static columns internally and shouldn't set any clustering.
 +        RowUpdateBuilder adder = new 
RowUpdateBuilder(SystemKeyspace.LegacyKeyspaces, timestamp, keyspace.name);
 +
 +        adder.add("durable_writes", keyspace.params.durableWrites)
 +             .add("strategy_class", 
keyspace.params.replication.klass.getName())
 +             .add("strategy_options", 
json(keyspace.params.replication.options));
 +
 +        Mutation mutation = adder.build();
 +
 +        keyspace.tables.forEach(table -> addTableToSchemaMutation(table, 
timestamp, true, mutation));
 +        keyspace.types.forEach(type -> addTypeToSchemaMutation(type, 
timestamp, mutation));
 +        keyspace.functions.udfs().forEach(udf -> 
addFunctionToSchemaMutation(udf, timestamp, mutation));
 +        keyspace.functions.udas().forEach(uda -> 
addAggregateToSchemaMutation(uda, timestamp, mutation));
 +
 +        return mutation;
 +    }
 +
 +    /*
 +     * Serializing tables
 +     */
 +
 +    private static void addTableToSchemaMutation(CFMetaData table, long 
timestamp, boolean withColumnsAndTriggers, Mutation mutation)
 +    {
 +        // For property that can be null (and can be changed), we insert 
tombstones, to make sure
 +        // we don't keep a property the user has removed
 +        RowUpdateBuilder adder = new 
RowUpdateBuilder(SystemKeyspace.LegacyColumnfamilies, timestamp, mutation)
 +                                 .clustering(table.cfName);
 +
 +        adder.add("cf_id", table.cfId)
 +             .add("type", table.isSuper() ? "Super" : "Standard");
 +
 +        if (table.isSuper())
 +        {
 +            adder.add("comparator", table.comparator.subtype(0).toString())
 +                 .add("subcomparator", 
((MapType)table.compactValueColumn().type).getKeysType().toString());
 +        }
 +        else
 +        {
 +            adder.add("comparator", 
LegacyLayout.makeLegacyComparator(table).toString());
 +        }
 +
 +        adder.add("bloom_filter_fp_chance", table.getBloomFilterFpChance())
 +             .add("caching", table.getCaching().toString())
 +             .add("comment", table.getComment())
 +             .add("compaction_strategy_class", 
table.compactionStrategyClass.getName())
 +             .add("compaction_strategy_options", 
json(table.compactionStrategyOptions))
 +             .add("compression_parameters", 
json(table.compressionParameters.asThriftOptions()))
 +             .add("default_time_to_live", table.getDefaultTimeToLive())
 +             .add("gc_grace_seconds", table.getGcGraceSeconds())
 +             .add("key_validator", table.getKeyValidator().toString())
 +             .add("local_read_repair_chance", 
table.getDcLocalReadRepairChance())
 +             .add("max_compaction_threshold", 
table.getMaxCompactionThreshold())
 +             .add("max_index_interval", table.getMaxIndexInterval())
 +             .add("memtable_flush_period_in_ms", 
table.getMemtableFlushPeriod())
 +             .add("min_compaction_threshold", 
table.getMinCompactionThreshold())
 +             .add("min_index_interval", table.getMinIndexInterval())
 +             .add("read_repair_chance", table.getReadRepairChance())
 +             .add("speculative_retry", 
table.getSpeculativeRetry().toString());
 +
 +        for (Map.Entry<ColumnIdentifier, CFMetaData.DroppedColumn> entry : 
table.getDroppedColumns().entrySet())
 +        {
 +            String name = entry.getKey().toString();
 +            CFMetaData.DroppedColumn column = entry.getValue();
 +            adder.addMapEntry("dropped_columns", name, column.droppedTime);
 +        }
 +
 +        adder.add("is_dense", table.isDense());
 +
 +        adder.add("default_validator", 
table.makeLegacyDefaultValidator().toString());
 +
 +        if (withColumnsAndTriggers)
 +        {
 +            for (ColumnDefinition column : table.allColumns())
 +                addColumnToSchemaMutation(table, column, timestamp, mutation);
 +
 +            for (TriggerMetadata trigger : table.getTriggers())
 +                addTriggerToSchemaMutation(table, trigger, timestamp, 
mutation);
 +        }
 +
 +        adder.build();
 +    }
 +
 +    private static void addColumnToSchemaMutation(CFMetaData table, 
ColumnDefinition column, long timestamp, Mutation mutation)
 +    {
 +        RowUpdateBuilder adder = new 
RowUpdateBuilder(SystemKeyspace.LegacyColumns, timestamp, mutation)
 +                                 .clustering(table.cfName, 
column.name.toString());
 +
 +        adder.add("validator", column.type.toString())
 +             .add("type", serializeKind(column.kind, table.isDense()))
 +             .add("component_index", column.isOnAllComponents() ? null : 
column.position())
 +             .add("index_name", column.getIndexName())
 +             .add("index_type", column.getIndexType() == null ? null : 
column.getIndexType().toString())
 +             .add("index_options", json(column.getIndexOptions()))
 +             .build();
 +    }
 +
 +    private static String serializeKind(ColumnDefinition.Kind kind, boolean 
isDense)
 +    {
 +        // For backward compatibility, we special case CLUSTERING_COLUMN and 
the case where the table is dense.
 +        if (kind == ColumnDefinition.Kind.CLUSTERING_COLUMN)
 +            return "clustering_key";
 +
 +        if (kind == ColumnDefinition.Kind.REGULAR && isDense)
 +            return "compact_value";
 +
 +        return kind.toString().toLowerCase();
 +    }
 +
 +    private static void addTriggerToSchemaMutation(CFMetaData table, 
TriggerMetadata trigger, long timestamp, Mutation mutation)
 +    {
 +        new RowUpdateBuilder(SystemKeyspace.LegacyTriggers, timestamp, 
mutation)
 +            .clustering(table.cfName, trigger.name)
 +            .addMapEntry("trigger_options", "class", trigger.classOption)
 +            .build();
 +    }
 +
 +    /*
 +     * Serializing types
 +     */
 +
 +    private static void addTypeToSchemaMutation(UserType type, long 
timestamp, Mutation mutation)
 +    {
 +        RowUpdateBuilder adder = new 
RowUpdateBuilder(SystemKeyspace.LegacyUsertypes, timestamp, mutation)
 +                                 .clustering(type.getNameAsString());
 +
 +        adder.resetCollection("field_names")
 +             .resetCollection("field_types");
 +
 +        for (int i = 0; i < type.size(); i++)
 +        {
 +            adder.addListEntry("field_names", type.fieldName(i))
 +                 .addListEntry("field_types", type.fieldType(i).toString());
 +        }
 +
 +        adder.build();
 +    }
 +
 +    /*
 +     * Serializing functions
 +     */
 +
 +    private static void addFunctionToSchemaMutation(UDFunction function, long 
timestamp, Mutation mutation)
 +    {
 +        RowUpdateBuilder adder = new 
RowUpdateBuilder(SystemKeyspace.LegacyFunctions, timestamp, mutation)
 +                                 .clustering(function.name().name, 
functionSignatureWithTypes(function));
 +
 +        adder.add("body", function.body())
 +             .add("language", function.language())
 +             .add("return_type", function.returnType().toString())
 +             .add("called_on_null_input", function.isCalledOnNullInput());
 +
 +        adder.resetCollection("argument_names")
 +             .resetCollection("argument_types");
 +
 +        for (int i = 0; i < function.argNames().size(); i++)
 +        {
 +            adder.addListEntry("argument_names", 
function.argNames().get(i).bytes)
 +                 .addListEntry("argument_types", 
function.argTypes().get(i).toString());
 +        }
 +
 +        adder.build();
 +    }
 +
 +    /*
 +     * Serializing aggregates
 +     */
 +
 +    private static void addAggregateToSchemaMutation(UDAggregate aggregate, 
long timestamp, Mutation mutation)
 +    {
 +        RowUpdateBuilder adder = new 
RowUpdateBuilder(SystemKeyspace.LegacyAggregates, timestamp, mutation)
 +                                 .clustering(aggregate.name().name, 
functionSignatureWithTypes(aggregate));
 +
 +        adder.resetCollection("argument_types");
 +
 +        adder.add("return_type", aggregate.returnType().toString())
-              .add("state_func", aggregate.stateFunction().name().toString());
++             .add("state_func", aggregate.stateFunction().name().name);
 +
 +        if (aggregate.stateType() != null)
 +            adder.add("state_type", aggregate.stateType().toString());
 +        if (aggregate.finalFunction() != null)
-             adder.add("final_func", 
aggregate.finalFunction().name().toString());
++            adder.add("final_func", aggregate.finalFunction().name().name);
 +        if (aggregate.initialCondition() != null)
 +            adder.add("initcond", aggregate.initialCondition());
 +
 +        for (AbstractType<?> argType : aggregate.argTypes())
 +            adder.addListEntry("argument_types", argType.toString());
 +
 +        adder.build();
 +    }
 +
 +    // We allow method overloads, so a function is not uniquely identified by 
its name only, but
 +    // also by its argument types. To distinguish overloads of given function 
name in the schema
 +    // we use a "signature" which is just a list of it's CQL argument types.
 +    public static ByteBuffer functionSignatureWithTypes(AbstractFunction fun)
 +    {
 +        List<String> arguments =
 +            fun.argTypes()
 +               .stream()
 +               .map(argType -> argType.asCQL3Type().toString())
 +               .collect(Collectors.toList());
 +
 +        return ListType.getInstance(UTF8Type.instance, 
false).decompose(arguments);
 +    }
 +}

Reply via email to