Skip to content

Commit 93d0fa2

Browse files
authored
Support list columns partition and range columns partition (#105)
1 parent 871de8e commit 93d0fa2

File tree

11 files changed

+143
-32
lines changed

11 files changed

+143
-32
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,13 @@ You can change the concurrency by setting `--concurrency` flag.
4242
- [x] Non-recursive CTE with common select
4343
- [ ] Nested CTE
4444
- [ ] Recursive CTE
45+
- [ ] Partition Table
46+
- [x] one column partitions, such as `range`, `list`, `hash`, `key`, `list columns` and `range columns`
47+
- [ ] multi columns partitions
48+
- [ ] ddl operates
49+
- [ ] exchange partition
50+
- [ ] add/drop partition
51+
- [ ] truncate partition
52+
- [ ] reorg partition
4553
- [ ] Subquery
4654
- [x] Scalar Subquery

framework/run.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ func ddlIgnoreError(err error) bool {
340340
strings.Contains(errStr, "Invalid JSON text") ||
341341
strings.Contains(errStr, "since the unique index is not including all partitioning columns, and GLOBAL is not given as IndexOption") ||
342342
strings.Contains(errStr, "Defining a virtual generated column as primary key' is not supported for generated columns") ||
343-
strings.Contains(errStr, "doesn't yet support") {
343+
strings.Contains(errStr, "doesn't yet support") ||
344+
strings.Contains(errStr, "Partition column values of incorrect type") {
344345
return true
345346
}
346347
return false

reduce/rule.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func simpleExprRule(node *ast.ExprNode) bool {
4646
case *ast.BinaryOperationExpr:
4747
l := rand.Intn(2) == 0
4848
if l {
49-
exprNode := v.L.(ast.ExprNode)
49+
exprNode := v.L
5050
// Recursively apply the rule.
5151
if _, ok := exprNode.(*ast.BinaryOperationExpr); ok && rand.Intn(2) == 0 {
5252
simpleExprRule(&exprNode)
@@ -55,7 +55,7 @@ func simpleExprRule(node *ast.ExprNode) bool {
5555
node = &exprNode
5656
return true
5757
} else {
58-
exprNode := v.R.(ast.ExprNode)
58+
exprNode := v.R
5959
// Recursively apply the rule.
6060
if _, ok := exprNode.(*ast.BinaryOperationExpr); ok && rand.Intn(2) == 0 {
6161
simpleExprRule(&exprNode)
@@ -93,10 +93,7 @@ func (r *removeHintRule) apply(node *ast.StmtNode) bool {
9393
randIdx := rand.Intn(len(sel.TableHints))
9494
sel.TableHints = append(sel.TableHints[:randIdx], sel.TableHints[randIdx+1:]...)
9595

96-
if len(sel.TableHints) == 0 {
97-
return false
98-
}
99-
return true
96+
return len(sel.TableHints) != 0
10097
}
10198

10299
type removeOrderByRule struct {

reduce/rule_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package reduce
22

33
import (
4-
"github.com/stretchr/testify/require"
54
"testing"
6-
)
75

8-
type checkFunc func(sql string) bool
6+
"github.com/stretchr/testify/require"
7+
)
98

109
func TestReduceSQL(t *testing.T) {
11-
mockChcker := func(sql string) (bool, error) {
10+
mockChcker := func(sql string, isReduce bool) (bool, error) {
1211
switch sql {
1312
case "select * from t":
1413
return false, nil

sqlgenerator/db_constant.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,21 +246,40 @@ func (c ColumnType) IsTimeType() bool {
246246
return false
247247
}
248248

249-
func (c ColumnType) IsPartitionType() bool {
250-
// A partitioning key must be either an integer column or
251-
// an expression that resolves to an integer.
249+
func (c ColumnType) IsRangePartitionType() bool {
250+
return c.IsIntegerType()
251+
}
252+
253+
func (c ColumnType) IsListPartitionType() bool {
254+
return c.IsIntegerType()
255+
}
256+
257+
func (c ColumnType) IsHashPartitionType() bool {
252258
return c.IsIntegerType()
253259
}
254260

255261
func (c ColumnType) IsKeyPartitionType() bool {
256262
switch c {
257-
case ColumnTypeBlob, ColumnTypeJSON:
263+
case ColumnTypeBlob, ColumnTypeJSON, ColumnTypeText:
258264
return false
259265
default:
260266
return true
261267
}
262268
}
263269

270+
func (c ColumnType) IsColumnsPartitionType() bool {
271+
switch c {
272+
case ColumnTypeInt, ColumnTypeTinyInt, ColumnTypeSmallInt, ColumnTypeMediumInt, ColumnTypeBigInt:
273+
return true
274+
case ColumnTypeDate, ColumnTypeDatetime:
275+
return true
276+
case ColumnTypeChar, ColumnTypeVarchar, ColumnTypeBinary, ColumnTypeVarBinary:
277+
return true
278+
default:
279+
return false
280+
}
281+
}
282+
264283
func (c ColumnType) IsPointGetableType() bool {
265284
switch c {
266285
case ColumnTypeFloat, ColumnTypeDouble, ColumnTypeText, ColumnTypeBlob:

sqlgenerator/db_printer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ func PrintColumnWithFunction(col *Column) string {
180180
func PrintConstantWithFunction(tp ColumnType) string {
181181
switch tp {
182182
case ColumnTypeInt:
183-
return fmt.Sprintf("1+1")
183+
return "1+1"
184184
case ColumnTypeChar:
185-
return fmt.Sprintf("concat('a', 1)")
185+
return "concat('a', 1)"
186186
}
187187

188188
return "1"

sqlgenerator/db_type.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ func (s *State) GetCTECount() int {
201201
// QueryState represent an intermediate state during a query generation.
202202
type QueryState struct {
203203
SelectedCols map[*Table]QueryStateColumns
204+
TableIndexes map[*Table]Indexes
204205
IsWindow bool
205206
// AggCols is the aggregate columns in the select list. It's the available columns used in
206207
// select field, having clause and order by clause.

sqlgenerator/generator_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (f Fn) Eval(state *State) (res string, err error) {
9090
defer func() {
9191
r := recover()
9292
if r != nil {
93-
fmt.Println(fmt.Sprintf("Panic in NewFn: %v, info: %s", r, state.FnStack))
93+
fmt.Printf("Panic in NewFn: %v, info: %s\n", r, state.FnStack)
9494
}
9595
}()
9696
newFn := f

sqlgenerator/rule.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,14 @@ var CreateTable = NewFn(func(state *State) Fn {
103103
if err != nil {
104104
return NoneBecauseOf(err)
105105
}
106-
state.env.PartColumn = tbl.Columns.Filter(func(c *Column) bool { return c.Tp.IsPartitionType() }).Rand()
106+
state.env.PartColumn = tbl.Columns.Rand()
107107
ePartitionDef, err := PartitionDefinition.Eval(state)
108108
if err != nil {
109109
return NoneBecauseOf(err)
110110
}
111+
if len(ePartitionDef) == 0 {
112+
state.env.PartColumn = nil
113+
}
111114
eTableOption, err := TableOptions.Eval(state)
112115
if err != nil {
113116
return NoneBecauseOf(err)

sqlgenerator/rule_partition.go

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,35 @@ package sqlgenerator
33
import "math/rand"
44

55
var PartitionDefinition = NewFn(func(state *State) Fn {
6-
if state.env.PartColumn == nil {
6+
partColumn := state.env.PartColumn
7+
if partColumn == nil {
78
return Empty
89
}
9-
return Or(
10-
Empty,
11-
PartitionDefinitionHash,
12-
PartitionDefinitionRange,
13-
PartitionDefinitionList,
14-
PartitionDefinitionKey,
15-
)
10+
var supportsPartitionTypes []Fn
11+
12+
supportsPartitionTypes = append(supportsPartitionTypes, Empty)
13+
14+
if partColumn.Tp.IsKeyPartitionType() {
15+
supportsPartitionTypes = append(supportsPartitionTypes, PartitionDefinitionKey)
16+
}
17+
18+
if partColumn.Tp.IsRangePartitionType() {
19+
supportsPartitionTypes = append(supportsPartitionTypes, PartitionDefinitionRange)
20+
}
21+
22+
if partColumn.Tp.IsListPartitionType() {
23+
supportsPartitionTypes = append(supportsPartitionTypes, PartitionDefinitionList)
24+
}
25+
26+
if partColumn.Tp.IsHashPartitionType() {
27+
supportsPartitionTypes = append(supportsPartitionTypes, PartitionDefinitionHash)
28+
}
29+
30+
if partColumn.Tp.IsColumnsPartitionType() {
31+
supportsPartitionTypes = append(supportsPartitionTypes, PartitionDefinitionListColumns, PartitionDefinitionRangeColumns)
32+
}
33+
34+
return Or(supportsPartitionTypes...)
1635
})
1736

1837
var PartitionDefinitionHash = NewFn(func(state *State) Fn {
@@ -41,10 +60,9 @@ var PartitionDefinitionKey = NewFn(func(state *State) Fn {
4160

4261
var PartitionDefinitionRange = NewFn(func(state *State) Fn {
4362
partitionedCol := state.env.PartColumn
44-
partitionCount := rand.Intn(5) + 1
45-
vals := partitionedCol.RandomValuesAsc(partitionCount)
63+
vals := partitionedCol.RandomValuesAsc(rand.Intn(5) + 1)
64+
vals = uniqueOrderedStrings(vals)
4665
if rand.Intn(2) == 0 {
47-
partitionCount++
4866
vals = append(vals, "maxvalue")
4967
}
5068
return Strs(
@@ -55,9 +73,25 @@ var PartitionDefinitionRange = NewFn(func(state *State) Fn {
5573
)
5674
})
5775

76+
var PartitionDefinitionRangeColumns = NewFn(func(state *State) Fn {
77+
partitionedCol := state.env.PartColumn
78+
vals := partitionedCol.RandomValuesAsc(rand.Intn(5) + 1)
79+
vals = uniqueOrderedStrings(vals)
80+
if rand.Intn(2) == 0 {
81+
vals = append(vals, "maxvalue")
82+
}
83+
return Strs(
84+
"partition by range columns(",
85+
partitionedCol.Name, ") (",
86+
PrintRangePartitionDefs(vals),
87+
")",
88+
)
89+
})
90+
5891
var PartitionDefinitionList = NewFn(func(state *State) Fn {
5992
partitionedCol := state.env.PartColumn
6093
listVals := partitionedCol.RandomValuesAsc(20)
94+
listVals = uniqueOrderedStrings(listVals)
6195
listGroups := RandomGroups(listVals, rand.Intn(3)+1)
6296
return Strs(
6397
"partition by list (",
@@ -66,3 +100,31 @@ var PartitionDefinitionList = NewFn(func(state *State) Fn {
66100
")",
67101
)
68102
})
103+
104+
var PartitionDefinitionListColumns = NewFn(func(state *State) Fn {
105+
partitionedCol := state.env.PartColumn
106+
listVals := partitionedCol.RandomValuesAsc(20)
107+
listVals = uniqueOrderedStrings(listVals)
108+
listGroups := RandomGroups(listVals, rand.Intn(3)+1)
109+
return Strs(
110+
"partition by list columns(",
111+
partitionedCol.Name, ") (",
112+
PrintListPartitionDefs(listGroups),
113+
")",
114+
)
115+
})
116+
117+
func uniqueOrderedStrings(input []string) []string {
118+
if len(input) == 0 {
119+
return input
120+
}
121+
var result []string
122+
prev := ""
123+
for i, str := range input {
124+
if i == 0 || str != prev {
125+
result = append(result, str)
126+
prev = str
127+
}
128+
}
129+
return result
130+
}

0 commit comments

Comments
 (0)