• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codenotary / immudb / 9367064922

04 Jun 2024 12:27PM UTC coverage: 89.43% (-0.02%) from 89.451%
9367064922

push

gh-ci

ostafen
Add support for JSON type

Signed-off-by: Stefano Scafiti <stefano.scafiti96@gmail.com>

521 of 575 new or added lines in 14 files covered. (90.61%)

12 existing lines in 5 files now uncovered.

35172 of 39329 relevant lines covered (89.43%)

160547.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.25
/embedded/sql/sort_reader.go
1
/*
2
Copyright 2024 Codenotary Inc. All rights reserved.
3

4
SPDX-License-Identifier: BUSL-1.1
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    https://mariadb.com/bsl11/
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package sql
18

19
import (
20
        "context"
21
)
22

23
type sortDirection int8
24

25
const (
26
        sortDirectionDesc sortDirection = -1
27
        sortDirectionAsc  sortDirection = 1
28
)
29

30
type sortRowReader struct {
31
        rowReader          RowReader
32
        ordCols            []*OrdCol
33
        orderByDescriptors []ColDescriptor
34
        sorter             fileSorter
35

36
        resultReader resultReader
37
}
38

39
func newSortRowReader(rowReader RowReader, ordCols []*OrdCol) (*sortRowReader, error) {
45✔
40
        if rowReader == nil || len(ordCols) == 0 {
46✔
41
                return nil, ErrIllegalArguments
1✔
42
        }
1✔
43

44
        descriptors, err := rowReader.Columns(context.Background())
44✔
45
        if err != nil {
44✔
46
                return nil, err
×
47
        }
×
48

49
        colPosBySelector, err := getColPositionsBySelector(descriptors)
44✔
50
        if err != nil {
44✔
51
                return nil, err
×
52
        }
×
53

54
        colTypes, err := getColTypes(rowReader)
44✔
55
        if err != nil {
44✔
56
                return nil, err
×
57
        }
×
58

59
        orderByDescriptors, err := getOrderByDescriptors(ordCols, rowReader)
44✔
60
        if err != nil {
45✔
61
                return nil, err
1✔
62
        }
1✔
63

64
        tx := rowReader.Tx()
43✔
65
        sr := &sortRowReader{
43✔
66
                rowReader:          rowReader,
43✔
67
                ordCols:            ordCols,
43✔
68
                orderByDescriptors: orderByDescriptors,
43✔
69
                sorter: fileSorter{
43✔
70
                        colPosBySelector: colPosBySelector,
43✔
71
                        colTypes:         colTypes,
43✔
72
                        tx:               tx,
43✔
73
                        sortBufSize:      tx.engine.sortBufferSize,
43✔
74
                        sortBuf:          make([]*Row, tx.engine.sortBufferSize),
43✔
75
                },
43✔
76
        }
43✔
77

43✔
78
        directions := make([]sortDirection, len(ordCols))
43✔
79
        for i, col := range ordCols {
110✔
80
                directions[i] = sortDirectionAsc
67✔
81
                if col.descOrder {
93✔
82
                        directions[i] = sortDirectionDesc
26✔
83
                }
26✔
84
        }
85

86
        t1 := make(Tuple, len(ordCols))
43✔
87
        t2 := make(Tuple, len(ordCols))
43✔
88

43✔
89
        sr.sorter.cmp = func(r1, r2 *Row) (int, error) {
73,771✔
90
                if err := sr.evalSortSelectors(r1, t1); err != nil {
73,728✔
NEW
91
                        return 0, err
×
NEW
92
                }
×
93

94
                if err := sr.evalSortSelectors(r2, t2); err != nil {
73,728✔
NEW
95
                        return 0, err
×
NEW
96
                }
×
97

98
                res, idx, err := t1.Compare(t2)
73,728✔
99
                if err != nil {
73,933✔
100
                        return 0, err
205✔
101
                }
205✔
102

103
                if idx >= 0 {
142,894✔
104
                        return res * int(directions[idx]), nil
69,371✔
105
                }
69,371✔
106
                return res, nil
4,152✔
107
        }
108
        return sr, nil
43✔
109
}
110

111
func (s *sortRowReader) evalSortSelectors(inRow *Row, out Tuple) error {
147,456✔
112
        for i, col := range s.ordCols {
400,388✔
113
                val, err := col.sel.reduce(s.Tx(), inRow, s.TableAlias())
252,932✔
114
                if err != nil {
252,932✔
NEW
115
                        return err
×
NEW
116
                }
×
117
                out[i] = val
252,932✔
118
        }
119
        return nil
147,456✔
120
}
121

122
func getOrderByDescriptors(ordCols []*OrdCol, rowReader RowReader) ([]ColDescriptor, error) {
44✔
123
        colsBySel, err := rowReader.colsBySelector(context.Background())
44✔
124
        if err != nil {
44✔
NEW
125
                return nil, err
×
NEW
126
        }
×
127

128
        params := make(map[string]string)
44✔
129
        orderByDescriptors := make([]ColDescriptor, len(ordCols))
44✔
130
        for i, col := range ordCols {
112✔
131
                sqlType, err := col.sel.inferType(colsBySel, params, rowReader.TableAlias())
68✔
132
                if err != nil {
69✔
133
                        return nil, err
1✔
134
                }
1✔
135

136
                aggFn, table, col := col.sel.resolve(rowReader.TableAlias())
67✔
137
                orderByDescriptors[i] = ColDescriptor{
67✔
138
                        AggFn:  aggFn,
67✔
139
                        Table:  table,
67✔
140
                        Column: col,
67✔
141
                        Type:   sqlType,
67✔
142
                }
67✔
143
        }
144
        return orderByDescriptors, nil
43✔
145
}
146

147
func getColTypes(r RowReader) ([]string, error) {
44✔
148
        descriptors, err := r.Columns(context.Background())
44✔
149
        if err != nil {
44✔
150
                return nil, err
×
151
        }
×
152

153
        cols := make([]string, len(descriptors))
44✔
154
        for i, desc := range descriptors {
234✔
155
                cols[i] = desc.Type
190✔
156
        }
190✔
157
        return cols, err
44✔
158
}
159

160
func getColPositionsBySelector(desc []ColDescriptor) (map[string]int, error) {
44✔
161
        colPositionsBySelector := make(map[string]int)
44✔
162
        for i, desc := range desc {
234✔
163
                colPositionsBySelector[desc.Selector()] = i
190✔
164
        }
190✔
165
        return colPositionsBySelector, nil
44✔
166
}
167

168
func (sr *sortRowReader) onClose(callback func()) {
41✔
169
        sr.rowReader.onClose(callback)
41✔
170
}
41✔
171

172
func (sr *sortRowReader) Tx() *SQLTx {
294,025✔
173
        return sr.rowReader.Tx()
294,025✔
174
}
294,025✔
175

176
func (sr *sortRowReader) TableAlias() string {
334,273✔
177
        return sr.rowReader.TableAlias()
334,273✔
178
}
334,273✔
179

180
func (sr *sortRowReader) Parameters() map[string]interface{} {
1✔
181
        return sr.rowReader.Parameters()
1✔
182
}
1✔
183

184
func (sr *sortRowReader) OrderBy() []ColDescriptor {
5✔
185
        return sr.orderByDescriptors
5✔
186
}
5✔
187

188
func (sr *sortRowReader) ScanSpecs() *ScanSpecs {
31✔
189
        return sr.rowReader.ScanSpecs()
31✔
190
}
31✔
191

192
func (sr *sortRowReader) Columns(ctx context.Context) ([]ColDescriptor, error) {
16✔
193
        return sr.rowReader.Columns(ctx)
16✔
194
}
16✔
195

196
func (sr *sortRowReader) colsBySelector(ctx context.Context) (map[string]ColDescriptor, error) {
18✔
197
        return sr.rowReader.colsBySelector(ctx)
18✔
198
}
18✔
199

200
func (sr *sortRowReader) InferParameters(ctx context.Context, params map[string]SQLValueType) error {
1✔
201
        return sr.rowReader.InferParameters(ctx, params)
1✔
202
}
1✔
203

204
func (sr *sortRowReader) Read(ctx context.Context) (*Row, error) {
8,811✔
205
        if sr.resultReader == nil {
8,840✔
206
                reader, err := sr.readAndSort(ctx)
29✔
207
                if err != nil {
30✔
208
                        return nil, err
1✔
209
                }
1✔
210
                sr.resultReader = reader
28✔
211
        }
212
        return sr.resultReader.Read()
8,810✔
213
}
214

215
func (sr *sortRowReader) readAndSort(ctx context.Context) (resultReader, error) {
29✔
216
        err := sr.readAll(ctx)
29✔
217
        if err != nil {
29✔
218
                return nil, err
×
219
        }
×
220
        return sr.sorter.finalize()
29✔
221
}
222

223
func (sr *sortRowReader) readAll(ctx context.Context) error {
29✔
224
        for {
8,935✔
225
                row, err := sr.rowReader.Read(ctx)
8,906✔
226
                if err == ErrNoMoreRows {
8,935✔
227
                        return nil
29✔
228
                }
29✔
229

230
                if err != nil {
8,877✔
231
                        return err
×
232
                }
×
233

234
                err = sr.sorter.update(row)
8,877✔
235
                if err != nil {
8,877✔
236
                        return err
×
237
                }
×
238
        }
239
}
240

241
func (sr *sortRowReader) Close() error {
42✔
242
        return sr.rowReader.Close()
42✔
243
}
42✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc