Skip to content

Commit d7954c4

Browse files
分库分表: 排序merger的nullable数据的支持 (#195)
排序merger中对nullable类型的列的支持
1 parent 400c80e commit d7954c4

File tree

8 files changed

+955
-21
lines changed

8 files changed

+955
-21
lines changed

.CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- [eorm: 修复单条查询时连接泄露问题](https://github.com/ecodeclub/eorm/pull/188)
2626
- [eorm: 分库分表: 结果集处理--聚合函数(含GroupBy子句)](https://github.com/ecodeclub/eorm/pull/193)
2727
- [eorm: 分库分表: NOT 支持](https://github.com/ecodeclub/eorm/pull/191)
28+
- [eorm: 分库分表: Merger NullAble类型数据的支持(sortMerger)](https://github.com/ecodeclub/eorm/pull/195)
2829

2930
## v0.0.1:
3031
- [Init Project](https://github.com/ecodeclub/eorm/pull/1)

internal/merger/internal/errs/error.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var (
3030
ErrMergerAggregateHasEmptyRows = errors.New("merger: 聚合函数计算时rowsList有一个或多个为空")
3131
ErrMergerInvalidAggregateColumnIndex = errors.New("merger: ColumnInfo的index不合法")
3232
ErrMergerAggregateFuncNotFound = errors.New("merger: 聚合函数方法未找到")
33+
ErrMergerNullable = errors.New("merger: 接收数据的类型需要为sql.Nullable")
3334
)
3435

3536
func NewRepeatSortColumn(column string) error {

internal/merger/sortmerger/heap.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414

1515
package sortmerger
1616

17-
import "reflect"
17+
import (
18+
"database/sql/driver"
19+
"reflect"
20+
"time"
21+
)
1822

1923
var compareFuncMapping = map[reflect.Kind]func(any, any, Order) int{
2024
reflect.Int: compare[int],
@@ -45,8 +49,14 @@ func (h *Heap) Less(i, j int) bool {
4549
for k := 0; k < h.sortColumns.Len(); k++ {
4650
valueI := h.h[i].sortCols[k]
4751
valueJ := h.h[j].sortCols[k]
48-
kind := reflect.TypeOf(valueI).Kind()
49-
cp := compareFuncMapping[kind]
52+
_, ok := valueJ.(driver.Valuer)
53+
var cp func(any, any, Order) int
54+
if ok {
55+
cp = compareNullable
56+
} else {
57+
kind := reflect.TypeOf(valueI).Kind()
58+
cp = compareFuncMapping[kind]
59+
}
5060
res := cp(valueI, valueJ, h.sortColumns.Get(k).order)
5161
if res == 0 {
5262
continue
@@ -84,11 +94,35 @@ type node struct {
8494

8595
func compare[T Ordered](ii any, jj any, order Order) int {
8696
i, j := ii.(T), jj.(T)
87-
if i < j && order || i > j && !order {
97+
if i < j && order == ASC || i > j && order == DESC {
8898
return -1
89-
} else if i > j && order || i < j && !order {
99+
} else if i > j && order == ASC || i < j && order == DESC {
90100
return 1
91101
} else {
92102
return 0
93103
}
94104
}
105+
106+
func compareNullable(ii, jj any, order Order) int {
107+
i := ii.(driver.Valuer)
108+
j := jj.(driver.Valuer)
109+
iVal, _ := i.Value()
110+
jVal, _ := j.Value()
111+
// 如果i,j都为空返回0
112+
// 如果val返回为空永远是最小值
113+
if iVal == nil && jVal == nil {
114+
return 0
115+
} else if iVal == nil && order == ASC || jVal == nil && order == DESC {
116+
return -1
117+
} else if iVal == nil && order == DESC || jVal == nil && order == ASC {
118+
return 1
119+
}
120+
121+
vali, ok := iVal.(time.Time)
122+
if ok {
123+
valj := jVal.(time.Time)
124+
return compare[int64](vali.UnixMilli(), valj.UnixMilli(), order)
125+
}
126+
kind := reflect.TypeOf(iVal).Kind()
127+
return compareFuncMapping[kind](iVal, jVal, order)
128+
}

0 commit comments

Comments
 (0)