EVOLUTION-MANAGER
Edit File: change_column_all.py
import sys import random import string import re class Field: def __init__(self, name, is_nullible): self.name = name self.is_nullible = is_nullible class Field_int(Field): sizes = [ 1, 2, 3, 4, 8 ] types = [ "TINYINT", "SMALLINT", "MEDIUMINT", "INT", "BIGINT" ] uint_ranges = [ (0,(1<<8)-1), (0,(1<<16)-1), (0,(1<<24)-1), (0,(1<<32)-1), (0,(1<<64)-1) ] int_ranges = [ (-(1<<7), (1<<7)-1), (-(1<<15),(1<<15)-1), (-(1<<23),(1<<23)-1), (-(1<<31),(1<<31)-1), (-(1<<63),(1<<63)-1) ] def __init__(self, name, size, is_unsigned, is_nullible): Field.__init__(self, name, is_nullible) self.idx = Field_int.sizes.index(size) self.size = size self.is_unsigned = is_unsigned def get_type(self): t = Field_int.types[self.idx] if self.is_unsigned: t += " UNSIGNED" if not self.is_nullible: t += " NOT NULL" return t def get_value(self): if self.is_unsigned: r = Field_int.uint_ranges[self.idx] else: r = Field_int.int_ranges[self.idx] return random.randint(r[0],r[1]) def next_field(self): return Field_int(self.name, Field_int.sizes[random.randint(self.idx,len(Field_int.sizes)-1)], self.is_unsigned, self.is_nullible) class Field_int_auto_inc(Field_int): def __init__(self, name, size, is_unsigned, is_nullible): Field_int.__init__(self, name, size, is_unsigned, is_nullible) self.next_value = 0 def get_type(self): return Field_int.get_type(self) def get_value(self): v = self.next_value self.next_value += 1 return v class Field_char(Field): types = [ "CHAR", "BINARY" ] def __init__(self, name, size, is_binary, is_nullible): Field.__init__(self, name, is_nullible) assert 0 <= size and size < 256 self.size = size self.is_binary = is_binary def get_type(self): t = "%s(%d)" % (Field_char.types[self.is_binary], self.size) if not self.is_nullible: t += " NOT NULL" return t def next_size(self): if self.size < 255: return self.size + 1 return self.size def get_value(self): l = random.randint(1, self.size) s = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for x in range(l)) return "'%s'" % (s) def next_field(self): return Field_char(self.name, self.next_size(), self.is_binary, self.is_nullible) class Field_varchar(Field): types = [ "VARCHAR", "VARBINARY" ] def __init__(self, name, size, is_binary, is_nullible): Field.__init__(self, name, is_nullible) assert 0 <= size and size < 64*1024 self.size = size self.is_binary = is_binary def get_type(self): t = "%s(%d)" % (Field_varchar.types[self.is_binary], self.size) if not self.is_nullible: t += " NOT NULL" return t; def get_value(self): l = random.randint(1, self.size) s = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for x in range(l)) return "'%s'" % (s) def next_size(self): if self.size < 64*1024: return self.size + 1 return self.size def next_field(self): if self.size < 256: new_size = 256 else: new_size = self.size + 1 return Field_varchar(self.name, new_size, self.is_binary, self.is_nullible) class Field_blob(Field): types = [ "TINYBLOB", "BLOB", "MEDIUMBLOB", "LONGBLOB" ] def __init__(self, name, size, is_nullible, idx): Field.__init__(self, name, is_nullible) self.size = size self.idx = idx def get_type(self): t = "%s" % (Field_blob.types[self.idx]) if not self.is_nullible: t += " NOT NULL" return t def get_value(self): l = random.randint(1, self.size) s = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for x in range(l)) return "'%s'" % (s) def next_field(self): self.size += 1 if self.idx < 3: self.idx += 1 return Field_blob(self.name, self.size, self.is_nullible, self.idx) def create_fields(): fields = [] fields.append(create_int('a')) fields.append(create_int('b')) fields.append(create_char('c')) fields.append(create_varchar('d')) fields.append(create_varchar('e')) fields.append(create_varchar('f')) fields.append(create_blob('g')) fields.append(create_blob('h')) fields.append(Field_int_auto_inc('id', 8, 0, 0)) return fields def create_int(name): int_sizes = [ 1, 2, 3, 4, 8] return Field_int(name, int_sizes[random.randint(0,len(int_sizes)-1)], random.randint(0,1), random.randint(0,1)) def create_char(name): return Field_char(name, random.randint(1, 100), random.randint(0,1), random.randint(0,1)) def create_varchar(name): return Field_varchar(name, random.randint(1, 100), random.randint(0,1), random.randint(0,1)) def create_blob(name): return Field_blob(name, random.randint(1,2), random.randint(0,1), random.randint(0,3)) def create_table(fields, tablename, engine): if engine == "tokudb": key_type = "CLUSTERING KEY" else: key_type = "KEY" t = "CREATE TABLE %s (" % (tablename) for f in fields: t += "%s %s, " % (f.name, f.get_type()) t += "KEY(b), %s(e), PRIMARY KEY(id)" % (key_type) t += ") ENGINE=%s;" % (engine) return t def insert_row(fields): t = "INSERT INTO %s VALUES (" for i in range(len(fields)): f = fields[i] t += "%s" % (f.get_value()) if i < len(fields)-1: t += "," t += ");" return t def header(): print "# generated from change_column_all.py" print "# test random column change on wide tables" print "source include/have_tokudb.inc;" print "--source include/big_test.inc" print "--disable_warnings" print "DROP TABLE IF EXISTS t, ti;" print "--enable_warnings" print "SET SESSION TOKUDB_DISABLE_SLOW_ALTER=1;" print "SET SESSION DEFAULT_STORAGE_ENGINE='TokuDB';" print def main(): experiments = 1000 nrows = 10 seed = 0 for arg in sys.argv[1:]: match = re.match("--(.*)=(.*)", arg) if match: exec("%s = %s" % (match.group(1),match.group(2))) random.seed(seed) header() for experiment in range(experiments): # generate a schema fields = create_fields() # create a table with the schema print create_table(fields, "t", "tokudb") # insert some rows for r in range(nrows): print insert_row(fields) % ('t') print create_table(fields, "ti", "myisam"); print "INSERT INTO ti SELECT * FROM t;" # transform table schema and contents for f in [ 0, 2, 3, 5, 6, 7 ]: fields[f] = fields[f].next_field() print "ALTER TABLE t CHANGE COLUMN %s %s %s;" % (fields[f].name, fields[f].name, fields[f].get_type()) print "ALTER TABLE ti CHANGE COLUMN %s %s %s;" % (fields[f].name, fields[f].name, fields[f].get_type()) new_row = insert_row(fields) print new_row % ('t') print new_row % ('ti') # compare tables print "let $diff_tables = test.t, test.ti;" print "source include/diff_tables.inc;" # cleanup print "DROP TABLE t, ti;" print return 0 sys.exit(main())