From 14632d22fdd3b40d02e27d34f70a42b33ac73134 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 12 Feb 2019 14:12:00 +0200 Subject: [PATCH 1/4] schema: Fix error handling in generateValue The error condition in generateValue() is ignored because the error object created with fmt.Errorf() is not returned anywhere. As this is an internal error, let's just call panic() to stop execution. --- schema.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.go b/schema.go index cb31e137..17319b31 100644 --- a/schema.go +++ b/schema.go @@ -97,7 +97,7 @@ func generateValue(columnType string, p *PartitionRange, values []interface{}) [ case "timestamp", "date": values = append(values, randDate()) default: - fmt.Errorf("generate value: not supported type %s", columnType) + panic(fmt.Sprintf("generate value: not supported type %s", columnType)) } return values } From 0d9b1fcf91ecbef83e443f4578ce2164fa90e899 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 12 Feb 2019 12:08:07 +0200 Subject: [PATCH 2/4] schema: Schema generation The schema is currently configured via an external file "schema.json". This commit adds support for generating the schema with the tool. Users can still define the schema themselves via a JSON file with the "--schema" command line option. Fixes #9 --- cmd/gemini/root.go | 44 +++++++++-------- schema.go | 119 ++++++++++++++++++++++++++++++--------------- 2 files changed, 105 insertions(+), 58 deletions(-) diff --git a/cmd/gemini/root.go b/cmd/gemini/root.go index 4d8160e6..fae423d2 100644 --- a/cmd/gemini/root.go +++ b/cmd/gemini/root.go @@ -16,6 +16,7 @@ import ( var ( testClusterHost string oracleClusterHost string + schemaFile string maxTests int concurrency int pkNumberPerThread int @@ -27,7 +28,6 @@ var ( ) const ( - confFile = "schema.json" writeMode = "write" readMode = "read" mixedMode = "mixed" @@ -45,12 +45,7 @@ type Results interface { Print() } -type jsonSchema struct { - Keyspace gemini.Keyspace `json:"keyspace"` - Tables []gemini.Table `json:"tables"` -} - -type testJob func(gemini.Schema, gemini.Table, *gemini.Session, gemini.PartitionRange, chan Status, string) +type testJob func(*gemini.Schema, gemini.Table, *gemini.Session, gemini.PartitionRange, chan Status, string) func (r *Status) Merge(sum *Status) Status { sum.WriteOps += r.WriteOps @@ -72,14 +67,13 @@ func (r Status) String() string { return fmt.Sprintf("write ops: %v | read ops: %v | write errors: %v | read errors: %v", r.WriteOps, r.ReadOps, r.WriteErrors, r.ReadErrors) } -func createSchema() (gemini.Schema, error) { +func readSchema(confFile string) (*gemini.Schema, error) { byteValue, err := ioutil.ReadFile(confFile) if err != nil { return nil, err } - fmt.Printf("Schema: %v", string(byteValue)) - var shm jsonSchema + var shm gemini.Schema err = json.Unmarshal(byteValue, &shm) if err != nil { @@ -103,12 +97,21 @@ func run(cmd *cobra.Command, args []string) { fmt.Printf("Test cluster: %s\n", testClusterHost) fmt.Printf("Oracle cluster: %s\n", oracleClusterHost) - schema, err := createSchema() - if err != nil { - fmt.Printf("cannot create schema: %v", err) - return + var schema *gemini.Schema + if len(schemaFile) > 0 { + var err error + schema, err = readSchema(schemaFile) + if err != nil { + fmt.Printf("cannot create schema: %v", err) + return + } + } else { + schema = gemini.GenSchema() } + jsonSchema, _ := json.MarshalIndent(schema, "", " ") + fmt.Printf("Schema: %v\n", string(jsonSchema)) + session := gemini.NewSession(testClusterHost, oracleClusterHost) defer session.Close() @@ -136,12 +139,12 @@ func run(cmd *cobra.Command, args []string) { runJob(Job, schema, session, mode) } -func runJob(f testJob, schema gemini.Schema, s *gemini.Session, mode string) { +func runJob(f testJob, schema *gemini.Schema, s *gemini.Session, mode string) { c := make(chan Status) minRange := 0 maxRange := pkNumberPerThread - for _, table := range schema.Tables() { + for _, table := range schema.Tables { for i := 0; i < concurrency; i++ { p := gemini.PartitionRange{Min: minRange + i*maxRange, Max: maxRange + i*maxRange} go f(schema, table, s, p, c, mode) @@ -149,7 +152,7 @@ func runJob(f testJob, schema gemini.Schema, s *gemini.Session, mode string) { } var testRes Status - for i := 0; i < concurrency*len(schema.Tables()); i++ { + for i := 0; i < concurrency*len(schema.Tables); i++ { res := <-c testRes = res.Merge(&testRes) if testRes.ReadErrors > 0 { @@ -162,7 +165,7 @@ func runJob(f testJob, schema gemini.Schema, s *gemini.Session, mode string) { testRes.PrintResult() } -func mutationJob(schema gemini.Schema, table gemini.Table, s *gemini.Session, p gemini.PartitionRange, testStatus *Status) { +func mutationJob(schema *gemini.Schema, table gemini.Table, s *gemini.Session, p gemini.PartitionRange, testStatus *Status) { mutateStmt := schema.GenMutateStmt(table, &p) mutateQuery := mutateStmt.Query mutateValues := mutateStmt.Values() @@ -176,7 +179,7 @@ func mutationJob(schema gemini.Schema, table gemini.Table, s *gemini.Session, p } } -func validationJob(schema gemini.Schema, table gemini.Table, s *gemini.Session, p gemini.PartitionRange, testStatus *Status) { +func validationJob(schema *gemini.Schema, table gemini.Table, s *gemini.Session, p gemini.PartitionRange, testStatus *Status) { checkStmt := schema.GenCheckStmt(table, &p) checkQuery := checkStmt.Query checkValues := checkStmt.Values() @@ -194,7 +197,7 @@ func validationJob(schema gemini.Schema, table gemini.Table, s *gemini.Session, } } -func Job(schema gemini.Schema, table gemini.Table, s *gemini.Session, p gemini.PartitionRange, c chan Status, mode string) { +func Job(schema *gemini.Schema, table gemini.Table, s *gemini.Session, p gemini.PartitionRange, c chan Status, mode string) { testStatus := Status{} for i := 0; i < maxTests; i++ { @@ -240,6 +243,7 @@ func init() { rootCmd.MarkFlagRequired("test-cluster") rootCmd.Flags().StringVarP(&oracleClusterHost, "oracle-cluster", "o", "", "Host name of the oracle cluster that provides correct answers") rootCmd.MarkFlagRequired("oracle-cluster") + rootCmd.Flags().StringVarP(&schemaFile, "schema", "", "", "Schema JSON config file") rootCmd.Flags().StringVarP(&mode, "mode", "m", mixedMode, "Query operation mode. Mode options: write, read, mixed (default)") rootCmd.Flags().IntVarP(&maxTests, "max-tests", "n", 100, "Maximum number of test iterations to run") rootCmd.Flags().IntVarP(&concurrency, "concurrency", "c", 10, "Number of threads per table to run concurrently") diff --git a/schema.go b/schema.go index 17319b31..a9f1fc22 100644 --- a/schema.go +++ b/schema.go @@ -26,22 +26,14 @@ type Table struct { Columns []ColumnDef `json:"columns"` } -type Schema interface { - Tables() []Table - GetDropSchema() []string - GetCreateSchema() []string - GenMutateStmt(Table, *PartitionRange) *Stmt - GenCheckStmt(Table, *PartitionRange) *Stmt -} - type Stmt struct { Query string Values func() []interface{} } -type schema struct { - keyspace Keyspace - tables []Table +type Schema struct { + Keyspace Keyspace `json:"keyspace"` + Tables []Table `json:"tables"` } type PartitionRange struct { @@ -68,14 +60,65 @@ func randDate() time.Time { return time.Unix(sec, 0) } -func (s *schema) Tables() []Table { - return s.tables +func (s *Schema) GetDropSchema() []string { + return []string{ + fmt.Sprintf("DROP KEYSPACE IF EXISTS %s", s.Keyspace.Name), + } } -func (s *schema) GetDropSchema() []string { - return []string{ - fmt.Sprintf("DROP KEYSPACE IF EXISTS %s", s.keyspace.Name), +var types = [...]string{"int", "bigint", "blob", "uuid", "text", "varchar", "timestamp", "date"} + +func genColumnName(prefix string, idx int) string { + return fmt.Sprintf("%s%d", prefix, idx) +} + +func genColumnType() string { + n := rand.Intn(len(types)) + return types[n] +} + +func genColumnDef(prefix string, idx int) ColumnDef { + return ColumnDef{ + Name: genColumnName(prefix, idx), + Type: genColumnType(), + } +} + +const ( + MaxPartitionKeys = 2 + MaxClusteringKeys = 4 + MaxColumns = 8 +) + +func GenSchema() *Schema { + builder := NewSchemaBuilder() + keyspace := Keyspace{ + Name: "ks1", + } + builder.Keyspace(keyspace) + partitionKeys := []ColumnDef{} + numPartitionKeys := rand.Intn(MaxPartitionKeys-1) + 1 + for i := 0; i < numPartitionKeys; i++ { + partitionKeys = append(partitionKeys, ColumnDef{Name: genColumnName("pk", i), Type: "int"}) + } + clusteringKeys := []ColumnDef{} + numClusteringKeys := rand.Intn(MaxClusteringKeys) + for i := 0; i < numClusteringKeys; i++ { + clusteringKeys = append(clusteringKeys, ColumnDef{Name: genColumnName("ck", i), Type: "int"}) + } + columns := []ColumnDef{} + numColumns := rand.Intn(MaxColumns) + for i := 0; i < numColumns; i++ { + columns = append(columns, ColumnDef{Name: genColumnName("col", i), Type: genColumnType()}) + } + table := Table{ + Name: "table1", + PartitionKeys: partitionKeys, + ClusteringKeys: clusteringKeys, + Columns: columns, } + builder.Table(table) + return builder.Build() } func generateValue(columnType string, p *PartitionRange, values []interface{}) []interface{} { @@ -102,12 +145,12 @@ func generateValue(columnType string, p *PartitionRange, values []interface{}) [ return values } -func (s *schema) GetCreateSchema() []string { - createKeyspace := fmt.Sprintf("CREATE KEYSPACE IF NOT EXISTS %s WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1}", s.keyspace.Name) +func (s *Schema) GetCreateSchema() []string { + createKeyspace := fmt.Sprintf("CREATE KEYSPACE IF NOT EXISTS %s WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1}", s.Keyspace.Name) stmts := []string{createKeyspace} - for _, t := range s.tables { + for _, t := range s.Tables { partitionKeys := []string{} clusteringKeys := []string{} columns := []string{} @@ -124,9 +167,9 @@ func (s *schema) GetCreateSchema() []string { } var createTable string if len(clusteringKeys) == 0 { - createTable = fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s))", s.keyspace.Name, t.Name, strings.Join(columns, ","), strings.Join(partitionKeys, ",")) + createTable = fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s))", s.Keyspace.Name, t.Name, strings.Join(columns, ","), strings.Join(partitionKeys, ",")) } else { - createTable = fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY ((%s), %s))", s.keyspace.Name, t.Name, strings.Join(columns, ","), + createTable = fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY ((%s), %s))", s.Keyspace.Name, t.Name, strings.Join(columns, ","), strings.Join(partitionKeys, ","), strings.Join(clusteringKeys, ",")) } stmts = append(stmts, createTable) @@ -134,7 +177,7 @@ func (s *schema) GetCreateSchema() []string { return stmts } -func (s *schema) GenInsertStmt(t Table, p *PartitionRange) *Stmt { +func (s *Schema) GenInsertStmt(t Table, p *PartitionRange) *Stmt { columns := []string{} placeholders := []string{} values := make([]interface{}, 0) @@ -153,7 +196,7 @@ func (s *schema) GenInsertStmt(t Table, p *PartitionRange) *Stmt { placeholders = append(placeholders, "?") values = generateValue(cdef.Type, p, values) } - query := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)", s.keyspace.Name, t.Name, strings.Join(columns, ","), strings.Join(placeholders, ",")) + query := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)", s.Keyspace.Name, t.Name, strings.Join(columns, ","), strings.Join(placeholders, ",")) return &Stmt{ Query: query, Values: func() []interface{} { @@ -162,7 +205,7 @@ func (s *schema) GenInsertStmt(t Table, p *PartitionRange) *Stmt { } } -func (s *schema) GenDeleteRows(t Table, p *PartitionRange) *Stmt { +func (s *Schema) GenDeleteRows(t Table, p *PartitionRange) *Stmt { relations := []string{} values := make([]interface{}, 0) for _, pk := range t.PartitionKeys { @@ -175,7 +218,7 @@ func (s *schema) GenDeleteRows(t Table, p *PartitionRange) *Stmt { values = generateValue(ck.Type+"_range", p, values) } } - query := fmt.Sprintf("DELETE FROM %s.%s WHERE %s", s.keyspace.Name, t.Name, strings.Join(relations, " AND ")) + query := fmt.Sprintf("DELETE FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) return &Stmt{ Query: query, Values: func() []interface{} { @@ -184,7 +227,7 @@ func (s *schema) GenDeleteRows(t Table, p *PartitionRange) *Stmt { } } -func (s *schema) GenMutateStmt(t Table, p *PartitionRange) *Stmt { +func (s *Schema) GenMutateStmt(t Table, p *PartitionRange) *Stmt { switch n := rand.Intn(1000); n { case 10, 100: return s.GenDeleteRows(t, p) @@ -194,7 +237,7 @@ func (s *schema) GenMutateStmt(t Table, p *PartitionRange) *Stmt { return nil } -func (s *schema) GenCheckStmt(t Table, p *PartitionRange) *Stmt { +func (s *Schema) GenCheckStmt(t Table, p *PartitionRange) *Stmt { switch n := rand.Intn(4); n { case 0: return s.genSinglePartitionQuery(t, p) @@ -208,14 +251,14 @@ func (s *schema) GenCheckStmt(t Table, p *PartitionRange) *Stmt { return nil } -func (s *schema) genSinglePartitionQuery(t Table, p *PartitionRange) *Stmt { +func (s *Schema) genSinglePartitionQuery(t Table, p *PartitionRange) *Stmt { relations := []string{} values := make([]interface{}, 0) for _, pk := range t.PartitionKeys { relations = append(relations, fmt.Sprintf("%s = ?", pk.Name)) values = generateValue(pk.Type, p, values) } - query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s", s.keyspace.Name, t.Name, strings.Join(relations, " AND ")) + query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) return &Stmt{ Query: query, Values: func() []interface{} { @@ -224,7 +267,7 @@ func (s *schema) genSinglePartitionQuery(t Table, p *PartitionRange) *Stmt { } } -func (s *schema) genMultiplePartitionQuery(t Table, p *PartitionRange) *Stmt { +func (s *Schema) genMultiplePartitionQuery(t Table, p *PartitionRange) *Stmt { relations := []string{} values := make([]interface{}, 0) pkNum := rand.Intn(10) @@ -236,7 +279,7 @@ func (s *schema) genMultiplePartitionQuery(t Table, p *PartitionRange) *Stmt { values = generateValue(pk.Type, p, values) } } - query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s ORDER BY %s", s.keyspace.Name, t.Name, strings.Join(relations, " AND "), strings.Join(pkNames, ",")) + query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s ORDER BY %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND "), strings.Join(pkNames, ",")) return &Stmt{ Query: query, Values: func() []interface{} { @@ -245,7 +288,7 @@ func (s *schema) genMultiplePartitionQuery(t Table, p *PartitionRange) *Stmt { } } -func (s *schema) genClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { +func (s *Schema) genClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { relations := []string{} values := make([]interface{}, 0) for _, pk := range t.PartitionKeys { @@ -256,7 +299,7 @@ func (s *schema) genClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { relations = append(relations, fmt.Sprintf("%s > ? AND %s < ?", ck.Name, ck.Name)) values = generateValue(ck.Type+"_range", p, values) } - query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s", s.keyspace.Name, t.Name, strings.Join(relations, " AND ")) + query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) return &Stmt{ Query: query, Values: func() []interface{} { @@ -265,7 +308,7 @@ func (s *schema) genClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { } } -func (s *schema) genMultiplePartitionClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { +func (s *Schema) genMultiplePartitionClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { relations := []string{} pkNum := rand.Intn(10) pkNames := []string{} @@ -281,7 +324,7 @@ func (s *schema) genMultiplePartitionClusteringRangeQuery(t Table, p *PartitionR relations = append(relations, fmt.Sprintf("%s >= ? AND %s <= ?", ck.Name, ck.Name)) values = generateValue(ck.Type+"_range", p, values) } - query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s ORDER BY %s", s.keyspace.Name, t.Name, strings.Join(relations, " AND "), strings.Join(pkNames, ",")) + query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s ORDER BY %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND "), strings.Join(pkNames, ",")) return &Stmt{ Query: query, Values: func() []interface{} { @@ -293,7 +336,7 @@ func (s *schema) genMultiplePartitionClusteringRangeQuery(t Table, p *PartitionR type SchemaBuilder interface { Keyspace(Keyspace) SchemaBuilder Table(Table) SchemaBuilder - Build() Schema + Build() *Schema } type schemaBuilder struct { @@ -311,8 +354,8 @@ func (s *schemaBuilder) Table(table Table) SchemaBuilder { return s } -func (s *schemaBuilder) Build() Schema { - return &schema{keyspace: s.keyspace, tables: s.tables} +func (s *schemaBuilder) Build() *Schema { + return &Schema{Keyspace: s.keyspace, Tables: s.tables} } func NewSchemaBuilder() SchemaBuilder { From 7586d2a6f1902b8ee313dfe91b3aba715c93dd81 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 12 Feb 2019 14:36:26 +0200 Subject: [PATCH 3/4] schema: Rename generateValue to genValue --- schema.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/schema.go b/schema.go index a9f1fc22..526d4fc9 100644 --- a/schema.go +++ b/schema.go @@ -121,7 +121,7 @@ func GenSchema() *Schema { return builder.Build() } -func generateValue(columnType string, p *PartitionRange, values []interface{}) []interface{} { +func genValue(columnType string, p *PartitionRange, values []interface{}) []interface{} { switch columnType { case "int": values = append(values, randRange(p.Min, p.Max)) @@ -184,17 +184,17 @@ func (s *Schema) GenInsertStmt(t Table, p *PartitionRange) *Stmt { for _, pk := range t.PartitionKeys { columns = append(columns, pk.Name) placeholders = append(placeholders, "?") - values = generateValue(pk.Type, p, values) + values = genValue(pk.Type, p, values) } for _, ck := range t.ClusteringKeys { columns = append(columns, ck.Name) placeholders = append(placeholders, "?") - values = generateValue(ck.Type, p, values) + values = genValue(ck.Type, p, values) } for _, cdef := range t.Columns { columns = append(columns, cdef.Name) placeholders = append(placeholders, "?") - values = generateValue(cdef.Type, p, values) + values = genValue(cdef.Type, p, values) } query := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)", s.Keyspace.Name, t.Name, strings.Join(columns, ","), strings.Join(placeholders, ",")) return &Stmt{ @@ -210,12 +210,12 @@ func (s *Schema) GenDeleteRows(t Table, p *PartitionRange) *Stmt { values := make([]interface{}, 0) for _, pk := range t.PartitionKeys { relations = append(relations, fmt.Sprintf("%s = ?", pk.Name)) - values = generateValue(pk.Type, p, values) + values = genValue(pk.Type, p, values) } if len(t.ClusteringKeys) == 1 { for _, ck := range t.ClusteringKeys { relations = append(relations, fmt.Sprintf("%s >= ? AND %s <= ?", ck.Name, ck.Name)) - values = generateValue(ck.Type+"_range", p, values) + values = genValue(ck.Type+"_range", p, values) } } query := fmt.Sprintf("DELETE FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) @@ -256,7 +256,7 @@ func (s *Schema) genSinglePartitionQuery(t Table, p *PartitionRange) *Stmt { values := make([]interface{}, 0) for _, pk := range t.PartitionKeys { relations = append(relations, fmt.Sprintf("%s = ?", pk.Name)) - values = generateValue(pk.Type, p, values) + values = genValue(pk.Type, p, values) } query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) return &Stmt{ @@ -276,7 +276,7 @@ func (s *Schema) genMultiplePartitionQuery(t Table, p *PartitionRange) *Stmt { pkNames = append(pkNames, pk.Name) relations = append(relations, fmt.Sprintf("%s IN (%s)", pk.Name, strings.TrimRight(strings.Repeat("?,", pkNum), ","))) for i := 0; i < pkNum; i++ { - values = generateValue(pk.Type, p, values) + values = genValue(pk.Type, p, values) } } query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s ORDER BY %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND "), strings.Join(pkNames, ",")) @@ -293,11 +293,11 @@ func (s *Schema) genClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { values := make([]interface{}, 0) for _, pk := range t.PartitionKeys { relations = append(relations, fmt.Sprintf("%s = ?", pk.Name)) - values = generateValue(pk.Type, p, values) + values = genValue(pk.Type, p, values) } for _, ck := range t.ClusteringKeys { relations = append(relations, fmt.Sprintf("%s > ? AND %s < ?", ck.Name, ck.Name)) - values = generateValue(ck.Type+"_range", p, values) + values = genValue(ck.Type+"_range", p, values) } query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) return &Stmt{ @@ -317,12 +317,12 @@ func (s *Schema) genMultiplePartitionClusteringRangeQuery(t Table, p *PartitionR pkNames = append(pkNames, pk.Name) relations = append(relations, fmt.Sprintf("%s IN (%s)", pk.Name, strings.TrimRight(strings.Repeat("?,", pkNum), ","))) for i := 0; i < pkNum; i++ { - values = generateValue(pk.Type, p, values) + values = genValue(pk.Type, p, values) } } for _, ck := range t.ClusteringKeys { relations = append(relations, fmt.Sprintf("%s >= ? AND %s <= ?", ck.Name, ck.Name)) - values = generateValue(ck.Type+"_range", p, values) + values = genValue(ck.Type+"_range", p, values) } query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s ORDER BY %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND "), strings.Join(pkNames, ",")) return &Stmt{ From c458b614883004ffc8bc38a74bbcb2dce589fa07 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 12 Feb 2019 14:37:33 +0200 Subject: [PATCH 4/4] schema: Separate value range generation to genValueRange --- schema.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/schema.go b/schema.go index 526d4fc9..0fa4d5ff 100644 --- a/schema.go +++ b/schema.go @@ -127,11 +127,6 @@ func genValue(columnType string, p *PartitionRange, values []interface{}) []inte values = append(values, randRange(p.Min, p.Max)) case "bigint": values = append(values, rand.Int63()) - case "int_range": - start := randRange(p.Min, p.Max) - end := start + randRange(p.Min, p.Max) - values = append(values, start) - values = append(values, end) case "blob", "uuid": r, _ := uuid.NewRandom() values = append(values, r.String()) @@ -145,6 +140,19 @@ func genValue(columnType string, p *PartitionRange, values []interface{}) []inte return values } +func genValueRange(columnType string, p *PartitionRange, values []interface{}) []interface{} { + switch columnType { + case "int": + start := randRange(p.Min, p.Max) + end := start + randRange(p.Min, p.Max) + values = append(values, start) + values = append(values, end) + default: + panic(fmt.Sprintf("generate value range: not supported type %s", columnType)) + } + return values +} + func (s *Schema) GetCreateSchema() []string { createKeyspace := fmt.Sprintf("CREATE KEYSPACE IF NOT EXISTS %s WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1}", s.Keyspace.Name) @@ -215,7 +223,7 @@ func (s *Schema) GenDeleteRows(t Table, p *PartitionRange) *Stmt { if len(t.ClusteringKeys) == 1 { for _, ck := range t.ClusteringKeys { relations = append(relations, fmt.Sprintf("%s >= ? AND %s <= ?", ck.Name, ck.Name)) - values = genValue(ck.Type+"_range", p, values) + values = genValueRange(ck.Type, p, values) } } query := fmt.Sprintf("DELETE FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) @@ -297,7 +305,7 @@ func (s *Schema) genClusteringRangeQuery(t Table, p *PartitionRange) *Stmt { } for _, ck := range t.ClusteringKeys { relations = append(relations, fmt.Sprintf("%s > ? AND %s < ?", ck.Name, ck.Name)) - values = genValue(ck.Type+"_range", p, values) + values = genValueRange(ck.Type, p, values) } query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND ")) return &Stmt{ @@ -322,7 +330,7 @@ func (s *Schema) genMultiplePartitionClusteringRangeQuery(t Table, p *PartitionR } for _, ck := range t.ClusteringKeys { relations = append(relations, fmt.Sprintf("%s >= ? AND %s <= ?", ck.Name, ck.Name)) - values = genValue(ck.Type+"_range", p, values) + values = genValueRange(ck.Type, p, values) } query := fmt.Sprintf("SELECT * FROM %s.%s WHERE %s ORDER BY %s", s.Keyspace.Name, t.Name, strings.Join(relations, " AND "), strings.Join(pkNames, ",")) return &Stmt{