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

codenotary / immudb / 12046815258

27 Nov 2024 08:52AM UTC coverage: 89.303% (-0.004%) from 89.307%
12046815258

push

gh-ci

ostafen
chore(embedded/sql): Implement CASE statement

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

170 of 198 new or added lines in 3 files covered. (85.86%)

2 existing lines in 1 file now uncovered.

37441 of 41926 relevant lines covered (89.3%)

150675.25 hits per line

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

93.59
/embedded/sql/proj_row_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
        "fmt"
22
)
23

24
type projectedRowReader struct {
25
        rowReader  RowReader
26
        tableAlias string
27

28
        targets []TargetEntry
29
}
30

31
func newProjectedRowReader(ctx context.Context, rowReader RowReader, tableAlias string, targets []TargetEntry) (*projectedRowReader, error) {
890✔
32
        // case: SELECT *
890✔
33
        if len(targets) == 0 {
1,331✔
34
                cols, err := rowReader.Columns(ctx)
441✔
35
                if err != nil {
442✔
36
                        return nil, err
1✔
37
                }
1✔
38

39
                for _, col := range cols {
1,970✔
40
                        targets = append(targets, TargetEntry{
1,530✔
41
                                Exp: &ColSelector{
1,530✔
42
                                        table: col.Table,
1,530✔
43
                                        col:   col.Column,
1,530✔
44
                                },
1,530✔
45
                        })
1,530✔
46
                }
1,530✔
47
        }
48

49
        return &projectedRowReader{
889✔
50
                rowReader:  rowReader,
889✔
51
                tableAlias: tableAlias,
889✔
52
                targets:    targets,
889✔
53
        }, nil
889✔
54
}
55

56
func (pr *projectedRowReader) onClose(callback func()) {
384✔
57
        pr.rowReader.onClose(callback)
384✔
58
}
384✔
59

60
func (pr *projectedRowReader) Tx() *SQLTx {
80,252✔
61
        return pr.rowReader.Tx()
80,252✔
62
}
80,252✔
63

64
func (pr *projectedRowReader) TableAlias() string {
15,723✔
65
        if pr.tableAlias == "" {
31,346✔
66
                return pr.rowReader.TableAlias()
15,623✔
67
        }
15,623✔
68

69
        return pr.tableAlias
100✔
70
}
71

72
func (pr *projectedRowReader) OrderBy() []ColDescriptor {
24✔
73
        return pr.rowReader.OrderBy()
24✔
74
}
24✔
75

76
func (pr *projectedRowReader) ScanSpecs() *ScanSpecs {
95✔
77
        return pr.rowReader.ScanSpecs()
95✔
78
}
95✔
79

80
func (pr *projectedRowReader) Columns(ctx context.Context) ([]ColDescriptor, error) {
125✔
81
        colsBySel, err := pr.colsBySelector(ctx)
125✔
82
        if err != nil {
126✔
83
                return nil, err
1✔
84
        }
1✔
85

86
        colsByPos := make([]ColDescriptor, len(pr.targets))
124✔
87

124✔
88
        for i, t := range pr.targets {
422✔
89
                var aggFn, table, col string = "", pr.rowReader.TableAlias(), ""
298✔
90
                if s, ok := t.Exp.(Selector); ok {
593✔
91
                        aggFn, table, col = s.resolve(pr.rowReader.TableAlias())
295✔
92
                }
295✔
93

94
                if pr.tableAlias != "" {
298✔
95
                        table = pr.tableAlias
×
96
                }
×
97

98
                if t.As != "" {
315✔
99
                        col = t.As
17✔
100
                } else if aggFn != "" || col == "" {
313✔
101
                        col = fmt.Sprintf("col%d", i)
15✔
102
                }
15✔
103
                aggFn = ""
298✔
104

298✔
105
                colsByPos[i] = ColDescriptor{
298✔
106
                        AggFn:  aggFn,
298✔
107
                        Table:  table,
298✔
108
                        Column: col,
298✔
109
                }
298✔
110
                encSel := colsByPos[i].Selector()
298✔
111
                colsByPos[i].Type = colsBySel[encSel].Type
298✔
112
        }
113
        return colsByPos, nil
124✔
114
}
115

116
func (pr *projectedRowReader) colsBySelector(ctx context.Context) (map[string]ColDescriptor, error) {
170✔
117
        dsColDescriptors, err := pr.rowReader.colsBySelector(ctx)
170✔
118
        if err != nil {
171✔
119
                return nil, err
1✔
120
        }
1✔
121

122
        colDescriptors := make(map[string]ColDescriptor, len(pr.targets))
169✔
123
        emptyParams := make(map[string]string)
169✔
124

169✔
125
        for i, t := range pr.targets {
582✔
126
                var aggFn, table, col string = "", pr.rowReader.TableAlias(), ""
413✔
127
                if s, ok := t.Exp.(Selector); ok {
823✔
128
                        aggFn, table, col = s.resolve(pr.rowReader.TableAlias())
410✔
129
                }
410✔
130

131
                sqlType, err := t.Exp.inferType(dsColDescriptors, emptyParams, pr.rowReader.TableAlias())
413✔
132
                if err != nil {
413✔
133
                        return nil, err
×
134
                }
×
135

136
                if pr.tableAlias != "" {
418✔
137
                        table = pr.tableAlias
5✔
138
                }
5✔
139

140
                if t.As != "" {
431✔
141
                        col = t.As
18✔
142
                } else if aggFn != "" || col == "" {
428✔
143
                        col = fmt.Sprintf("col%d", i)
15✔
144
                }
15✔
145
                aggFn = ""
413✔
146

413✔
147
                des := ColDescriptor{
413✔
148
                        AggFn:  aggFn,
413✔
149
                        Table:  table,
413✔
150
                        Column: col,
413✔
151
                        Type:   sqlType,
413✔
152
                }
413✔
153
                colDescriptors[des.Selector()] = des
413✔
154
        }
155
        return colDescriptors, nil
169✔
156
}
157

158
func (pr *projectedRowReader) InferParameters(ctx context.Context, params map[string]SQLValueType) error {
52✔
159
        if err := pr.rowReader.InferParameters(ctx, params); err != nil {
61✔
160
                return err
9✔
161
        }
9✔
162

163
        cols, err := pr.rowReader.colsBySelector(ctx)
43✔
164
        if err != nil {
43✔
165
                return err
×
166
        }
×
167

168
        for _, ex := range pr.targets {
172✔
169
                _, err = ex.Exp.inferType(cols, params, pr.TableAlias())
129✔
170
                if err != nil {
129✔
171
                        return err
×
172
                }
×
173
        }
174
        return nil
43✔
175
}
176

177
func (pr *projectedRowReader) Parameters() map[string]interface{} {
67,152✔
178
        return pr.rowReader.Parameters()
67,152✔
179
}
67,152✔
180

181
func (pr *projectedRowReader) Read(ctx context.Context) (*Row, error) {
16,133✔
182
        row, err := pr.rowReader.Read(ctx)
16,133✔
183
        if err != nil {
16,729✔
184
                return nil, err
596✔
185
        }
596✔
186

187
        prow := &Row{
15,537✔
188
                ValuesByPosition: make([]TypedValue, len(pr.targets)),
15,537✔
189
                ValuesBySelector: make(map[string]TypedValue, len(pr.targets)),
15,537✔
190
        }
15,537✔
191

15,537✔
192
        for i, t := range pr.targets {
81,865✔
193
                e, err := t.Exp.substitute(pr.Parameters())
66,328✔
194
                if err != nil {
66,328✔
NEW
195
                        return nil, fmt.Errorf("%w: when evaluating WHERE clause", err)
×
NEW
196
                }
×
197

198
                v, err := e.reduce(pr.Tx(), row, pr.rowReader.TableAlias())
66,328✔
199
                if err != nil {
66,348✔
200
                        return nil, err
20✔
201
                }
20✔
202

203
                var aggFn, table, col string = "", pr.rowReader.TableAlias(), ""
66,308✔
204
                if s, ok := t.Exp.(Selector); ok {
131,867✔
205
                        aggFn, table, col = s.resolve(pr.rowReader.TableAlias())
65,559✔
206
                }
65,559✔
207

208
                if pr.tableAlias != "" {
66,339✔
209
                        table = pr.tableAlias
31✔
210
                }
31✔
211

212
                if t.As != "" {
66,859✔
213
                        col = t.As
551✔
214
                } else if aggFn != "" || col == "" {
67,228✔
215
                        col = fmt.Sprintf("col%d", i)
920✔
216
                }
920✔
217

218
                prow.ValuesByPosition[i] = v
66,308✔
219
                prow.ValuesBySelector[EncodeSelector("", table, col)] = v
66,308✔
220
        }
221
        return prow, nil
15,517✔
222
}
223

224
func (pr *projectedRowReader) Close() error {
900✔
225
        return pr.rowReader.Close()
900✔
226
}
900✔
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